When abuild starts up, it reads its internal information about supported platforms and platform types. It then reads additional information from plugins, which it combines with its built-in information. This section contains information about the specific formats of the directives used to add platform types and platforms to abuild.
Platform type information is read from a plain text file that contains platform type declarations. Information about platforms is obtained by running a program, usually written in Perl. The reason for putting platform type information in a file and platform information in a program is that the list of platform types should be static for a given build tree, while the list of available platforms is a function of what the build host can provide. Abuild automatically skips build items that belong to a valid platform type that happens to have no platforms in it, but if it encounters a build item with invalid platform types, it considers that an error.
Of the target types that abuild supports, the only one for
which additional platform types and platforms may be specified
is the object-code
target type. Platform
types are declared in a file called
platform-types
. Abuild looks for this
file first in its own private
directory and
then at the root of each declared plugin. The
platform-types
file contains a single
platform type declaration on each line. Comment lines starting
with the #
character and blank lines are
ignored. Each line may have the following syntax:
platform-typenew-platform-type
[-parentparent-platform-type
]
Platform type names may contain only alphanumeric characters, underscores, and dashes.
You may optionally specify another previously-declared
object-code platform type as the new platform type's parent. If
a platform type is declared without a parent platform type, it
has indep as its implicit parent. (Note that
indep may not be declared explicitly as a parent;
only other object-code
platform types may be
declared are parents.) Declaring a parent platform type means
that any platform in the new platform type may link against any
platform in the parent platform type. It is up to the creator
of the platform types to ensure that this is actually the case.
One example use of parent platform types would be to implement a
base platform type for a particular environment and then to
create derived platform types that refine some aspect of the
base platform type. For example, this could be used to overlay
additional include directories or libraries on top of support
for an embedded operating system to support selective hardware.
It would also be possible to create platform types that refine
the native platform type for specific
circumstances. Most uses of parent platform types could be
achieved in some other way, such as through use of conditionals
in Abuild.interface
or
Abuild.mk
files or through use of
pass-through build items with multiple dependencies, but when
used properly, parent platform types can reduce the number of
times common code has to be recompiled for different platform
types.
The ability to specify parent platform types was introduced in abuild 1.1.4 and is closely related to platform type compatibility as discussed in Section 24.2, “Dependencies and Platform Compatibility”. It's possible that a future version of abuild may further generalize the ability to create compatibility relationships among platform types.
Since platforms are, by their nature, dynamic, abuild runs a program that outputs platform declarations rather than reading them from a file. This makes it possible for the existence of a platform to be conditional upon the existence of a specific tool, the value of an environment variable, or other factors. To get the list of platforms, abuild runs a program called list_platforms. Abuild invokes list_platforms with the following arguments:
list_platforms [ --windows ] --native-dataos
cpu
toolset
The --windows
option is only present when
abuild is running on a Windows system. The three options to
--native-data
provide information about the
default native platform. Most compiler plugins will not need to
use this information since there is special way to add a native
platform, as discussed below.
To discover new platforms, abuild first runs the
list_platforms program in its own
private
directory, and then it runs any
list_platforms programs it finds at the root
directories of any plugins. On a Windows system, abuild
explicitly invokes the list_platforms program
as perl list_platforms
options
. For this reason,
to support portability to a Windows system,
list_platforms programs must be written in
perl. If necessary, a future version of abuild may provide a
mechanism to make writing list_platforms
programs in other languages. Note that abuild passes the
--windows flag to
list_platforms when running on Windows. This
not only saves the list_platforms program
from detecting Windows on its own but is actually necessary
since list_platforms couldn't tell on its own
whether it is being run to support a native Windows build of
abuild or whether it is being run to support a Cygwin build of
abuild.
[56]
Each line of output of list_platforms
declares either a new platform or a new native compiler, which
implies a new platform. A given platform may be declared
exactly one time across abuild's internally defined platforms
and plugins. When a platform type contains multiple platforms,
unless overridden, abuild always chooses to build on the last
platform declared that belongs to a given platform type. Since
plugins are evaluated in the order in which they are declared,
that means that platforms declared in later plugins can override
earlier ones as well as abuild's internal platform list with
respect to determining which platforms will be built by default.
[57]
When specifying a new platform or local compiler, the
list_platforms program may include the option
-lowpri
to indicate that this is a low priority
platform or native compiler. This will cause the new platform
to be added with lower priority than previously declared
compilers including the built-in ones. Such compilers will only
be chosen if explicitly selected. The user can further refine
the choice of which platforms are built, including selecting low
priority compilers and platforms, by using platform selectors
(see Section 24.1, “Platform Selection”).
Each line of output of list_platforms must take one of the following forms:
platform [-lowpri]new-platform
-typeplatform-type
native-compiler [-lowpri]compiler[.option]
By convention, each native compiler should support a platform with no options, a platform with the debug option, and a platform with the release option. The default should be to select the platform with no options, which means the list_platforms program should output platforms with no options last. The platform with no options should provide both debugging and optimization flags. The debug platform should omit all optimization flags, and the release platform should omit all debugging flags. For normal, everyday development, it generally makes sense to have both debugging and optimization turned on. The reason to have debugging turned on is that it makes it possible to do light debugging in a debugger even with optimized code. The reason to have optimization turned on is so that any problems introduced by the optimizer and additional static analysis that the compiler may do when optimizing will be enabled during normal development. Since optimized code is harder to debug in a symbolic debugger, the debug version of a platform omits all optimization. Since it is often desirable to ship code without debugging information in it, the release version of a platform omits all debug information.
These options only define the default behavior. It is still
possible to override debugging and optimization information on a
per-file basis or globally for a build item in
Abuild.mk
(see Section 18.2.1, “C and C++: ccxx
Rules”).
Note that on some platforms (such as Windows with Visual C++),
mixing debugging and non-debugging code may not be reliable. On
most UNIX platforms, it works fine to mix debugging and
non-debugging code.
When declaring a platform, all platform types that contain the platform must have already been declared.
Note that object code platform names take the form os.cpu.toolset.compiler[.option]. When declaring a platform with the native-compiler directive, abuild automatically constructs a platform name by using the native values for os, cpu, and toolset. This saves every list_platforms program from having to determine this information.
[56]
Note that Cygwin is not Windows. Cygwin is really more like a
UNIX environment. Although abuild uses Cygwin to provide
make and other UNIX-like tools, the
Windows abuild executable is a native Windows application.
If you were to compile a Cygwin version of abuild, it would
not consider itself to be running in Windows and would not
invoke list_platforms with the
--windows
option. That said, there are a few
pieces of code in the periphery of abuild that assume that,
if we're in a Cygwin environment, it is to support Windows.
These are all commented as such. Those parts of the code
would need to change if someone were to attempt to package
abuild for Cygwin.
[57]
Note, however, that the --list-platforms
option shows highest priority platforms first, which
effectively means that it shows the user platforms in the
opposite of their declaration order.