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.
The BUILD file for a package may only refer directly to source files belonging
to another package if they are explicitly exported with an
exports_files() statement. Read more about
visibility of files.
As a legacy behaviour, also files mentioned as input to a rule are exported
with the default visibility until the flag
--incompatible_no_implicit_file_export
is flipped. However, this behavior should not be relied upon and actively
migrated away from.
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, allow_empty=True)
Glob is a helper function that finds all files that match certain path patterns, and returns a new, mutable, sorted list of their paths. Glob only searches files in its own package, and looks only for source files (not generated files nor other targets).
A source file's Label is included in the result if the file's package-relative
path matches any of the include patterns and none of the
exclude patterns.
The include and exclude lists contain path patterns
that are relative to the current package. Every pattern may consist of one or
more path segments. As usual with Unix paths, these segments are separated by
/. Segments may contain the * wildcard: this matches
any substring in the path segment (even the empty substring), excluding the
directory separator /. This wildcard can be used multiple times
within one path segment. Additionally, the ** wildcard can match
zero or more complete path segments, but it must be declared as a standalone
path segment.
foo/bar.txtmatches exactly thefoo/bar.txtfile in this packagefoo/*.txtmatches every file in thefoo/directory if the file ends with.txt(unlessfoo/is a subpackage)foo/a*.htm*matches every file in thefoo/directory that starts witha, then has an arbitrary string (could be empty), then has.htm, and ends with another arbitrary string; such asfoo/axx.htmandfoo/a.htmlorfoo/axxx.html**/a.txtmatches everya.txtfile in every subdirectory of this package**/bar/**/*.txtmatches every.txtfile in every subdirectory of this package, if at least one directory on the resulting path is calledbar, such asxxx/bar/yyy/zzz/a.txtorbar/a.txt(remember that**also matches zero segments) orbar/zzz/a.txt**matches every file in every subdirectory of this packagefoo**/a.txtis an invalid pattern, because**must stand on its own as a segment
If the exclude_directories argument is enabled (set to 1), files of
type directory will be omitted from the results (default 1).
If the allow_empty argument is set to False, the
glob function will error-out if the result would otherwise be the
empty list.
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, you must append an explicit list of generated files to the glob. See the example below with:myliband:gen_java_srcs. -
If a rule has the same name as a matched source file, the rule will "shadow" the file.
To understand this, remember that
glob()returns a list of paths, so usingglob()in other rules' attribute (e.g.srcs = glob(["*.cc"])) has the same effect as listing the matched paths explicitly. If for exampleglob()yields["Foo.java", "bar/Baz.java"]but there's also a rule in the package called "Foo.java" (which is allowed, though Bazel warns about it), then the consumer of theglob()will use the "Foo.java" rule (its outputs) instead of the "Foo.java" file. See GitHub issue #10395 for more details. - 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
**/*.ccin packagexdoes not includex/y/z.ccifx/yexists 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.ccif there was no package calledx/yor 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 completely matched by both the**and the*wildcards. If you want to match a hidden file with a compound pattern, your pattern needs to begin with a.. For example,*and.*.txtwill match.foo.txt, but*.txtwill not. Hidden directories are also matched in the same manner. Hidden directories may include files that are not required as inputs, and can increase the number of unnecessarily globbed files and memory consumption. To exclude hidden directories, add them to the "exclude" list argument. -
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.
You can use this, 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 use is as follows:
sh_binary(
name = "mytarget",
srcs = select({
":conditionA": ["mytarget_a.sh"],
":conditionB": ["mytarget_b.sh"],
"//conditions:default": ["mytarget_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 or
constraint_value,
which "matches" if the target's configuration matches an expected set of
values. The value of mytarget#srcs then becomes whichever
label list matches the current invocation.
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:defaultis considered to match if no other condition matches. If this condition is left out, some other rule must match to avoid an error. selectcan 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.selectworks with most, but not all, attributes. Incompatible attributes are markednonconfigurablein their documentation.subpackages
subpackages(include, exclude=[], allow_empty=True)
subpackages()is a helper function, similar toglob()that lists subpackages instead of files and directories. It uses the same path patterns asglob()and can match any subpackage that is a direct decendant of the currently loading BUILD file. See glob for a detailed explanation and examples of include and exclude patterns.The resulting list of subpackages returned is in sorted order and contains paths relative to the current loading package that match the given patterns in
includeand not those inexclude.Example
The following example lists all the direct subpackages for the package
foo/BUILD# The following BUILD files exist: # foo/BUILD # foo/bar/baz/BUILD # foo/sub/BUILD # foo/sub/deeper/BUILD # # In foo/BUILD a call to subs = subpackages(include = ["**"]) # results in subs == ["sub", "bar/baz"] # # 'sub/deeper' is not included because it is a subpackage of 'foo/sub' not of # 'foo'
In general it is preferred that instead of calling this function directly that users use the 'subpackages' module of skylib.