This plain example project demonstrates how to use built-in rules to define:
A single top-level TARGETS
is sufficient to describe the build of
a project that only uses built-in rules.
One of the simplest buildable target a user can define uses the built-in rule
generic
.
With this rule, custom shell commands can be run to produce the specified
outputs.
The simple_greeter
computes the file out.txt
from a static string using the
rule generic
. It is defined in the file TARGETS.
simple_greeter: {
type: 'generic',
cmds: 'printf "Hello World\n" > out.txt',
outs: 'out.txt',
},
To build the output of this greeter, run:
$ must build simple_greeter
INFO: Requested target is [["@","","","simple_greeter"],{}]
INFO: Discovered 1 actions, 0 trees, 0 blobs
INFO: Processed 1 actions, 0 cache hits.
INFO: Artifacts built, logical paths are:
out.txt [557db03de997c86a4a028e1ebd3a1ceb225be238:12:f]
By default, the subcommand build
will not pollute the source directory and
not stage any
outputs to your local file system. Instead, you have to use the subcommand
install
to stage the output to your local file system.
$ must install simple_greeter -o .
INFO: Requested target is [["@","","","simple_greeter"],{}]
INFO: Discovered 1 actions, 0 trees, 0 blobs
INFO: Processed 1 actions, 1 cache hits.
INFO: Artifacts can be found in:
./out.txt [557db03de997c86a4a028e1ebd3a1ceb225be238:12:f]
$ cat ./out.txt
Hello World
If you just want to see the generated output without installing it, you can also
use the -P
option after the subcommand build
.
$ must build simple_greeter -P out.txt
INFO: Requested target is [["@","","","simple_greeter"],{}]
INFO: Discovered 1 actions, 0 trees, 0 blobs
INFO: Processed 1 actions, 1 cache hits.
INFO: Artifacts built, logical paths are:
out.txt [557db03de997c86a4a028e1ebd3a1ceb225be238:12:f]
Hello World
The file_greeter
reads the string that will be used for greeting from the
local file name.txt. This time, two commands were used to compute
the output. For convenience, the Jsonnet multi-line string operator (|||
) is
used to generate a newline-separated string.
file_greeter: {
type: 'generic',
// Field 'cmds' expects a list of strings or a newline-separated string.
// -> Jsonnet multi-line string generates a newline-separated string.
cmds: |||
printf "Hello " > out.txt
cat name.txt >> out.txt
|||,
outs: 'out.txt',
deps: ['name.txt'],
},
To build this greeter and see its output, run:
$ must build file_greeter -P out.txt
INFO: Requested target is [["@","","","file_greeter"],{}]
INFO: Discovered 1 actions, 0 trees, 0 blobs
INFO: Processed 1 actions, 0 cache hits.
INFO: Artifacts built, logical paths are:
out.txt [34c97eeca89eb286aed798efd885da6ea77e9a96:13:f]
Hello Galaxy
The input_greeter
runs similar commands to the previous one. The major
difference is that the file input.txt
is not a local file, but instead the
output of the depending target input.txt
.
input_greeter: {
type: 'generic',
cmds: |||
printf "Hello " > out.txt
cat input.txt >> out.txt
|||,
outs: 'out.txt',
// Dependency 'input.txt' is a target (see below), not a file!
deps: ['input.txt'],
},
Note that instead of depending on another target, you can also explicitly depend on a local file
input.txt
(if it exists) by using the explicitfile()
reference (e.g.,file('input.txt')
).
To build this greeter and see its output, run:
$ must build input_greeter -P out.txt
INFO: Requested target is [["@","","","input_greeter"],{}]
INFO: Discovered 1 actions, 0 trees, 1 blobs
INFO: Processed 1 actions, 0 cache hits.
INFO: Artifacts built, logical paths are:
out.txt [a17dcb5259599be90a546576d571d2afcb66e37b:15:f]
Hello Universe
File-gen targets use the built-in
rule
file_gen
to generate files.
Lets have a look at the file-gen target input.txt
defined in
TARGETS
. It generates the file input.txt
from the string
specified in data
. The value
for data
is read from the variable INPUT_STRING
, which defaults to string
"Universe\n"
if not set (see expression
var()
).
'input.txt': {
type: 'file_gen',
// We want to read variable 'INPUT_STRING'.
arguments_config: 'INPUT_STRING',
name: 'input.txt',
// Use content of variable 'INPUT_STRING' if set, or else use 'Universe\n'
data: var('INPUT_STRING', default='Universe\n'),
},
Using the variable INPUT_STRING
, a caller can specify a string to use for the
greeting on the command line via the -D
option:
$ must build input_greeter -P out.txt -D'{"INPUT_STRING":"Mustbuild\n"}'
INFO: Requested target is [["@","","","input_greeter"],{"INPUT_STRING":"Mustbuild\n"}]
INFO: Discovered 1 actions, 0 trees, 1 blobs
INFO: Processed 1 actions, 0 cache hits.
INFO: Artifacts built, logical paths are:
out.txt [b874bf2dd8d4c5bde51c7bda3b02a4a401458771:16:f]
Hello Mustbuild
Alternatively, configuration variables can also be specified as a JSON file via the option
--config
.
Last, we would like to show the built-in rule
install
.
It allows the flexible restaging (renaming/restructuring) of artifacts.
For example, what if we want to install the outputs of all greeters at once? It
would lead to a conflict, as all of them produce an output file with the same
name out.txt
. In such scenarios, the following install
target can be used to
restage and combine the outputs of all greeters.
ALL: {
type: 'install',
files: {
'out/simple.txt': 'simple_greeter',
'out/file.txt': 'file_greeter',
'out/input.txt': 'input_greeter',
},
},
To build this target and produce all outputs, run:
$ must build ALL
INFO: Requested target is [["@","","","ALL"],{}]
INFO: Discovered 3 actions, 0 trees, 1 blobs
INFO: Processed 3 actions, 3 cache hits.
INFO: Artifacts built, logical paths are:
out/file.txt [34c97eeca89eb286aed798efd885da6ea77e9a96:13:f]
out/input.txt [a17dcb5259599be90a546576d571d2afcb66e37b:15:f]
out/simple.txt [557db03de997c86a4a028e1ebd3a1ceb225be238:12:f]