genrule()
genrule() is used to generate files from a shell command. It must produce a single output file or folder.Arguments
name(required) #The name of the genrule.
srcs(defaults to[]) #A list of files to be used in the shell command.
cmd(defaults toNone) #The shell command to run to generate the output file. It is the fallback of
bashandcmd_exe. It will be subject to the following environment variable substitutions:SRCS- A string expansion of the
srcsargument delimited by theenvironment_expansion_separatorargument where each element ofsrcswill be translated into an absolute path. SRCDIR- The absolute path to a directory to which sources are copied to prior to running the command.
OUTThe output file or directory for the
genrule(). This variable will have whatever value is specified by theoutargument. The value should be a valid filepath. The semantics of the shell command determine whether this filepath is treated as a file or a directory. If the filepath is a directory, then the shell command needs to create it.The file or directory specified by this variable must always be written by this command. If not, the execution of this rule will be considered a failure, halting the build process.
TMP- A temporary directory which can be used for intermediate results and will not be bundled into the output.
It is also possible to expand references to other rules within thecmd, using builtin string parameter macros. Note that all build rules expanded in the command will be automatically considered to be dependencies of thegenrule().$(classpath //path/to:target)- Expands a build rule for something that has a java classpath to the transitive classpath of that rule. If the rule does not have (or contribute to) a classpath, an exception will be thrown and the build will break.
$(exe //path/to:target)- Expands a build rule that results in an executable to the commands necessary to execute that command. For example, a
java_binary()may expand to a call tojava -jar path/to/target.jar. Files that are executable (perhaps generated by agenrule()) will also be expanded. If the build rule does not generate an executable output an exception will be thrown and the build will break. $(location //path/to:target)- Expands to the location of the output of the build rule. This means that you can refer to these without needing to be aware of how Buck is storing data on the disk mid-build.
$(maven_coords //path/to:target)- Expands to the Maven coordinates for the build rule. This allows you to access the Maven coordinates for Maven-aware build rules. The format of the expansion is:
<groupId>:<artifactId>[:<extension>[:<classifier>]]:<version>
bash(defaults toNone) #A platform-specific version of the shell command parameter
cmd. It runs on Linux and UNIX systems—including OSX—on whichbashis installed. It has a higher priority thancmd. Thebashargument is run with/bin/bash -c. It has access to the same set of macros and variables as thecmdargument.cmd_exe(defaults toNone) #A platform-specific version of the shell command parameter
cmd. It runs on Windows and has a higher priority thancmd. Thecmd_exeargument is run withcmd.exe /c. It has access to the same set of macros and variables as thecmdargument.type(defaults toNone) #Specifies the type of this genrule. This is used for logging and is particularly useful for grouping genrules that share an underlying logical "type".
For example, if you have the following
cxx_genruledefined in the root directory of your Buck projectcxx_genrule( name = 'cxx_gen', type = 'epilog', cmd = 'touch finish.txt; cp finish.txt $OUT', out = 'finish.txt' )
then the following
buck querycommandbuck query "attrfilter( type, 'epilog', '//...' )"
returns
//:cxx_gen
out(required) #The name of the output file or directory. The complete path to this argument is provided to the shell command through the
OUTenvironment variable.environment_expansion_separator(defaults to" ") #The delimiter between paths in environment variables, such as SRCS, that can contain multiple paths. It can be useful to specify this parameter if the paths could contain spaces.
no_remote(defaults toFalse) #Whether this rule (and all rules that depend on it) can be executed remotely. This does not change whether this rule (or any rule that depends on it) can be cached (locally or remotely). This feature may be removed in the future.
enable_sandbox(defaults toFalse) #Whether this target should be executed in a sandbox or not.
executable(defaults toFalse) #Whether the output of the genrule is itself executable. Marking an output as executable makes
buck runand$(exe ...)macro expansion work with this target.tests(defaults to[]) #List of build targets that identify tests that exercise this target.
visibility(defaults to[]) #List of build target patterns that identify the build rules that can include this rule as a dependency, for example, by listing it in their
depsorexported_depsattributes. For more information, see visibility.licenses(defaults to[]) #Set of license files for this library. To get the list of license files for a given build rule and all of its dependencies, you can use
buck query.labels(defaults to[]) #Set of arbitrary strings which allow you to annotate a build rule with tags that can be searched for over an entire dependency tree using
buck query attrfilter.
Examples
This genrule() uses a Python script to derive a newAndroidManifest.xml from an AndroidManifest.xml in the source tree. Note you don't need to prepend execution commands with python: Buck knows how to execute different kinds of binaries using $(exe) command.genrule(
name = 'generate_manifest',
srcs = [
'AndroidManifest.xml',
],
bash = '$(exe //python/android:basic_to_full) ' \
'$SRCDIR/AndroidManifest.xml > $OUT',
cmd_exe = '$(exe //python/android:basic_to_full) ' \
'%SRCDIR%\\AndroidManifest.xml > %OUT%',
out = 'AndroidManifest.xml',
)