In abuild, it is possible to assign certain traits to a build item. Traits are a very powerful feature of abuild. This material is somewhat more complicated than anything introduced up to this point, so don't worry if you have to read this section more than once.
Traits are used for two main purposes. Throughout this material, we will refer back to the two purposes. We will also provide clarifying examples later in the chapter.
The first purpose of traits is creation of semantically defined groups of build items. In this case, a trait corresponding to the grouping criteria would be applied to a build item directly. For example, all build items that can be deployed could be assigned the deployable trait.
A second purpose of traits is to create specific relationships among build items. These relationships may or may not correspond to dependencies among build items. These traits may be applied to a build item by itself or in reference to other build items. For example, the tester trait may be applied to a general system test build item by itself and may be applied to every test suite build item with a reference to the specific item being tested.
Traits are used to assist in the construction of build sets. In particular, you can narrow a build set by removing all items that don't have all of a specified list of traits. You can also expand a build set to add any build items that relate to any items already in the set by referring to them through all of a specified list of traits. This makes it possible to say things like “run the deploy target for every build item that has the deployable trait,” or “run the test target for every item that tests my local build item or anything it depends on.”
Since traits are visible in abuild's --dump-data
output (see Appendix F, --dump-data
Format), they are available
to scripts or front ends to abuild. They may also be used for
purely informational purposes such as specifying the
classification level of a build item or applying a uniform label
to all build items that belong to some group. Trait names are
subject to the same constraints as build item names: they are
case-sensitive and may consist of mixed case alphanumeric
characters, numbers, underscores, dashes, and periods. Unlike
with build items, the period does not have any semantic meaning
when used in a trait name.
Starting with abuild 1.1.6, a build item that uses either the
GNU Make backend or the Groovy backend (but not the deprecated
xml-based ant backend) may also get access to the list of traits
that are declared in its Abuild.conf
file.
For the GNU Make backend, the variable
ABUILD_TRAITS
contains a list of traits
separated by spaces. For the Groovy backend, the variable
abuild.traits
contains a groovy list of traits
represented as strings. In both cases, any information about
referent build items is excluded; only the list of declared
traits is provided. Possible uses for this information would
include having a custom rule check to make sure a given trait is
specified before providing a particular target, having it give an
error if a particular trait is not defined, or even having it
change behavior on the basis of a trait.
Any named build item may include a traits
key that lists one or more of the traits that are supported in
its build tree. The list of traits supported in a build tree is
given as the value of the supported-traits
key in the root build item's Abuild.conf
.
The list of supported traits is inherited through tree
dependencies, so any trait declared as valid in any trees your
tree depends on are also available. The set of traits that can
be specified on the command line is the union of all traits
allowed by all known trees.
Traits listed in the traits key can be made
referent to other build items by listing the other build items
in an -item
option. For example, the following
Abuild.conf
fragment declares that the
potato.test
build item is deployable,
unclassified, and a tester for the
potato.lib
and
potato.bin
build items:
this: potato.test traits: deployable tester -item=potato.lib -item=potato.bin unclassified
To modify the build set or clean set based on traits, use the
--only-with-traits
and
--related-by-traits
command-line options to
abuild. These options must be combined with the specification
of a build set. They correspond to the two purposes of traits
discussed above.
To build all build items that have all of a specified list of
traits, run abuild
--build=set
--only-with-traits
trait
[,trait
,...].
This is particularly useful when semantically grouped build
items share a common custom target. For example, if all the
deployable build items had a special deploy
target, you could run the deploy target for
all deployable items in the local build tree with the command
abuild --build=local --only-with-traits deployable deploy
If multiple traits are specified at once, only build items with all of the specified traits are included.
Once a build set has been constructed, you may want to add
additional items to the set based on traits. Specifically, you
may want to add all items related by a trait to items already in
the build set. To expand a build set in this way, run
abuild --build=set
--related-by-traits
trait
[,trait
,...]
For example, if you wanted to run the test
target for all build items that are declared as testers (using
the tester trait) of your build item or any
of its dependencies, you could run the command
abuild --build=current --related-by-traits=tester test
As above, if multiple traits are specified at once, only build
items that are related by all of the specified traits are
included. Note that the same trait may be used referent to
another build item or in isolation. The
--related-by-traits
option only applies to
traits used in reference to other build items. For example, if
a build item had the tester trait not
referent to any build item, it would not be picked up by the
above command. The --only-with-traits
option
picks up all build items that have the named traits either in
isolation or referent to other build items.
It is also possible to combine these options. In that case, the
build set is first restricted using
--only-with-traits
and then expanded using the
--related-by-traits
as shown in examples below.
The order of the arguments has no effect on this behavior.
Ordinarily, when a specific target is specified as an argument to abuild (as in abuild test or abuild deploy rather than just abuild), abuild runs that target for every item initially in the build set (before dependency expansion). When the build set is expanded or restricted based on traits, any explicitly specified targets are run only for build items that have the specified traits. This is important because it enables you to use traits to group build items that define specific custom targets.
If --related-by-traits
and
--only-with-traits
are both specified, any
explicit targets are applied only to traits named in
--related-by-traits
as the effect of that
option is applied last. All other build items are built with
the all target. Note that the
--apply-targets-to-deps
option will cause any
explicit targets to be applied to all build items, as always.
Later in this chapter, we review the exact rules that abuild
uses to decide which targets to apply to which build items.
The --list-traits
flag provides information
about which traits can be used on the command line. To see more
detailed information about which traits were made available in
which build trees, you can examine the output of abuild
--dump-data (see Appendix F, --dump-data
Format).
For more detailed information about how build sets are constructed with respect to traits, please see Section 33.5, “Construction of the Build Set”.
Run the deploy target for all items at or below the current directory that have the deployable trait, and run the all target for all items that they depend on.
Build the current build item and all of its dependencies with the all target, and run the test target for any build items that declared themselves as a tester for any of those items. Any additional dependencies of the testers would also be built with the all target.
Run both the deploy and the test targets for any build items in the local build tree (the current build item's tree excluding its tree dependencies) that have both the deployable and the tester traits either specified alone or in reference to other build items. Run the all target for their dependencies.
Run the all target for all items that have the requires-hw trait as well as any of their dependencies, and run the hwtest target for all items that test any of them. Additional dependencies of the testers would also be built with the all target.