Defining Binaries for the Build System¶
One part of what the build system does is compile C/C++ and link the resulting objects to produce executables and/or libraries. This document describes the basics of defining what is going to be built and how. All the following describes constructs to use in moz.build files.
Source files¶
Source files to be used in a given directory are registered in the SOURCES
and UNIFIED_SOURCES
variables. UNIFIED_SOURCES
have a special behavior
in that they are aggregated by batches of 16, requiring, for example, that there
are no conflicting variables in those source files.
SOURCES
and UNIFIED_SOURCES
are lists which must be appended to, and
each append requires the given list to be alphanumerically ordered.
UNIFIED_SOURCES += [
'FirstSource.cpp',
'SecondSource.cpp',
'ThirdSource.cpp',
]
SOURCES += [
'OtherSource.cpp',
]
SOURCES
and UNIFIED_SOURCES
can contain a mix of different file types,
for C, C++, and Objective C.
Static Libraries¶
To build a static library, other than defining the source files (see above), one
just needs to define a library name with the Library
template.
Library('foo')
The library file name will be libfoo.a
on UNIX systems and foo.lib
on
Windows.
If the static library needs to aggregate other static libraries, a list of
Library
names can be added to the USE_LIBS
variable. Like SOURCES
, it
requires the appended list to be alphanumerically ordered.
USE_LIBS += ['bar', 'baz']
If there are multiple directories containing the same Library
name, it is
possible to disambiguate by prefixing with the path to the wanted one (relative
or absolute):
USE_LIBS += [
'/path/from/topsrcdir/to/bar',
'../relative/baz',
]
Note that the leaf name in those paths is the Library
name, not an actual
file name.
Note that currently, the build system may not create an actual library for static libraries. It is an implementation detail that shouldn’t need to be worried about.
As a special rule, USE_LIBS
is allowed to contain references to shared
libraries. In such cases, programs and shared libraries linking this static
library will inherit those shared library dependencies.
Intermediate (Static) Libraries¶
In many cases in the tree, static libraries are built with the only purpose
of being linked into another, bigger one (like libxul). Instead of adding all
required libraries to USE_LIBS
for the bigger one, it is possible to tell
the build system that the library built in the current directory is meant to
be linked to that bigger library, with the FINAL_LIBRARY
variable.
FINAL_LIBRARY = 'xul'
The FINAL_LIBRARY
value must match a unique Library
name somewhere
in the tree.
As a special rule, those intermediate libraries don’t need a Library
name
for themselves.
Executables¶
Executables, a.k.a. programs, are, in the simplest form, defined with the
Program
template.
Program('foobar')
On UNIX systems, the executable file name will be foobar
, while on Windows,
it will be foobar.exe
.
Like static and shared libraries, the build system can be instructed to link
libraries to the executable with USE_LIBS
, listing various Library
names.
In some cases, we want to create an executable per source file in the current
directory, in which case we can use the SimplePrograms
template
SimplePrograms([
'FirstProgram',
'SecondProgram',
])
Contrary to Program
, which requires corresponding SOURCES
, when using
SimplePrograms
, the corresponding SOURCES
are implied. If the
corresponding sources
have an extension different from .cpp
, it is
possible to specify the proper extension:
SimplePrograms([
'ThirdProgram',
'FourthProgram',
], ext='.c')
Please note this construct was added for compatibility with what already lives
in the mozilla tree ; it is recommended not to add new simple programs with
sources with a different extension than .cpp
.
Similar to SimplePrograms
, is the CppUnitTests
template, which defines,
with the same rules, C++ unit tests programs. Like SimplePrograms
, it takes
an ext
argument to specify the extension for the corresponding SOURCES
,
if it’s different from .cpp
.
Linking with system libraries¶
Programs and libraries usually need to link with system libraries, such as a
widget toolkit, etc. Those required dependencies can be given with the
OS_LIBS
variable.
OS_LIBS += [
'foo',
'bar',
]
This expands to foo.lib bar.lib
when building with MSVC, and
-lfoo -lbar
otherwise.
For convenience with pkg-config
, OS_LIBS
can also take linker flags
such as -L/some/path
and -llib
, such that it is possible to directly
assign LIBS
variables from CONFIG
, such as:
OS_LIBS += CONFIG['MOZ_PANGO_LIBS']
(assuming CONFIG['MOZ_PANGO_LIBS']
is a list, not a string)
Like USE_LIBS
, this variable applies to static and shared libraries, as
well as programs.
Libraries from third party build system¶
Some libraries in the tree are not built by the moz.build-governed build
system, and there is no Library
corresponding to them.
However, USE_LIBS
allows to reference such libraries by giving a full
path (like when disambiguating identical Library
names). The same naming
rules apply as other uses of USE_LIBS
, so only the library name without
prefix and suffix shall be given.
USE_LIBS += [
'/path/from/topsrcdir/to/third-party/bar',
'../relative/third-party/baz',
]
Note that /path/from/topsrcdir/to/third-party
and
../relative/third-party/baz
must lead under a subconfigured directory (a
directory with an AC_OUTPUT_SUBDIRS in configure.in), or security/nss
.
Miscellaneous¶
The SONAME
variable declares a “shared object name” for the library. It
defaults to the Library
name or the SHARED_LIBRARY_NAME
if set. When
linking to a library with a SONAME
, the resulting library or program will
have a dependency on the library with the name corresponding to the SONAME
instead of the Library
name. This only impacts ELF systems.
a/moz.build:
Library('mylib')
b/moz.build:
Library('otherlib')
SONAME = 'foo'
c/moz.build:
Program('myprog')
USE_LIBS += [
'mylib',
'otherlib',
]
On e.g. Linux, the above myprog
will have DT_NEEDED markers for
libmylib.so
and libfoo.so
instead of libmylib.so
and
libotherlib.so
if there weren’t a SONAME
. This means the runtime
requirement for myprog
is libfoo.so
instead of libotherlib.so
.