Skip to main content

String parameter macros

Many rule attributes (the ones with type attrs.arg) support expanding references to other rules using a mechanism called string parameter macros. All expanded build rules are automatically added as dependencies.

Note that the paths returned by these macros are relative paths. Using relative paths ensures that your builds are hermetic, that is, they are reproducible across different machine environments.

$(location //path/to:target)

Expands to the location of the output of the specified build rule. This means that you can refer to the output without needing to be aware of how Buck is storing data on the disk mid-build.

For example:

cxx_test(
name = "my_test",
srcs = ["main.cpp"],
preprocessor_flags = ["-DTEST_DIR=$(location :test_dir)"],
)

filegroup(
name = "test_dir",
srcs = [
"test_files/foo.json",
"test_files/bar.toml",
],
)

$(source relative/path/to/source)

Expands to the location of the specified source. The difference with using $(location path/to:export_file_target) is that the path points to the file in the source tree, rather than a copy or symlink in buck-out.

For example:

cxx_test(
name = "my_test",
srcs = ["main.cpp"],
preprocessor_flags = ["-DMY_SOURCE_FILE=$(source path/to/my_source_file)"],
)

$(exe //path/to:target)

Expands a build rule that results in an executable to the commands necessary to run that executable as part of the build.

For example, a java_binary() might expand to a call to java -jar path/to/target.jar. Files that are executable (perhaps generated by a genrule()) are also expanded.

If the build rule does not generate an executable output, then an exception is thrown and the build breaks.

If the $(exe my_dependency) dependency should actually be built with the target platform, use $(exe_target my_dependency) instead, which will stick to the same platform as the target.

$(exe_target //path/to:target)

Identical to $(exe //path/to:target), except that the target is built using the target platform, rather than the execution platform.

This is for example useful to get the paths to executables to be run as part of tests. For example:

sh_test(
name = "my_test",
args = [
"$(exe_target //path/to:target_to_test)",
],
# `my_test.sh` takes a single argument, which is the path to an executable
# to test.
test = "my_test.sh",
visibility = ["//risk/tap_enricher/..."],
)

$(query_targets queryfunction(//path/to:target))

Runs a query on the given target and replaces the macro with the matching targets.

For example:

my_rule(
name = "example",
# Will be replaced by all dependencies of `some_target`.
foo = "$(query_targets deps(:some_target))"
)

$(query_outputs queryfunction(//path/to:target))

Runs a query on the given target and replaces the macro with the outputs of the matching targets.

For example:

my_rule(
name = "example",
# Will be replaced by the outputs of all dependencies of `some_target`.
foo = "$(query_outputs deps(:some_target))"
)

$(query_targets_and_outputs [separator] queryfunction(//path/to:target))

Runs a query on the given target and replaces the macro with matching targets and their outputs, which are separated by an optional separator (defaults to a space).

For example:

my_rule(
name = "example",
# Will be replaced by the space-separated dependencies of `some_target`, as
# well as their outputs.
foo = "$(query_targets_and_outputs deps(:some_target))"
)

$(classpath //path/to:target)

Expands to the transitive classpath of the specified build rule, provided that the rule has a Java classpath. If the rule does not have (or contribute to) a classpath, then an exception is thrown and the build breaks.