Rules
After the file layout and declarative model from 0.3.1 Anatomy of a BUILD File, the next question is what those top-level calls actually are. java_library, cc_binary, and sh_test are rules: schemas for a kind of target. Calling one in a BUILD file instantiates a rule target with a label, attributes, and hidden implementation logic that Bazel later uses to produce artifacts and dependency information.1,2,3
Rule Is A Type, Target Is An Instance
A real example appears in app/BUILD.bazel:
java_binary(
name = "server",
srcs = ["Main.java"],
deps = [":lib"],
)
In that snippet, java_binary is the rule. server is the target name. Together with the package path //app, that declaration becomes the label //app:server.1,2,4 Bazel's glossary is explicit that a rule is not the same thing as a rule target, even though people sometimes use the words loosely.4
That distinction matters because labels from 0.2.1 Label Anatomy point at targets, not at rule types. A BUILD file is therefore mostly a list of instantiated rule types: each call creates one target that other targets can depend on later.2,4
What A Rule Contributes
A rule does two jobs. First, it defines the attribute schema available in the call: which fields exist, and what kind of information they accept. Second, it hides the build logic that turns those attribute values into outputs and metadata for downstream targets.1,3,4
For a BUILD-file author, that means you do not spell out compiler invocations or file-copy steps in the BUILD file. You fill in facts such as name, source files, and dependencies, and the rule implementation handles the mechanics.1,4 That is also why 0.3.3 Attributes & Semantic Roles deserves its own article: the meaning of srcs, deps, data, or rule-specific fields comes from the rule kind you are calling.
Rule Families Help You Read Intent
Most rules come in recognizable families. The official BUILD-file docs call out the common pattern *_library, *_binary, and *_test: libraries are separately compiled modules, binaries are executable programs, and tests are specialized executables for automated verification.2 When you see those names in a BUILD file, you can already make a good first guess about how the target is meant to be used.
That naming pattern also explains why a java_binary is something you may later run with 1.1.2 bazel run & Runfiles, while a java_library is usually something other targets depend on. The prefix often signals the language or ruleset: cc_* for C++, java_* for Java, and many others supplied by external rulesets rather than Bazel core itself.1,2,4 The bigger split between the generic engine and language plugins is the theme of P.2.3 Core vs Rulesets, while the mechanics of importing rule symbols belong to 0.3.5 Load Statements.
Where The Rule Name Comes From
Some rule names are built into Bazel, but many enter the file through load() statements from .bzl files.2,4 For Level 0, the important point is just that the symbol you call in the BUILD file is the interface of a rule. The details of how that symbol got into scope, or how to author your own rule type, can wait until 0.3.5 Load Statements and later 4.3 Custom Rules, Providers & Actions.
Not Every Target Is A Rule Target
Not every label in Bazel names a rule target. The official terminology separates rule targets from file targets, and also treats package_group as its own target kind used mainly for visibility control.3,4 //app:server is a rule target, //app:Main.java is a file target, and a package_group target exists to be referenced from visibility settings rather than to compile code.3
This is useful when reading BUILD files because it prevents a common beginner mistake: assuming that every target is "some rule invocation." Rules are the most important target kind in everyday BUILD-file reading, but they are still just one category inside the broader target model.3,4
A rule is the type; a rule target is the instance created by calling that type in a BUILD file. When you open an unfamiliar package, first identify the rule families in use, then read each call as "one target of this kind with these attributes." The next step is 0.3.3 Attributes & Semantic Roles, where those fields get their semantic roles; defining brand-new rule types waits until 4.3 Custom Rules, Providers & Actions.
1.What is the relationship between a rule and a target?
2.What two jobs does a rule perform?
3.What do the naming families *_library, *_binary, and *_test tell you?
Footnotes
-
Bazel Training 101 (Part 9): Packages, Rules, Targets, and Labels — rule as schema and black box, constructor-like rule calls, naming families, and common BUILD-file attributes ↩1 ↩2 ↩3 ↩4 ↩5
-
BUILD files — rule calls creating targets, common
*_library/*_binary/*_testfamilies, and BUILD-file rule semantics ↩1 ↩2 ↩3 ↩4 ↩5 ↩6 -
Repositories, workspaces, packages, and targets — rule instances as input/output relationships, and the distinction between rule, file, and package-group targets ↩1 ↩2 ↩3 ↩4 ↩5
-
Bazel Glossary — precise terminology for rule vs rule target, target kinds, native rules, and attribute schema ↩1 ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8 ↩9