Buck: String Parameter Macros

String Parameter Macros

This is liable to change in the future.

Some rules allow the use of specialized macros embedded within the strings of their parameters. These string parameter macros provide additional functionality, such as exposing the output paths of other rules.

Examples of rules that use string parameter macros are:

String parameter macros have the form

$(macroname [ argument ... ])

String parameter macros take a space-separated list of arguments, where each argument is a build target pattern.

If you need to prevent expansion of a string parameter macro, prefix the macro with a backslash.

\$(dirname ...)

For an example of preventing expansion in the context of a rule, see the Examples section below.

Supported macros

  • $(classpath //:foo) expands to the set of JARs that are in the classpath of the given target.
  • $(classpath_abi //:foo) expands to the set of Application Binary Interface (ABI) JARs that are in the classpath of the given target. For more information about using ABI JARs with Buck, see the topic Java ABIs.
  • $(exe //:foo) expands to the executable output of the given target—if the target produces such an executable.
  • $(location //:foo) expands to the output file or directory of the given target.
  • $(location //:foo[output]) expands to the named output file or directory of the given target, for rules that expose supplementary outputs.
  • $(maven_coords //:foo) expands to the maven coordinates associated with the given target.
  • $(output name) expands to the path of the named output of the rule in which you use this macro. Used only for rules that allow named supplementary outputs.
  • $(query_targets "queryfunction(//:foo)") executes the given query and expands to the list of targets that match. See the Query functions section below for the list of supported queryfunctions.
  • $(query_outputs "queryfunction(//:foo)") executes the given query and expands to the output files of the targets that match. See the Query functions section below for the list of supported queryfunctions.
  • $(query_targets_and_outputs [SEPARATOR] "queryfunction(//:foo)") executes the given query and expands to both the target names and the output files of the targets that match. Targets and paths are separated by SEPARATOR if provided, or a space if it is not. See the Query functions section below for the list of supported queryfunctions.

Query functions

The query_* macros accept a quoted query expression which supports the following query functions.

All of these except for classpath behave the same as the corresponding operations in buck query.

The classpath query function is used to query the classpath of java_library rules. It takes an optional second argument to limit the depth of the traversal. Its behavior is similar to the corresponding operation in buck audit.

The items in the preceding list link to the corresponding descriptions in the buck query and buck audit topics.

Examples

Example: Use a string parameter macro in a genrule() to copy the output of another rule.

genrule(
  name = 'gen',
  out  = 'out.txt',
  cmd  = 'cp $(location //some/other:rule) $OUT',
)

Example: Use a backslash to prevent macro expansion. The rule passes the dirname command to the shell to execute in a subshell; dirname is a Unix/Linux command-line utility that returns the directory of a specified file. We need to use an escape because the syntax for subshells is the same as the syntax for string parameter macros.

genrule(
  name = 'gen',
  out  = 'out.txt',
  cmd  = 'cp $SRCS \$(dirname $OUT)',
  srcs = [
    'test1.txt',
    'test2.txt',
  ],
)

Example: Queries

cmd = '$(query_targets "deps(:foo)")'
cmd = '$(query_outputs "filter(name_regex, deps(:bar))")'
cmd = '$(query_targets "attrfilter(annotation_processors, com.foo.Processor, deps(:app))")'

Frequently Asked Questions (FAQ)

  • When are macros evaluated? Macros are evaluated before the command is passed to the shell for execution. You can think of them as simple string replacements.
  • Can macros be nested? Macros cannot be nested. If you need to run an additional macro on the output of a previous macro, create a nested genrule definition and use the $(location) macro to read the output of the previous macro.
  • Are parentheses okay inside a macro? Inside a macro, parentheses must be balanced. Parentheses which are part of a quoted string are ignored.
  • Is white space okay inside a macro? Macro arguments are white space separated, so arguments which contain white space must be quoted.
  • Are nested quotes allowed? A single level of nested quotes is allowed, such as "My name is 'Buck'." or 'My name is "Buck".'). Note that when you use a macro in a BUCK file, you must ensure that quotes are properly escaped, so that the shell command that uses the macro forms a proper string.

Extended Backus—Naur form

The Extended Backus—Naur form (EBNF) grammar for a macro is as follows:

macro = "$(", macro_name, whitespace, [arg_list], ")";
macro_name = {all_ascii_chars - whitespace - parens};
whitespace = "\t" | "\n" | " " | "\r";
parens = "(" | ")";
arg_list = arg | arg, whitespace, arg_list;
arg = {all_ascii_chars - whitespace - parens}
      | "(", arg, ")"
      | "\"", [{-"\""}], "\""
      | "'", [{-"'"}], "'";