JUSTBUILD(1)

πŸ“¦
version 1.6.5 Β· 3 versions
, in ubuntu stonking

πŸ’– NAME πŸ’–

hey bestie! πŸ‘‹ this is justbuild(1), straight outta the General Commands Manual, and the name on the tin is justbuild β€” a generic build tool. it’s giving β€œwe build things generically” and honestly? iconic. 🫢


✨ SYNOPSIS ✨

okay so here’s the whole β€œhow do you even call this thing” vibe check. type these exactly, no improv:

justbuild version
justbuild {analyse|build} [OPTION]...  [[module] target]
justbuild install [OPTION]...  -o OUTPUT_DIR [[module] target]
justbuild install-cas [OPTION]...  OBJECT_ID
justbuild add-to-cas [OPTION]...  PATH
justbuild describe [OPTION]...  [[module] target]
justbuild rebuild [OPTION]...  [[module] target]
justbuild traverse [OPTION]...  -o OUTPUT_DIR -g GRAPH_FILE
justbuild gc [OPTION]...
justbuild execute [OPTION]...
justbuild serve SERVE_CONFIG_FILE

🌸 DESCRIPTION 🌸

so Just is a generic multi-repository build system; language-specific knowledge is described in separate rule files. for every build action, the relative location of the inputs is independent of their physical location. this staging allows taking sources from different locations (logical repositories), including bare Git repositories. targets are defined using JSON format, in proper files (by default, named TARGETS). targets are uniquely identified by their name, the repository, and the module they belong to. a module is the relative path from the repository target root directory to a subdirectory containing a target file.

the module’s name of the targets defined at the target root level is the empty string. specifying the correct repository, target root, module, and target name allows to process that target independently of the current working directory. iykyk β€” location independence is the whole moment. πŸ’…

if the module is not specified on the command line, justbuild sets the module corresponding to the current working directory. easy peasy.

if a target is not specified, the lexicographically-first target, according to native byte order, is used. so, a target named with an empty string will always be the default target for that module. periodt.

if a target depends on other targets defined in other modules or repositories, justbuild will recursively visit all and only the required modules. not extra, not missing β€” all and only. the algorithm ate. πŸ”₯

the main repository is the repository containing the target specified on the command line. the main repository can either be read from the multi-repository configuration file if it contains the key main or through the option --main. the command-line option --main overrides what is eventually read from the multi-repository configuration file. if neither the multi-repository configuration file contains the main key nor the --main option is provided, the lexicographical first repository from the multi-repository configuration file is used as main.

the workspace_root of the main repository is then defined as follows. if the option --workspace-root is provided, then workspace_root is set accordingly. if the option is not provided, justbuild checks if it is specified within the multi-repository configuration file. if it is, then it is set accordingly. if not, justbuild starts looking for a marker in the current directory first, then in all the parent directories until it finds one. the supported markers are:

  • ROOT file (can be empty, content is ignored)
  • WORKSPACE (can be empty, content is ignored)
  • .git (can be either a file - empty or not, content is ignored - or the famous directory)

if it fails, bestie, justbuild errors out. πŸ’€ no vibes, just error.

for non-main repositories, the workspace_root entry must be declared in the multi-repository configuration file.

afterwards, target_root, rule_root, and expression_root directories for the main repository are set using the following strategy. if the corresponding command-line option is specified, then it is honored. otherwise, it is read from the multi-repo configuration file. if it is not specified there, the default value is used. the default value of target_root is workspace_root, of rule_root is target_root, and of expression_root is rule_root. cute little inheritance chain, honestly.

finally, the file names where targets, rules, and expressions are defined for the main repository. if the corresponding key is present in the multi-repository configuration file, it is set accordingly. if the user gives the corresponding command-line option, it overwrites what is eventually read from the configuration file. if they are not explicitly stated neither within the multi-repository configuration file nor on the command line, the default values are used, which are TARGETS, RULES, and EXPRESSIONS, respectively. those are the defaults, bestie β€” memorize them. πŸŽ€

for non-main repositories (i.e., repositories defining targets required by the target given on the command line), target_root, rule_root, expression_root, and file names of targets, rules and expressions, if different from the default values, must be declared in the multi-repository configuration file. πŸ’…

✨ SUBCOMMANDS ✨

okay bestie, buckle up, because these subcommands are the whole personality of justbuild. πŸ’…

version πŸŽ€

It prints a JSON object to stdout with all the version tea about the tool you're using. This JSON object has at least these keys, no cap:

  • "version" β€” the version itself, as a list of numbers of length at least 3, following the usual convention that version numbers are compared lexicographically. ✨
  • "suffix" β€” the version suffix as a string. Generally, suffixes starting with a + symbol are positive offsets to the version, while suffixes starting with a ~ symbol are negative offsets. πŸ¦‹
  • "SOURCE_DATE_EPOCH" β€” either a number or null. If it's a number, it's the time, in seconds since the epoch, of the last commit that went into this binary. It's null if that time is not known (e.g., in development builds). 😭

analyse|build|install 🌈

These three are literally besties: analyse, build, and install are strictly related. From left to right, one is a subset of the other. build performs work on top of analyse, and install on top of build. When you issue build, analyse is called underneath. So bestie, there is no need to run these three subcommands sequentially β€” they're already linked. πŸ‘‘

analyse πŸ”

analyse reads the target graph from TARGETS files for the given target, computes the action graph (required by e.g., build, install, traverse), and reports the artifacts, provides, and runfiles of the analysed target.

In short, the analyse subcommand identifies all the steps required to build a given target without actually performing those steps. It's giving "plan the outfit but don't leave the house" energy. πŸ’…

This subcommand, issued with proper flags, can dump in JSON format artifacts, action graph, nodes, actions, (transitive) targets (both named and anonymous), and trees. Iconic. ✨

build πŸ› οΈ

This subcommand performs the actions contained in the action graph computed through the analyse phase.

If building locally, the building process is performed in temporary separate directories to allow for staging according to the logical path described in the TARGETS file. Since artifacts are only stored in the CAS, the user has to use either the install or install-cas subcommand to get them. Don't forget, bestie! 😭

justbuild allows for both local (i.e., on the same machine where justbuild is used) and remote compilation (i.e., by sending requests over a TCP connection, e.g., to a different machine, cluster or cloud infrastructure). In case of a remote compilation, artifacts are compiled remotely and stored in the remote CAS. install and install-cas subcommands can be used to locally fetch and stage the desired artifacts. 🌈

install πŸ“¦

The install subcommand determines which (if any) actions need to be (re)done and issues the command to (re)run them. Then, it installs the artifacts (stored in the local or remote CAS) of the processed target under the given OUTPUT_DIR (set by option -o) honoring the logical path (aka, staging). If the output path does not exist, it will create all the necessary folders and subfolders. If files are already present, they will be overwritten. Periodt. πŸ’…

rebuild πŸ”

This subcommand inspects if builds are fully reproducible or not (e.g., time stamps are used). It simply rebuilds and compares artifacts to the cached build reporting actions with different output. To do so in a meaningful way, it requires that previous build is already in the cache (local or remote). So like, no cache, no vibe check. 🫢

describe πŸ“

The describe subcommand allows for describing the rule generating a target. The rule is resolved in precisely the same way as during the analysis. The doc-strings (if any) from the rule definition (if user-defined) are reported, together with a summary of the declared fields and their types. The multi-repository configuration is honored in the same way as during analyse and build; in particular, the rule definition can also reside in a git-tree root. Slay. πŸ‘‘

install-cas πŸ“₯

install-cas fetches artifacts from CAS (Content Addressable Storage) by means of their OBJECT_ID (object identifier). The canonical format of an object identifier is [<hash>:<size>:<type>]; however, when parsing an object identifier, install-cas uses the following default rules, to make usage simpler. πŸŽ€

  • The square brackets are optional.
  • If the size is missing (e.g., because the argument contains no colon), or cannot be parsed as a number, this is not an error, and the value 0 is assumed. While this is almost never the correct size, many CAS implementations, including the local CAS of justbuild itself, ignore the size for lookups.
  • From the type, only the first letter (f for non-executable file, x for executable file, and t for tree) is significant; the rest is ignored. If the type is missing (e.g., because the argument contains less than two colons), or its first letter is not one of the valid ones, f is assumed.

Depending on whether the output path is set or not, the behavior is different. πŸ‘€

Output path is omitted

If the output path is omitted, it prints the artifact content to stdout and if the artifact is a tree, it will print a human readable description.

Output path is set

  1. Output path does not exist

The artifact will be staged to that path. If artifact is a file, the installed one will have the name of the output path. If the artifact is a tree, it will create a directory named like the output path, and will stage all the entries (subtrees included) under that directory.

  1. Output path exists and it is a directory

If the artifact is a tree, a directory named with the hash of tree itself is created under the output path, and all the entries and subtrees are installed inside the hash-named directory.

If the artifact is a file, it is installed under the output path and named according to the hash of the artifact itself.

  1. Output path exists and it is a file

If the artifact is a file, it will replace the existing file. If the artifact is a tree, it will cause an error.

add-to-cas βž•

add-to-cas adds a file or directory to the local CAS and reports the hash (without size or type information) on stdout. If a remote endpoint is given, the object is also uploaded there. A main use case of this command is to simplify the setup of "git tree" repositories, where it can also avoid checking out a repository of a foreign version-control system twice. Big brain energy. 🧠✨

traverse πŸšΆβ€β™€οΈ

It allows for the building and staging of requested artifacts from a well-defined GRAPH_FILE. See just-graph-file(5) for more details. πŸ‘‘

gc πŸ—‘οΈ

The gc subcommand triggers garbage collection of the local cache. More precisely, it rotates the cache and CAS generations. During a build, upon cache hit, everything related to that cache hit is uplinked to the youngest generation; therefore, upon a call to gc everything not referenced since the last call to gc is purged and the corresponding disk space reclaimed. It's giving spring cleaning but for bytes. 🧹

Additionally, and before doing generation rotation,

  • left-over temporary directories (e.g., from interrupted justbuild invocations) are removed, and
  • large files are split and only the chunks and the information how to assemble the file from the chunks are kept; in this way disk space is saved without losing information.

As the non-rotating tasks can be useful in their own right, the --no-rotate option can be used to request only the clean-up tasks that do not lose information.

If it is necessary to remove the entire cache, the --all option can be used to skip generation rotation and splitting of large files. In this scenario, all cache generations get removed starting from the oldest generation.

--no-rotate and --all are incompatible options. Don't try it, bestie. πŸ’€

execute πŸƒ

This subcommand starts a single node remote execution service, honoring the just native remote protocol.

If the flag --compatible is provided, the execution service will honor the original remote build execution protocol. 🌈

serve 🍽️

This subcommand starts a service that provides target dependencies needed for a remote execution build. It expects as its only and mandatory argument the path to a configuration file, following the format described in just-serve-config(5). No cap. 🫢


✨ OPTIONS ✨

Generic program information

  • -h, --help β€” Output a usage message and exit. Supported by: all subcommands. πŸ’–

Compatibility options

  • --compatible β€” At increased computational effort, be compatible with the original remote build execution protocol. As the change affects identifiers, the flag must be used consistently for all related invocations. Supported by: add-to-cas|analyse|build|describe|install-cas|install|rebuild|traverse|execute. πŸ”₯

Build configuration options

  • --action-timeout NUM β€” Action timeout in seconds. (Default: 300). The timeout is honored only for the remote build. Supported by: analyse|build|install|rebuild|traverse. ⏳
  • -c, --config PATH β€” Path to configuration file. Supported by: analyse|build|describe|install|rebuild. πŸŽ€
  • -C, --repository-config PATH β€” Path to configuration file for multi-repository builds. See just-repository-config(5) for more details. Supported by: analyse|build|describe|install|rebuild|traverse. 🌸
  • -D, --defines JSON β€” Defines, via an in-line JSON object a configuration to overlay (in the sense of map_union) to the configuration obtained by the --config option. If -D is given several times, the -D options overlay in the order they are given on the command line. Supported by: analyse|build|describe|install|rebuild. πŸ’…
  • --request-action-input ACTION β€” Modify the request to be, instead of the analysis result of the requested target, the input stage of the specified action as artifacts, with empty runfiles and a provides map providing the remaining information about the action, in particular as "cmd" the arguments vector and "env" the environment.

An action can be specified in the following ways

  • an action identifier prefixed by the % character
  • a number prefixed by the # character (note that it requires quoting on most shells). This specifies the action with that index of the actions associated directly with that target; the indices start from 0 onwards, and negative indices count from the end of the array of actions.
  • an action identifier or number without prefix, provided the action identifier does not start with either % or # and the number does not happen to be a valid action identifier.

Supported by: analyse|build|describe|install|rebuild. 🌟

  • --expression-file-name TEXT β€” Name of the expressions file. Supported by: analyse|build|describe|install|rebuild. πŸ“„
  • --expression-root PATH β€” Path of the expression files’ root directory. Default: Same as --rule-root. Supported by: analyse|build|describe|install|rebuild. 🌿
  • -L, --local-launcher JSON_ARRAY β€” a JSON array of strings, aka the launcher that gets prepended to each action's command before it runs locally. Default value: ["env", "--"]. Supported by: analyse | build | install | rebuild | traverse | execute.
  • --local-build-root PATH β€” the root for your local CAS, cache, and build directories bestie πŸ—‚οΈ. Don't stress if the path isn't there yet β€” it gets created for you. Supported by: add-to-cas | build | describe | install-cas | install | rebuild | traverse | gc | execute.
  • --main NAME β€” the repository the target gets taken from. Supported by: analyse | build | describe | install | rebuild | traverse.
  • --rule-file-name TEXT β€” name of the rules file. Supported by: analyse | build | describe | install | rebuild.
  • --rule-root PATH β€” path of the rule files' root directory. Default: same as --target-root. Supported by: analyse | build | describe | install | rebuild.
  • --target-file-name TEXT β€” name of the targets file. Supported by: analyse | build | describe | install | rebuild.
  • --target-root PATH β€” path of the target files' root directory. Default: same as --workspace-root. Supported by: analyse | build | describe | install | rebuild.
  • -w, --workspace-root PATH β€” path of the workspace's root directory. Supported by: analyse | build | describe | install | rebuild | traverse.

✨ General output options ✨

  • --dump-artifacts-to-build PATH β€” file path where the artifacts-to-build get written. The output format is a JSON map with the staging path as key and the intentional artifact description as value. Supported by: analyse | build | install | rebuild.
  • --dump-artifacts PATH β€” dumps the artifacts generated by the target you gave. If you pass - as the PATH, it gets read as stdout πŸ“€. Heads up though: passing ./- instead creates a file literally named - in the current directory, not stdout β€” sneaky!! The output format is a JSON map with the staging path as key and the object id description (hash, type, size) as value. Every artifact here is guaranteed to be KNOWN in CAS. Which means this option cannot be used with analyse. Supported by: build | install | rebuild | traverse.
  • --profile PATH β€” writes a profile to the path you name. Peep just-profile(5) for the tea on the format β˜•. Supported by: analyse | build | install | rebuild | describe.
  • --dump-graph PATH β€” file path for writing the action graph description. just-graph-file(5) has the deets. Supported by: analyse | build | install | rebuild.
  • --dump-plain-graph PATH β€” same as dumping the action graph description to a file, except without the extra "origins" key. Again, just-graph-file(5) for more. Supported by: analyse | build | install | rebuild.
  • -f, --log-file PATH β€” path to the local log file. justbuild stashes everything it printed to stderr into this log file, along with the thread id and the timestamp of when that output was generated πŸ•°οΈ. Supported by: add-to-cas | analyse | build | describe | install | install-cas | rebuild | traverse | gc | execute.
  • --log-limit NUM β€” the log limit, in the interval [0,6]. Higher = more verbose. Default: 3. Supported by: add-to-cas | analyse | build | describe | install | install-cas | rebuild | traverse | gc | execute.
  • --restrict-stderr-log-limit NUM β€” restricts console logging to the minimum of whatever you set with --log-limit and the value you put here. By default the log level at the console isn't additionally restricted at all. Supported by: add-to-cas | analyse | build | describe | install | install-cas | rebuild | traverse | gc | execute.
  • --plain-log β€” no ANSI escape sequences for highlighting messages. plain and simple, no aesthetic ✨. Supported by: add-to-cas | analyse | build | describe | install | install-cas | rebuild | traverse | gc | execute.
  • --log-append β€” appends messages to the log file instead of overwriting what was already there. Supported by: add-to-cas | analyse | build | describe | install | install-cas | rebuild | traverse | gc | execute.
  • --expression-log-limit NUM β€” in error messages, truncates the entries in the enumeration of the active environment, plus the expression being evaluated, down to this many characters. Default: 320. Supported by: analyse | build | install.
  • --serve-errors-log PATH β€” path to a local file where justbuild writes, in machine readable form, references to all the errors that happened on the serve side πŸ‘€. More precisely: the value is a JSON array with one element per failure, and each element is a pair (an array of length 2) made of the configured target (serialized, as usual, as a pair of a qualified target name and a configuration) and a string with the hex representation of the blob identifier of the log. The log itself is guaranteed to be available on the remote-execution side. Supported by: analyse | build | install.
  • -P, --print-to-stdout LOGICAL_PATH β€” after building, prints the artifact you named to stdout. Supported by: build | install | rebuild | traverse.
  • -p, --print-unique-artifact β€” after building, prints the unique artifact to stdout, if there even is one. If -P was given, or the number of artifacts isn't precisely one, this option just does nothing. tragic 😭. Supported by: build | install | rebuild | traverse.
  • -s, --show-runfiles β€” stop omitting runfiles from the build report. Supported by: build | install | rebuild | traverse.
  • --target-cache-write-strategy STRATEGY β€” the strategy for creating target-level cache entries. The supported values are:
    • sync β€” synchronize the artifacts of the export targets and write target-level cache entries. This is the default behaviour πŸ’….
    • split β€” synchronize the artifacts of the export targets, using blob splitting if the remote-execution endpoint supports it, and write target-level cache entries. Unlike the default strategy, extra entries (the chunks) get created in the CAS β€” but subsequent syncs of similar blobs might need less traffic πŸš€.
    • disable β€” don't write any target-level cache entries. Since nothing has to be synced at all, this can be handy for one-off builds of a project, or when your connection to the remote-execution endpoint is crawling through a very slow network 🐌. Supported by: build | install | rebuild.

🌸 Output dir and path 🌸

  • -o, --output-dir PATH β€” path of the directory where outputs get copied. If the output path doesn't exist yet, all the necessary folders and subfolders get created. If artifacts were already staged there, they get overwritten (no cap). Required by: install | traverse.
  • -o, --output-path PATH β€” install path for the artifact. The install-cas section has more details for you. Supported by: install-cas.
  • --archive β€” instead of installing the requested tree, installs an archive containing the content of that tree. It is a user error to specify --archive and not request a tree β€” so pls don't πŸ™ˆ. Supported by: install-cas.
  • --raw-tree β€” when installing a tree to stdout, i.e. when no -o option is given, dumps the raw tree instead of a pretty-printed version. This option gets ignored if --archive is given. Supported by: install-cas.
  • -P, --sub-object-path PATH β€” instead of taking the specified tree object itself, take the object at the specified logical path inside it πŸ”. Supported by: install-cas.
  • --remember β€” makes sure all installed artifacts are available in the local CAS too, even when you're using remote execution. Supported by: install | traverse | install-cas.

🧚 Parallelism options 🧚

  • -J, --build-jobs NUM β€” how many jobs run during the build phase. Default: same as --jobs. Supported by: analyse | build | install | rebuild | traverse.
  • -j, --jobs NUM β€” how many jobs run. Default: number of cores. Supported by: analyse | build | describe | install | rebuild | traverse.

πŸ”₯ Remote execution options πŸ”₯

Since remote execution properties shard the target-level cache, they're also available for analysis. That way, the same action identifiers can be achieved despite the extensional projection inherent to target-level caching β€” e.g. in conjunction with --request-action-input.
  • --remote-execution-property KEY:VAL β€” a remote execution property as a key-value pair. Pass this option multiple times and the pairs accumulate. If multiple pairs share the same key, the latest one wins πŸ‘‘. Supported by: analyse | build | install | rebuild | traverse.
  • -r, --remote-execution-address NAME:PORT β€” address of the remote execution service. Supported by: add-to-cas | analyse | build | describe | install-cas | install | rebuild | traverse.
  • --remote-instance-name NAME β€” value to pass as instance_name in the remote execution API. Supported by: add-to-cas | analyse | build | describe | install-cas | install | rebuild | traverse.
  • --endpoint-configuration FILE β€” a file describing how to dispatch to different remote-execution endpoints based on the execution properties πŸ›°οΈ. The format is a JSON list of pairs (lists of length two) of an object of strings and a string. The first entry describes a condition (the remote-execution properties have to agree on the domain of this object), and the second entry is a remote-execution address in the NAME:PORT format, same as for the -r option. The first matching entry (if there is one) gets taken; if none matches, the default execution endpoint is taken instead (either the one specified by -r, or local execution if no endpoint was specified at all). Supported by: analyse | build | install | rebuild | traverse.
  • --max-attempts NUM β€” if a remote procedure call (rpc) returns grpc::StatusCode::UNAVAILABLE, that rpc gets retried at most NUM times. Default: 1, i.e. no retry. Supported by: analyse | build | describe | install | rebuild | traverse.
  • --initial-backoff-seconds NUM β€” before retrying for the second time, the client waits this many seconds plus a jitter, so the workload spreads out nicer. Default: 1. Supported by: analyse | build | describe | install | rebuild | traverse.
  • --max-backoff-seconds NUM β€” from the third attempt (included) onward, the backoff time doubles at each attempt until it goes over the max-backoff-seconds parameter. From that point on, the waiting time is computed as max-backoff-seconds plus a jitter. Default: 60. Supported by: analyse | build | describe | install | rebuild | traverse.
  • --max-attempts NUM β€” if a remote procedure call (rpc) returns grpc::StatusCode::UNAVAILABLE, that rpc gets retried at most NUM times. Default: 1, i.e. no retry. Supported by: analyse | build | install | rebuild | traverse.
  • --initial-backoff-seconds NUM β€” before retrying for the second time, the client waits this many seconds plus a jitter, to better distribute the workload. Default: 1. Supported by: analyse | build | install | rebuild | traverse.
  • --max-backoff-seconds NUM β€” from the third attempt (included) onward, the backoff time doubles at each attempt until it exceeds the max-backoff-seconds parameter. From there, the waiting time is computed as max-backoff-seconds plus a jitter. Default: 60. Supported by: analyse | build | install | rebuild | traverse.

πŸ’œ Remote serve options πŸ’œ

  • -R, --remote-serve-address NAME:PORT β€” address of the remote execution service. Supported by: analyse | build | describe | install | rebuild.

πŸ” Authentication options ✨

Okay bestie, real talk: only TLS and mutual TLS (mTLS) are supported here. That's it. That's the whole security menu. πŸ’…

  • --tls-ca-cert PATH β€” Path to a TLS CA certificate that is trusted to sign the server certificate. Supported by: add-to-cas|analyse|build|describe|install-cas|install|rebuild|traverse|execute.
  • --tls-client-cert PATH β€” Path to a TLS client certificate to enable mTLS. It must be passed in conjunction with --tls-client-key and --tls-ca-cert. Supported by: add-to-cas|analyse|build|describe|install-cas|install|rebuild|traverse.
  • --tls-client-key PATH β€” Path to a TLS client key to enable mTLS. It must be passed in conjunction with --tls-client-cert and --tls-ca-cert. Supported by: add-to-cas|analyse|build|describe|install-cas|install|rebuild|traverse.

πŸ‘‘ analyse specific options 🌈

  • --dump-actions PATH β€” Dump actions to file. - is treated as stdout. The output is a list of action descriptions, in JSON format, for the given target.
  • --dump-anonymous PATH β€” Dump anonymous targets to file. - is treated as stdout. Output is a JSON map, for all transitive targets, with two entries: nodes and rule_maps. The former contains maps between node id and the node description. rule_maps states the maps between the mode_type and the rule to use in order to make a target out of the node.
  • --dump-blobs PATH β€” Dump blobs to file. - is treated as stdout. The term blob identifies a collection of strings that the execution back end should be aware of before traversing the action graph. A blob will be referred to as a KNOWN artifact in the action graph.
  • --dump-nodes PATH β€” Dump nodes of only the given target to file. - is treated as stdout. Output is a JSON map between node id and its description.
  • --dump-vars PATH β€” Dump configuration variables to file. - is treated as stdout. The output is a JSON list of those variable names (in lexicographic order) at which the configuration influenced the analysis of this target. Heads up: this might contain variables unset in the configuration, if the fact that they were unset (and hence treated as the default null) was relevant for the analysis of that target.
  • --dump-targets PATH β€” Dump all transitive targets to file for the given target. - is treated as stdout. Output is a JSON map of all targets encoded as tree by their entity name:
{ "#": // anonymous targets
  { "<rule_map_id>":
    { "<node_id>": ["<serialized config1>", ...] } // all configs this target is configured with
  }
, "@": // "normal" targets
  { "<repo>":
    { "<module>":
      { "<target>": ["<serialized config1>", ...] } // all configs this target is configured with
    }
  }
}
  • --dump-export-targets PATH β€” Dump all transitive targets to file for the given target that are export targets. - is treated as stdout. The output format is the same as for --dump-targets.
  • --dump-targets-graph PATH β€” Dump the graph of configured targets to a file (even if it is called - πŸ‘€ like, yes, genuinely even then). In this graph, only non-source targets are reported. The graph is represented as a JSON object. The keys are the nodes of the graph, and for each node, the value is a JSON object containing the different kind of dependencies (each represented as a list of nodes).
    • "declared" are the dependencies coming from the target fields in the definition of the target.
    • "implicit" are the dependencies implicit from the rule definition.
    • "anonymous" are the dependencies on anonymous targets implicitly referenced during the evaluation of that rule.

While the node names are strings (so that they can be keys in a JSON object), they can themselves be decoded as JSON and in this way precisely name the configured target. More precisely, the JSON decoding of a node name is a list of length two, with the first entry being the target name (as ["@", repo, module, target] or ["#", rule_map_id, node_id]) and the second entry the effective configuration.

  • --dump-trees PATH β€” Dump trees and all subtrees of the given target to file. - is treated as stdout. Output is a JSON map between tree ids and the corresponding artifact map, which maps the path to the artifact description.
  • --dump-provides PATH β€” Dump the provides map of the given target to file. - is treated as stdout. The output is a JSON object mapping the providers to their values, serialized as JSON; in particular, artifacts are replaced by a JSON object with their intensional description. Therefore, the dumped JSON is not uniquely readable, but requires an out-of-band understanding where artifacts are to be expected.
  • --dump-result PATH β€” Dump the result of the analysis for the requested target to file. - is treated as stdout. The output is a JSON object with the keys "artifacts", "provides", and "runfiles".
  • --dump-provides PATH β€” Dump the provides map of the given target to file. - is treated as stdout. The output is a JSON object mapping the providers to their values, serialized as JSON; in particular, artifacts are replaced by a JSON object with their intensional description. Therefore, the dumped JSON is not uniquely readable, but requires an out-of-band understanding where artifacts are to be expected.
Not me noticing --dump-provides showing up twice β€” it's in the original like that, so it stays in like that. πŸ€·β€β™€οΈ Both entries, every word, no editing. That's the rule.

πŸ”₯ rebuild specific options πŸŽ€

  • --vs NAME:PORT|"local" β€” Cache endpoint to compare against (use "local" for local cache).
  • --dump-flaky PATH β€” Dump flaky actions to file.

πŸ¦‹ add-to-cas specific options πŸ’–

  • --follow-symlinks β€” Resolve the positional argument to not be a symbolic link by following symbolic links. The default is to add the link itself, i.e., the string obtained by readlink(2), as blob.
  • --resolve-special TEXT β€” When adding a directory to CAS, resolve any special filesystem entries based on the strategy denoted by the string value specified. Special entries are all those which are neither file, executables, or directories. If the option is missing or a non-supported value is provided, the default behavior is used, in which only non-upwards symlinks are accepted and stored unresolved. Currently accepted values:
    • "ignore": all special entries are ignored
    • "tree-upwards": accept only symlinks with a target path pointing inside the location directory and resolve the ones that are upwards
    • "tree-all": accept only symlinks with a target path pointing inside the location directory and resolve all of them
    • "all": unconditionally accept and resolve all symlinks

🌸 traverse specific options ✨

  • -a, --artifacts TEXT β€” JSON maps between relative path where to copy the artifact and its description (as JSON object as well).
  • -g, --graph-file TEXT [[REQUIRED]] β€” Path of the file containing the description of the actions. See just-graph-file(5) for more details.
  • --git-cas TEXT β€” Path to a Git repository, containing blobs of potentially missing KNOWN artifacts.

πŸ’… describe specific options 🫢

  • --json β€” Omit pretty-printing and describe rule in JSON format.
  • --rule β€” Module and target arguments refer to a rule instead of a target.

⭐ execute specific options πŸ‘‘

  • -p, --port INT β€” Execution service will listen to this port. If unset, the service will listen to the first available one.
  • --info-file TEXT β€” Write the used port, interface, and pid to this file in JSON format. If the file exists, it will be overwritten.
  • -i, --interface TEXT β€” Interface to use. If unset, the loopback device is used.
  • --pid-file TEXT β€” Write pid to this file in plain txt. If the file exists, it will be overwritten.
  • --tls-server-cert TEXT β€” Path to the TLS server certificate.
  • --tls-server-key TEXT β€” Path to the TLS server key.
  • --log-operations-threshold INT β€” Once the number of operations stored exceeds twice 2^n, where n is given by the option --log-operations-threshold, at most 2^n operations will be removed, in a FIFO scheme. If unset, defaults to 14. Must be in the range [0,63].

🧚 gc specific options πŸ’œ

  • --no-rotate β€” Do not rotate garbage-collection generations. Instead, only carry out clean up tasks that do not affect what is stored in the cache. Incompatible with --all.
  • --all β€” Do not rotate garbage-collection generations and do not split large files. Instead, remove all cache generations at once. Incompatible with --no-rotate.

πŸ’€ EXIT STATUS πŸ’€

The exit status of justbuild is one of the following values, bestie β€” memorize these, they're lowkey the whole story of your build:

  • 0: the command completed successfully
  • 1: the command failed due to a failing build action
  • 2: the command successfully parsed all the needed files (e.g., TARGETS), successfully compiled the eventually required objects, but the generation of some artifacts failed (e.g., a test failed).
  • 8: the command failed due to an error during analysis (e.g., missing or malformed TARGETS files, assertion errors during analysis, cyclic dependencies)
  • 16: the command failed due to some problems related to the build environment (e.g., local build root inaccessible, credentials for remote endpoint not accessible)
  • 32: the tool was invoked in a syntactically malformed way (e.g., failure parsing the command line)

πŸŽ€ See also πŸŽ€

just-repository-config(5), just-serve-config(5), just-graph-file(5), just-profile(5), just-mr(1)


And that's the whole page, babes. 🫢 This was JUSTBUILD(1) β€” this section's source and version lines plus its date were sitting at the bottom of the original, so go grab them from the real page if you need them; I'm just here to make the vibe iconic. ✨ Go build something, you've got this. πŸ’–

πŸ“¦ where this page comes from