The following sections describe special targets that are available in particular sets of rules for make-based builds.
Rules for compiling C and C++ code are provided by the
ccxx rules. These rules also include
support for Flex, Bison, and Sun RPC. It is possible for a
single build item to build multiple targets including any
mixture of static library, shared library, and executable
targets.
When building C and C++ code, you must define at least one of
TARGETS_lib or
TARGETS_bin. These variables contain a list
of library and executable targets respectively. Targets should
be specified without any operating system-specific prefixes or
suffixes. For example, the library target
moo might generate
libmoo.a on a UNIX system or
moo.lib on a Windows system. Likewise, the
executable target quack might generate
quack on a UNIX system and
quack.exe on a Windows system.
For each target target listed in
TARGETS_lib, you must define the variable
SRCS_lib_
to contain a list of source files used to build the library.
Likewise, for each binary target in
targetTARGETS_bin, you must define
SRCS_bin_.
These variables can contain any mixture of C and C++ files. The
source files listed in these variables are typically located in
the same directory as the targetAbuild.mk, but
they may also refer to automatically source files that will
actually appear in the output directory.
[26]
There are variables that can be used to control the creation of
shared libraries. For details, see Section 17.1, “Building Shared Libraries”. Files whose names
end with .c are treated as C code. Files
whose names end with either .cc or
.cpp are considered to be C++ code.
Although you can have any mixture of binary and library targets
in a build item, no single source file should be listed in more
than one target. Additionally, Abuild will automatically
include any library targets at the beginning of the library list
when linking any binary targets in the build item. All targets
are created directly in the abuild output directory.
In addition to the standard targets, the
ccxx rules provide a special target
ccxx_debug. This target prints the current
include and library path as well as the list of libraries that
we are linking against. This can be a useful debugging tool for
solving dependency declaration problems.
It is also possible to add additional preprocessor, compiler, or
linker flags globally or on a per-file basis and to specifically
override debug, optimization, or warning flags globally or on a
per-file basis. This is done by setting the values of certain
make variables, some of which may also be set in
Abuild.interface. Details about these
variables may be obtained by running abuild
rules-help from any C/C++ build item. The following
variables are available:
additional flags passed to the preprocessor, C compiler, and C++ compiler (but not the linker)
additional flags passed to the C compiler, C++ compiler, and linker
additional flags passed to the C++ compiler and linker
additional flags passed to the linker—usually not used for libraries
debug flags passed to the processor, compilers, and linker
optimization flags passed to the processor, compilers, and linker
warning flags passed to the processor, compilers, and linker
Note that the XCPPFLAGS,
XCFLAGS, XCXXFLAGS, and
XLINKFLAGS variables may be set in
Abuild.interface as well. Therefore,
although you assign to them normally with =
in Abuild.interface, when assigning to them
in Abuild.mk, it is generally better to
append to these variables (using +=) rather
than to set them outright. Also, keep in mind that flags are
often compiler-specific. It may often make sense to set certain
flags conditionally upon the value of the
$(ABUILD_PLATFORM_COMPILER) variable or other
platform field variables. This can be done using regular
GNU Make conditional syntax.
Each of the above variables also has a file-specific version.
For the X*FLAGS variables, the file-specific
values are added to the general values. For example, setting
XCPPFLAGS_File.cc will cause the value of
that variable to be added to the preprocessor, C compiler and
C++ compiler invocations for File.cc.
File-specific versions of XCPPFLAGS,
XCFLAGS, and XCXXFLAGS are
used only for compilation and, if appropriate, preprocessing of
those specific files. They are not used at link time.
The file-specific versions of DFLAGS,
OFLAGS, and WFLAGS
override the default values rather than
supplementing them. This makes it possible to completely change
debugging flags, optimization flags, or warning flags for
specific source files. For example, if
Hardware.cc absolutely cannot be compiled
with any optimization, you could set
OFLAGS_Hardware.cc to the empty string to
suppress optimization on that file regardless of the value of
OFLAGS. Similarly, if autogen.c were an
automatically generated file with lots of warnings, you could
explicitly set WFLAGS_autogen.c to the empty
string or to a flag that suppresses warnings. This would
suppress warnings for that file without affecting other files.
If you wish to append to the default flags instead of replacing
them, include the regular variable name in the value, as in
WFLAGS_File.cc := $(WFLAGS) -Wextra or even
WFLAGS_File.cc := $(filter-out
-Wall,$(WFLAGS)).
The ccxx rules provide a mechanism for you
to generate preprocessed output for any C or C++ file. For
,
file.c, or
file.cc, run
abuild file.cppfile.i.
This will generate
in the
output directory. Its contents will be the output of running
the preprocessor over the specified source file with all the
same flags that would be used during actual compilation.
[27]
file.i
As is the case for any rule set, you can run abuild rules-help and abuild interface-help for complete information.
When invoking abuild to build C or C++ executables or shared
libraries, it is possible to set the make variable
LINKWRAPPER to the name of a program that
should wrap the link command. This makes it possible to use
programs such as Purify or
Quantify that wrap the link step in
this fashion.
Ordinarily, abuild uses a C++ compiler or linker to link all
executables and shared libraries. If you are writing straight C
code that doesn't make any call to C libraries and you want to
link your program as a C program to avoid runtime dependencies
on the C++ standard libraries, set the variable
LINK_AS_C to some non-empty value in your
Abuild.mk. This applies to all shared
libraries and executables in the build item.
Most of the time, abuild manages all the dependencies of the
source and object files (as opposed to inter-build-item
dependencies) automatically, but there are some rare instances
in which you may have to create such dependencies on your own,
such as when an object file depends on an automatically generate
header file that is generated in the same build item. For an
example of this, see Section 18.3, “Dependency on a Make Variable”. To make it possible
to express such dependencies in a portable fashion, the
ccxx rules provide the variables
LOBJ and OBJ which are set
to the object file suffixes for library object files and
non-library object files respectively. For example, if you have
a source file called File.cc that is part
of a library, the name of the object file will be
File., and the
file will be created inside the abuild output directory. If
$(LOBJ)File.cc were part of an executable instead,
the object file would be
File. instead.
[28]
$(OBJ)
There is a lot more to abuild's C and C++ generation than is
discussed here. For a complete understanding of how it works,
you are encouraged to read make/ccxx.mk in
the abuild distribution (Appendix D, The ccxx.mk File).
There you will find copious comments and a lot of pretty hairy
GNU Make code.
The autoconf rules provide rules for
including autoconf fragments for a build item.
[29]
Rather than having a monolithic autoconf-based component in a
source tree, it is recommended that individual build items use
autoconf for only those things they need. This reduces the
likelihood that something may fail to build due to lack of
support for something it doesn't need (but that is checked for
by a monolithic autoconf component). The
autoconf rules don't supply any special
targets. A reasonably complete example of using autoconf
follows in Section 15.3, “Autoconf Example”. You may also
run abuild rules-help and abuild
interface-help from a build item that uses
autoconf rules for full information on
using these rules. (Creating an Abuild.mk
with the one line RULES := autoconf and
running abuild rules-help would suffice.)
Autoconf properly honors your C/C++ toolchain and runs
configure with the proper C/C++ compilation
environment defined. The usual approach for autoconf-based
build items is that, if make variables need to be defined based
on the results of running configure,
configure.ac generates a file called
autoconf.interface which is specified as an
after-build file in
Abuild.interface. This means that the
autoconf-based build item itself may not include code that is
conditional upon the results of running autoconf. It is okay,
however, for build items that depend on an autoconf-based build
item to include conditional code in their
Abuild.interface and
Abuild.mk files based on variables defined
in its autoconf.interface should this be
required.
In some rare cases, it may be desirable to create an
Abuild.mk file that does nothing. One
reason for doing this would be if you had a library that
contained some code that should only exist on certain platforms.
You might want to create an Abuild.mk file
that was conditional upon some value of the
ABUILD_PLATFORM_OS variable, for example.
Since abuild requires that you set at least one of
RULES, BUILD_ITEM_RULES,
or LOCAL_RULES, you can set the
RULES variable to the value
empty. Abuild will still attempt to
build the item in this case, but the build will not do
anything. The empty rule set is available
to both object-code and
platform-independent build items.
[26]
For example, if you have a local rule that generates
autogen.cc in the output directory, you
can simply list autogen.cc in one of your
SRCS variables, and abuild will find it
anyway. This is because abuild's make code uses
GNU Make's
vpath feature. We provide an example of
this construct in Section 18.2, “Code Generator Example”.
[27]
The .i suffix is a traditional UNIX
suffix for preprocessed C code and was created as an
intermediate file by some compilers. GCC recognizes this as
preprocessed C code and also recognizes
.ii as a suffix for preprocessed C++
code. When abuild is given a .i file
as a suffix, its make rules use a pattern-based rule to run
the preprocessor over the file, it never uses the resulting
files as input to the compiler. Abuild uses the original
suffix of the file (.c,
.cc, or .cpp) to
determine whether the file is a C or C++ source file and does
not therefore need to distinguish between
.i and .ii.
[28]
LOBJ and OBJ usually
have the same value as each other, and the value is usually
“o” on UNIX systems and
“obj” on Windows systems.
However, there are some circumstances under which either of
these conditions may not be true, so it is best to use
LOBJ or OBJ explicitly
as required.