diff options
author | Klaus Aehlig <klaus.aehlig@huawei.com> | 2022-05-23 11:03:53 +0200 |
---|---|---|
committer | Klaus Aehlig <klaus.aehlig@huawei.com> | 2022-05-24 14:30:07 +0200 |
commit | f99bd5ed4e532fa76529246d441233d7f44c74a4 (patch) | |
tree | 4cb2ed736ce3aefc6b9830c5268f3db9c6a0565c /doc | |
parent | 0612c368acc043290cbde5b8c622d418af8b54bc (diff) | |
download | justbuild-f99bd5ed4e532fa76529246d441233d7f44c74a4.tar.gz |
concepts: describe configuration
Diffstat (limited to 'doc')
-rw-r--r-- | doc/concepts/configuration.org | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/doc/concepts/configuration.org b/doc/concepts/configuration.org new file mode 100644 index 00000000..4217d22d --- /dev/null +++ b/doc/concepts/configuration.org @@ -0,0 +1,107 @@ +* Configuration + +Targets describe abstract concepts like "library". Depending on +requirements, a library might manifest itself in different ways. +For example, +- it can be built for various target architectures, +- it can have the requirement to produce position-independent code, +- it can be a special build for debugging, profiling, etc. + +So, a target (like a library described by header files, source files, +dependencies, etc) has some additional input. As those inputs are +typically of a global nature (e.g., a profiling build usually wants +all involved libraries to be built for profiling), this additional +input, called "configuration" follows the same approach as the +~UNIX~ environment: it is a global collection of key-value pairs +and every target picks, what it needs. + +** Top-level configuration + +The configuration is a ~JSON~ object. The configuration for the +target requested can be specified on the command line using the +~-c~ option; its argument is a file name and that file is supposed +to contain the ~JSON~ object. + +** Propagation + +Rules and target definitions have to declare which parts of the +configuration they want to have access to. The (essentially) full +configuration, however, is passed on to the dependencies; in this way, +a target not using a part of the configuration can still depend on +it, if one of its dependencies does. + +*** Rules configuration and configuration transitions + +As part of the definition of a rule, it specifies a set ~"config_vars"~ +of variables. During the evaluation of the rule, the configuration +restricted to those variables (variables unset in the original +configuration are set to ~null~) is used as environment. + +Additionally, the rule can request that certain targets be evaluated +in a modified configuration by specifying ~"config_transitions"~ +accordingly. Typically, this is done when a tool is required during +the build; then this tool has to be built for the architecture on +which the build is carried out and not the target architecture. Those +tools often are ~"implicit"~ dependencies, i.e., dependencies that +every target defined by that rule has, without the need to specify +it in the target definition. + +*** Target configuration + +Additionally (and independently of the configuration-dependency +of the rule), the target definition itself can depend on the +configuration. This can happen, if a debug version of a library +has additional dependencies (e.g., for structured debug logs). + +If such a configuration-dependency is needed, the reserved key +word ~"arguments_config"~ is used to specify a set of variables (if +unset, the empty set is assumed; this should be the usual case). +The environment in which all arguments of the target definition are +evaluated is the configuration restricted to those variables (again, +with values unset in the original configuration set to ~null~). + +For example, a library where the debug version has an additional +dependency could look as follows. +#+BEGIN_SRC +{ "libfoo": + { "type": ["@", "rules", "CC", "library"] + , "arguments_config": ["DEBUG"] + , "name": ["foo"] + , "hdrs": ["foo.hpp"] + , "srcs": ["foo.cpp"] + , "local defines": + { "type": "if" + , "cond": {"type": "var", "name": "DEBUG"} + , "then": ["DEBUG"] + } + , "deps": + { "type": "++" + , "$1": + [ ["libbar", "libbaz"] + , { "type": "if" + , "cond": {"type": "var", "name": "DEBUG"} + , "then": ["libdebuglog"] + } + ] + } + } +} +#+END_SRC + +** Effective configuration + +A target is influenced by the configuration through +- the configuration dependency of target definition, as specified + in ~"arguments_config"~, +- the configuration dependency of the underlying rule, as specified + in the rule's ~"config_vars"~ field, and +- the configuration dependency of target dependencies, not taking + into account values explicitly set by a configuration transition. +Restricting the configuration to this collection of variables yields +the effective configuration for that target-configuration pair. +The ~--dump-targets~ option of the ~analyse~ subcommand allows to +inspect the effective configurations of all involved targets. Due to +configuration transitions, a target can be analyzed in more than one +configuration, e.g., if a library is used both, for a tool needed +during the build, as well as for the final binary cross-compiled +for a different target architecture. |