Table of Contents
In large development environments, it is common to have collections of code that may be shared across multiple projects. Ideally, such collections of shared code should be accessible by multiple projects but should not be able to access code from the those projects. By creating this one-way relationship between project code and common code, it is possible to ensure that the common code is not modified to accidentally depend on project code. Abuild provides the ability to do this through the use of external build trees, also referred to as externals. We define the following additional terms:
The local build tree is the build tree that contains the current directory.
An external build tree is a separate build tree that can supplement the local build tree. Build items in the local build tree can resolve the names of build items in external build trees, but build items in external build trees cannot see items in the local tree.
There is nothing special about a build tree that makes it able to
be an external: any tree can be an external. In order for one
build tree to reference another build tree as an external, the
first tree must configure its root build item's
Abuild.conf to point to the external tree's
root directory. This is done by adding an
external-dirs key to the root build item's
Abuild.conf. The
external-dirs key, like the
child-dirs key, contains a space-separated
list of paths. Unlike with child-dirs, in
this case, there is no reciprocation; i.e.,
nothing in the external tree points back to the referring tree.
External trees can be specified as either relative paths or as
absolute paths. If an external tree is specified as a relative
path, then abuild will attempt to resolve it in a backing area
(see Section 10.3, “Resolving Externals to Backing Areas”) if
it is not found.
In addition to paths, there are two options that may be specified
for each external: the -ro option, which makes
an external read-only, and the
-winpath=
option, which allows an alternative path to be used only when
running in a Windows environment.
[15]
For example, this line makes windows-path../common a
regular external and /opt/abuild_library a
read-only external that can be found at
O:/abuild_library on Windows systems and
/opt/abuild_library on non-Windows systems:
external-dirs: ../common /opt/abuild_library -winpath=O:/abuild_library -ro
Abuild will never attempt to build an item in a read-only external tree when the build is started in a tree that declares it as a read-only external. You must therefore make sure that all your read-only externals are fully built for all platforms on which you will use their items. Read-only externals can be useful for making libraries of utility build items available to a large number of projects, or they can just be used to speed up your builds if your external area is relatively static and you don't mind manually rebuilding it when you make changes to it. If more than one developer is making use of the same physical external tree, it is recommended that they all declare that tree as a read-only external since this will prevent multiple users from trying to build the same items at the same time.
Once you set up another tree as an external to your tree, all
build items defined in the external build tree are available to
you (subject to normal scoping rules) as if they were in your
local build tree. This means that none of the build items in
your build tree may have the same name as any build item in the
external tree. Note that the external build tree is not affected
in any way by being referred to as an external. In order to
avoid build item name clashes, it's a good idea to pick a naming
convention for your build items that includes some kind of
tree-based prefix, as we have done with names like
common-lib1.
When declaring an external, you must give some thought as to whether you wish to use a relative path or an absolute path. In general, if your intention is to use an external tree to contain code that is parallel to your development environment, such as having a collection of shared code used by many related projects that live together in a version control system, you will probably want to use relative paths to external trees. On the other hand, if your externals contain libraries of build items that are required to be installed in a certain location on your development systems, an absolute path may be more appropriate. Just keep in mind that using absolute paths for your externals creates a dependency from inside your build tree to files located in a specific place outside of your build tree. This may be appropriate in some cases, but it may not always be what you want. [16]
[15]
Our syntax does not allow spaces to appear in any external path
names, including the argument to -winpath. In
Windows, you can always use the short form of the name, which
you can find using the dir /x command from
the Windows command prompt.
[16]
For example, if your backing area declares an external using an
absolute path and your root Abuild.conf is
a copy of your backing area's root
Abuild.conf, you can't shadow the external
locally without modifying your root
Abuild.conf. (Backing areas are discussed
in Chapter 10, Backing Areas.) If your external were
specified as a relative path, you would be able to shadow it by
simply creating it in the correct location, thus preventing it
from being resolved in the backing area.