Custom Build Rules¶
gen_rule¶
Windows note.
cmdis run by the host's default shell (/bin/shon POSIX,cmd.exeon Windows), so acmdwritten forshwill not work on Windows. Usecmd_bat(acmd.execommand) and/orcmd_bash(abashcommand) for portability — the platform-appropriate one is selected automatically. blade's own output-existence check is cross-platform.Keep gen_rule commands simple. For anything non-trivial, write a small Python script and call it (
cmd = 'python $SRC_DIR/gen.py $SRCS $OUTS'): Python is onPATHon every platform, so it is naturally cross-platform, easy to debug, and avoids per-shell quoting.
Used to customize your own construction rules, parameters:
- src_exts: list(str) The list of file extensions allowed in
src.
Without ., for example, ['m4'] can match config.m4. If it is empty, it means that all types of files are allowed.
Note that empty strings match files without extensions, such as ['h',''] matches vector.h and vector.
- outs: list, output file list
- cmd: str, the called command line, may contain the following variables, which will be replaced with actual values before running:
- $SRCS, space-separated list of source file names, relative to WORKSPACE
- $OUTS, space-separated list of output files, relative to WORKSPACE
- $SRCS[i] / $SRCS[name], a single input by index (all-digits) or by declared
name / basename, e.g.
$SRCS[0],$SRCS[calc.y] - $OUTS[i] / $OUTS[name], a single output by index or name, e.g.
$OUTS[0],$OUTS[parser.h]. When there is exactly one output,$OUTS[0]and$OUTSare equivalent. Prefer by-name ($OUTS[parser.h]) over by-index, since the index shifts if you reorderouts. - $SRC_DIR, the directory where the input file is located
- $OUT_DIR, the directory where the output file is located
- $FIRST_SRC, first input file path (deprecated — use
$SRCS[0]) - $FIRST_OUT, the path of the first output file (deprecated — use
$OUTS[0]) - BUILD_DIR, The root output directory, such as build[64,32]_[release, debug]
$(location target)/$(location target label)— replaced with the output file path of the referenced target. The optionallabelparameter selects a particular output (e.g.$(location //bin:server bin)). The target must have exactly one output (for that label).-
$(locations target)— replaced with all output files of the referenced target, space-separated. Use when the target produces several files, e.g.cmd = 'cat $(locations //idl:msgs) > $OUTS'. Commonly used ingen_rule.cmd,testdata,package, andsh_test. Example: -
cmd_bash: str, a command run via
bash(withset -e -o pipefail). Preferred on POSIX. (Not used on Windows — see below.) Same variables ascmd. - cmd_bat: str, a Windows batch command run via
cmd.exe /S /E:ON /V:ON /D /c. Preferred on Windows. Same variables ascmd. At least one ofcmd/cmd_bash/cmd_batmust be set; the platform-appropriate one is chosen automatically (Windows:cmd_bat→cmd; POSIX:cmd_bash→cmd). Provide bothcmd_batandcmd_bashin a single BUILD file for a cross-platform target — blade picks the right one per platform, so the BUILD never has to branch on the OS itself (cmdis the generic fallback for commands that are already portable). On Windows onlycmd.exeis used — there is no bash auto-detection (it was fragile and hurt reproducibility). To use bash on Windows, run blade under a POSIX environment (WSL / msys2 / cygwin), or invokebash -c "..."yourself insidecmd_bat. - cmd_name: str, the name of the command, used to display in simplified mode, the default is
COMMAND - generate_hdrs: bool, indicates whether this target will generate C/C++ header files other than the file names already listed in
outs. If a C/C ++ target depends on the gen_rule target that generates header files, then these header files need to be generated before compilation can begin. gen_rule will automatically analyze whether there are header files inouts, so there is no need to set it if all of the headers are listed inouts. This option will reduce the parallelism of compilation, because if a target can be divided into mutiple stages, such as: - generating source code (including header files)
- compiling
- generating library When the header file list is given accurately, after the first stage is generated, other targets can be built without waiting the whole target is built.
- export_incs: list, indicates the include path for generated header files, similar to
cc_library.export_incs, but NOTE its relative to the target dir. - system_export_incs: list, like
export_incsbut consumers compile with-isysteminstead of-Ifor these paths. Use when the generated headers come from third-party / vendored code whose own diagnostics should not be promoted to errors by the consumer's-Werror. Typical caller: a customcmake_build/autotools_buildmacro that wraps a foreign-language toolchain. Same path semantics (relative to the target dir). - cleans: list, specify the additional paths to be deleted when the
cleancommand is executed, which can be files or directories, relative to the$OUT_DIR. The files inoutswill always be deleted duringclean. But if some additional files or directories are generated, including them incleanscan ensure that they can be deleted during clean. - heavy: bool, indicates this a "heavy" target, that is, it will consume a lot of CPU or memory, making it impossible to parallel with other tasks or too much. Turning on this option will reduce build performance, but will help reduce build failures caused by insufficient resources.
Example:
```python gen_rule( name='test_gen_target', cmd='echo what_a_nice_day;touch test2.c', deps=[':test_gen'], outs=['test2.c'] ) ````
NOTE:
gen_rule only writes outs files in the subdir of BUILD_DIR, but when you use gen_rule
to generate source code and want to reference the generated source code in other targets, just
consider them as if they are generated in the source tree, without the BUILD_DIR prefix.
srcscan be empty, butoutscannot be empty, and at least one ofcmd/cmd_bash/cmd_batmust be set.gen_ruleshould only generate output files in the corresponding result output directory, and will not pollute the source code tree. But if you reference in other targets which generating source files withgen_rule, it is only necessary to assume that these files are generated in the source code directory, without considering the result directory prefix.- After the command is executed, the correct exit code must be returned, 0 means success, other values mean failure
- Successful commands should not output irrelevant information, and failed commands should output concise and useful error messages.
- When you need to use
$in a command, such as expanding environment variables or executing command substitution, you need to double write it as$$, such as$$(pwd). - Multiple duplicate or similar gen_rules should be considered as extensions and maintained in a separate
bldfile through include Functions are introduced to reduce code redundancy and better maintenance.