Functions
Contents
package
package(default_deprecation, default_testonly, default_visibility, features)
This function declares metadata that applies to every subsequent rule in the package. It is used at most once within a package (BUILD file).
The package() function should be called right after all the load() statements at the top of the file, before any rule.
Arguments
Attribute | Description |
---|---|
default_visibility |
The default visibility of the rules in this package. Every rule in this package has the visibility specified in this
attribute, unless otherwise specified in the |
default_deprecation |
Sets the default
|
default_testonly |
Sets the default
In packages under |
features |
Sets various flags that affect the semantics of this BUILD file. This feature is mainly used by the people working on the build system to tag packages that need some kind of special handling. Do not use this unless explicitly requested by someone working on the build system. |
Examples
The declaration below declares that the rules in this package are visible only to members of package group//foo:target
. Individual visibility declarations
on a rule, if present, override this specification.
package(default_visibility = ["//foo:target"])
package_group
package_group(name, packages, includes)
This function defines a set of packages and assigns a label to the
group. The label can be referenced in visibility
attributes.
Package groups are used for visibility control. You can grant access to a rule to one or more package groups, every rule in the entire source tree, or only to rules declared in the same package. For more detailed description of the visibility system, see the visibility attribute.
Arguments
Attribute | Description |
---|---|
name |
A unique name for this target. |
packages |
A complete enumeration of packages in this group. Packages should be referred to using their full names,
starting with a double slash. For
example, You can also specify wildcards: the specification
Package specifications can be prefixed with If this attribute is missing, the package group itself will contain no packages (but it can still include other package groups). |
includes |
Other package groups that are included in this one. The labels in this attribute must refer to other package
groups. Packages in referenced package groups are taken to be part
of this package group. This is transitive, that is, if package
group |
Examples
The following package_group
declaration specifies a
package group called "tropical" that contains tropical fruits.
package_group( name = "tropical", packages = [ "//fruits/mango", "//fruits/orange", "//fruits/papaya/...", ], )
The following declarations specify the package groups of a fictional application:
package_group( name = "fooapp", includes = [ ":controller", ":model", ":view", ], ) package_group( name = "model", packages = ["//fooapp/database"], ) package_group( name = "view", packages = [ "//fooapp/swingui", "//fooapp/webui", ], ) package_group( name = "controller", packages = ["//fooapp/algorithm"], )
exports_files
exports_files([label, ...], visibility, licenses)
exports_files()
specifies a list of files belonging to
this package that are exported to other packages but not otherwise
mentioned in the BUILD file.
The BUILD file for a package may only refer to files belonging to another
package if they are mentioned somewhere in the other packages's BUILD file,
whether as an input to a rule or an explicit or implicit output from a rule.
The remaining files are not associated with a specific rule but are just "data",
and for these, exports_files
ensures that they may be referenced by
other packages. (One kind of data for which this is particularly useful are
shell scripts.)
Arguments
The argument is a list of names of files within the current package. A
visibility declaration can also be specified; in this case, the files will be
visible to the targets specified. If no visibility is specified, the files
will be visible to every package, even if a package default visibility was
specified in the package
function. The licenses
can also be specified.
Example
The following example exports golden.txt
, a
text file from the test_data
package, so that other
packages may use it, for example, in the data
attribute
of tests.
# from //test_data/BUILD exports_files(["golden.txt"])
glob
glob(include, exclude=[], exclude_directories=1)
Glob is a helper function that can be used anywhere a list of filenames
is expected. It takes one or two lists of filename patterns containing
the *
wildcard: as per the Unix shell, this wildcard
matches any string excluding the directory separator /
.
In addition filename patterns can contain the recursive **
wildcard. This wildcard will match zero or more complete
path segments separated by the directory separator /
.
This wildcard can only be used as a complete path segment. For example,
"x/**/*.java"
is valid, but "test**/testdata.xml"
and "**.java"
are both invalid. No other wildcards are supported.
Glob returns a sorted list of every file in the current package that:
- Matches at least one pattern in
include
. - Does not match any of the patterns in
exclude
(default []).
If the exclude_directories
argument is enabled (set to 1), files of
type directory will be omitted from the results (default 1).
There are several important limitations and caveats:
-
Since
glob()
runs during BUILD file evaluation,glob()
matches files only in your source tree, never generated files. If you are building a target that requires both source and generated files, create a list of generated files. This list can be specified by using the labels for the generated files or using the label for the target that produces the generated files. Use+
to add the list of generated files to the result of theglob()
call as shown in the example below with the target:gen_java_srcs
. - Globs may match files in subdirectories. And subdirectory names may be wildcarded. However...
-
Labels are not allowed to cross the package boundary and glob does
not match files in subpackages.
For example, the glob expression
**/*.cc
in packagex
does not includex/y/z.cc
ifx/y
exists as a package (either asx/y/BUILD
, or somewhere else on the package-path). This means that the result of the glob expression actually depends on the existence of BUILD files — that is, the same glob expression would includex/y/z.cc
if there was no package calledx/y
or it was marked as deleted using the --deleted_packages flag. - The restriction above applies to all glob expressions, no matter which wildcards they use.
-
A hidden file with filename starting with
.
is matched by both the**
and the*
wildcards. - If a rule and a source file with the same name both exist in the package, the glob will return the outputs of the rule instead of the source file.
-
The "**" wildcard has one corner case: the pattern
"**"
doesn't match the package's directory path. That is to say,glob(["**"], exclude_directories = 0)
matches all files and directories transitively strictly under the current package's directory (but of course not going into directories of subpackages - see the previous note about that).
In general, you should try to provide an appropriate extension (e.g. *.html) instead of using a bare '*' for a glob pattern. The more explicit name is both self documenting and ensures that you don't accidentally match backup files, or emacs/vi/... auto-save files.
When writing build rules you can enumerate the elements of the glob. This enables generating individual rules for every input, for example. See the expanded glob example section below.
Glob Examples
Create a Java library built from all java files in this directory,
and all files generated by the :gen_java_srcs
rule.
java_library( name = "mylib", srcs = glob(["*.java"]) + [":gen_java_srcs"], deps = "...", ) genrule( name = "gen_java_srcs", outs = [ "Foo.java", "Bar.java", ], ... )
Include all txt files in directory testdata except experimental.txt. Note that files in subdirectories of testdata will not be included. If you want those files to be included, use a recursive glob (**).
sh_test( name = "mytest", srcs = ["mytest.sh"], data = glob( ["testdata/*.txt"], exclude = ["testdata/experimental.txt"], ), )
Recursive Glob Examples
Make the test depend on all txt files in the testdata directory and any of its subdirectories (and their subdirectories, and so on). Subdirectories containing a BUILD file are ignored. (See limitations and caveats above.)
sh_test( name = "mytest", srcs = ["mytest.sh"], data = glob(["testdata/**/*.txt"]), )
Create a library built from all java files in this directory and all subdirectories except those whose path includes a directory named testing. This pattern should be avoided if possible, as it can reduce build incrementality and therefore increase build times.
java_library( name = "mylib", srcs = glob( ["**/*.java"], exclude = ["**/testing/**"], ), )
Expanded Glob Examples
Create an individual genrule for *_test.cc in the current directory that counts the number of lines in the file.
# Conveniently, the build language supports list comprehensions. [genrule( name = "count_lines_" + f[:-3], # strip ".cc" srcs = [f], outs = ["%s-linecount.txt" % f[:-3]], cmd = "wc -l $< >$@", ) for f in glob(["*_test.cc"])]
If the BUILD file above is in package //foo and the package contains three
matching files, a_test.cc, b_test.cc and c_test.cc then running
bazel query '//foo:all'
will list all rules that were generated:
$ bazel query '//foo:all' | sort //foo:count_lines_a_test //foo:count_lines_b_test //foo:count_lines_c_test
select
select( {conditionA: valuesA, conditionB: valuesB, ...}, no_match_error = "custom message" )
select()
is the helper function that makes a rule attribute
configurable.
It can replace the right-hand side of
almost
any attribute assignment so its value depends on command-line Bazel flags.
This can be used, for example, to define platform-specific dependencies or to
embed different resources depending on whether a rule is built in "developer"
vs. "release" mode.
Basic usage is as follows:
sh_binary( name = "myrule", srcs = select({ ":conditionA": ["myrule_a.sh"], ":conditionB": ["myrule_b.sh"], "//conditions:default": ["myrule_default.sh"] }) )
This makes the srcs
attribute of
a sh_binary
configurable by replacing its normal label
list assignment with a select
call that maps
configuration conditions to matching values. Each condition is a label
reference to
a config_setting
instance,
which "matches" if the rule's configuration matches an expected set of
values. The value of myrule#srcs
then becomes whichever
label list matches the current invocation.
Further notes:
- Exactly one condition is selected on any invocation.
- If multiple conditions match and one is a specialization of the others, the specialization takes precedence. Condition B is considered a specialization of condition A if B has all the same flags as A plus some additional flags. However, the number of constraint values that A and B have are not considered in this comparison -- one condition cannot match a platform more than another condition does.
- If multiple conditions match and one is not a specialization of all the others, Bazel fails with an error.
- The special pseudo-label
//conditions:default
is considered to match if no other condition matches. If this condition is left out, some other rule must match to avoid an error. select
can be embedded inside a larger attribute assignment. Sosrcs = ["common.sh"] + select({ ":conditionA": ["myrule_a.sh"], ...})
andsrcs = select({ ":conditionA": ["a.sh"]}) + select({ ":conditionB": ["b.sh"]})
are valid expressions.select
works with most, but not all, attributes. Incompatible attributes are markednonconfigurable
in their documentation.
Configurable attribute "foo" doesn't match this configuration (would a default condition help?). Conditions checked: //pkg:conditionA. //pkg:conditionB.
no_match_error
can be used to signal more precise errors.
Examples
config_setting( name = "windows", values = { "crosstool_top": "//crosstools/windows", }, ) cc_binary( name = "multiplatform_app", ... linkopts = select({ ":windows": [ "-Wl,windows_support1.lib", "-Wl,windows_support2.lib", ], "//conditions:default": [], ... )
In the above example, multiplatform_app
links with additional
options when invoked with bazel build //pkg:multiplatform_app
--crosstool_top=//crosstools/windows
.
workspace
workspace(name = "com_example_project")
This can only be used in a WORKSPACE file.
Each repository's WORKSPACE file should have a workspace(name = "...") line, which sets a global name for the repository.
This name is used for the directory that the repository's runfiles are stored
in. For example, if there is a runfile foo/bar
in the local
repository and the WORKSPACE file contains
workspace(name = "baz")
, then the runfile will be available under
mytarget.runfiles/baz/foo/bar
. If no workspace name is
specified, then the runfile will be symlinked to
bar.runfiles/foo/bar
.
A workspace name must start with a letter and can contain letters, numbers, and underscores (this is to maximize the number of languages for which this string can be a valid package/module name). It should describe the project in reverse-DNS form, with elements separated by underscores. For example, if a project is hosted at example.com/some-project, you might use com_example_some_project as the workspace name.
Remote repository rule names must be
valid workspace names. For example, you could have
maven_jar(name = "foo")
, but not
maven_jar(name = "foo.bar")
, as Bazel would attempt to write a
WORKSPACE file for the maven_jar
containing
workspace(name = "foo.bar")
.