Now that the topic of build items and build trees has been
explored in somewhat more depth, let's take a look at a simple but
complete build tree. The build tree in
doc/example/general/reference/common illustrates many of
the concepts described above.
The first file to look at is the Abuild.conf
belonging to this tree's root build item:
general/reference/common/Abuild.conf
child-dirs: lib1 lib2 lib3 supported-traits: tester
This is a root build item configuration file. Notice that it
lacks a this key, as is often the case with
the root build item. This Abuild.conf
contains the names of some child directories and also a build tree
attribute: supported-traits, which lists the
traits that are allowed in the build tree. We will return to the
topic of traits in Section 8.3, “Traits”. In the mean
time, we will direct our focus to the child build items.
The first child of the root build item of this tree is in the
lib1 directory. We examine its
Abuild.conf:
general/reference/common/lib1/Abuild.conf
this: common-lib1 parent-dir: .. child-dirs: src test deps: common-lib1.src
This build item is called common-lib1.
Notice that the name of the build item is not the same as the name
of the directory, but it is based on the name of the directory.
This is a typical strategy for naming build items. Abuild
doesn't care how you name build items as long as they conform to
the syntactic restrictions and are unique within a build tree.
Coming up with a naming structure that parallels your system's
architecture and/or your file system layout is a good way to help
ensure that you do not create conflicting build item names.
This build item does not have any build or interface files. It is
a pass-through build item. It declares a
single dependency: common-lib1.src, and two
child directories: src and
test.
Next, look at the common-lib1.src build
item's Abuild.conf in the
common/lib1/src directory:
general/reference/common/lib1/src/Abuild.conf
this: common-lib1.src platform-types: native parent-dir: ..
The first thing to notice is this build item's name. It contains
a period and is therefore private to the
common-lib1 scope. That means that it is
not accessible to build items whose names are not also under that
scope. In particular, a build item called
common-lib2 would not be able to depend
directly on common-lib1.src. It would
instead depend on common-lib1 and would
inherit the dependency on common-lib1.src
indirectly.
This build item doesn't list any child directories and, as such,
is a leaf in the file system hierarchy. It also happens not to
declare any dependencies, so it is also a leaf in the dependency
tree, though one does not imply the other. This build item
configuration file contains the
platform-types key, as is required for all
build items that contain build or interface files. In addition
to the Abuild.conf file, we have an
Abuild.mk file and an
Abuild.interface file:
general/reference/common/lib1/src/Abuild.mk
TARGETS_lib := common-lib1 SRCS_lib_common-lib1 := CommonLib1.cpp RULES := ccxx
general/reference/common/lib1/src/Abuild.interface
INCLUDES = ../include LIBDIRS = $(ABUILD_OUTPUT_DIR) LIBS = common-lib1
There is nothing in these files that is fundamentally different
from the basic C++ library example shown in Section 3.4, “Building a C++ Library”. We can observe,
however, that the INCLUDES variable in
Abuild.interface actually points to
../include rather than the current
directory. This simply illustrates that abuild doesn't impose
any restrictions on how you might want to lay out your build
items, though it is recommended that you pick a consistent way
and stick with it for any given build tree. We will not study
the source and header files in this example here, but you are
encouraged to go to the
doc/example/general/reference/common directory in your
abuild source tree or installation directory to study the files
further on your own.
Next, look at the test directory. Here is
its Abuild.conf:
general/reference/common/lib1/test/Abuild.conf
this: common-lib1.test platform-types: native parent-dir: .. deps: common-lib1 traits: tester -item=common-lib1.src
Notice that it declares a dependency on
common-lib1. Since its name is also
private to the common-lib1 scope, it would
have been okay for it to declare a dependency directly on
common-lib1.src. Declaring its dependency
on common-lib1 instead means that this
test code is guaranteed to see the same interfaces as would be
seen by any outside user of common-lib1.
This may be appropriate in some cases and not in others, but it
demonstrates that it is okay for a build item that is inside of a
particular namespace scope to depend on its parent in the
namespace hierarchy. This build item also declares a trait, but
we will revisit this when we discuss traits later in the document
(see Section 8.3, “Traits”).
In addition to the lib1 directory, we also
have lib2 and lib3.
These are set up analogously to lib1, so we
will not inspect every file. We will draw your attention to one
file in particular: observe that the
common-lib2.src build item in
reference/common/lib2/src declares a dependency
on common-lib3:
general/reference/common/lib2/src/Abuild.conf
this: common-lib2.src platform-types: native parent-dir: .. deps: common-lib3
We will return to this build tree later to study build sets, traits, and examples of various ways to run builds.