Targets (programs/libraries)
Target descriptions are declaratively defined in rule files. They share the syntax with project descriptions, but the order of these files is irrelevant. The order of declarations within a file is also irrelevant. Moreover, the translator sorts the input files lexically before starting to parse them. This is to guarantee the same parse order on every system, so that errors appear in the same order and comparisons are easier.
Currently supported targets are programs and libraries. The simplest possible target is a program with a single source file.
program make { sources { make.c } }
If you wanted to build a library called
libmake.la
, instead, you would
substitute
library
for
program
. Programs and libraries are exactly the
same, except that libraries may be linked against by other programs and
libraries and programs may not.
Sections
A target contains at least one section and optionally a description string. You can add a description to a target. This is used in the configure summary and, in case of libraries, generated pkg-config files.
sources
The
sources
directive is used to list the sources for a target. This
directive supports wildcards and group matches.
The semantics of
*
and
?
are equal to their semantics in POSIX shell. An
additional
**
wildcard matches recursively. Furthermore,
{a b c}
group
matches may be used in wildcards.
Unlike pattern rules, these wildcards only match on the actual file system, more specifically the source directory. It does not match built files. If you want to distribute built sources, you need to list them, explicitly.
sources { # All .c files in the current directory and descendants **.c # Match ac.cc ad.cc bc.cc bd.cc {a b}{c d}.cc # Explicit source main.cpp }
Explicitly listed sources must either exist in the file system or be buildable via an explicit or pattern rule. Filenames can either be specified relative to the currently processed rules file or relative to the source root.
We recommend
not to use wildcards too much for several
reasons.
You may freely mix wildcard matches and explicit sources. The
-Wwildcard-match
flag warns for every file matched by a wildcard that was not
explicitly listed. This way, you can be notified if you create a new file
without adding it to the sources list.
Sources from other targets can be imported via a
sources
directive within the
sources list. Optionally, an
exclude
directive can prevent one or more
sources from being imported. Excluded files can either be specified in full or
just with the base name.
# sources for the math lib with emulated SSE sources { sources (mathlib) exclude { # do not import the SSE implementation math_sse.c } # we have an emulation math_see_emu.c }
A warning is issued if the imported set is empty after exclusions. It is an error to list the same file twice or to list a file that was already imported. It is, in fact, even an error to list two different files that ultimately target the same object file.
nodist_sources
All files listed in
sources
are shipped with the distribution. That includes
sources built from other sources or by rules. The
nodist_sources
section lets
you build sources without shipping them.
extra_dist
These files are added to the distribution produced by
make dist
. They are not
scoped and the files are also added, if the target containing them is not built.
This directive may also appear outside a target description.
# include/Rules extra_dist { # Distribute all header files (recursively matched) **.h }
link
In the
link
section of a target, you may refer to libraries built within this
project. The installation order of libraries is calculated using the dependency
information (libraries are topologically sorted and installed in inverse sort
order). It is an error to refer to a non-existent internal library.
In order to link against external libraries, you must add the
"-l"
prefix.
Libraries linked like this are automatically checked in configure. If you also
want to check whether certain symbols are defined in the library, you need to
add those checks, manually.
link { # Link against the locally built libmylib.la mylib # Also link against GMP -lgmp }
You may import
link
sections the same way as sources can be imported. Global
link
sections apply to all targets without a
link
section. They are not
imported by default, if a
link
section is present. In order to import the
global link section, the
link ()
directive must be present in the target's
link section.
link { # Import global libraries link () # But don't link against GMP exclude { -lgmp } }
If the global link section links against a locally built library, that library excludes itself, automatically. Care must be taken with locally built libraries in the global link section. It is very easy to introduce dependency cycles, this way.
cppflags
If inside a target, these are target-specific
CPPFLAGS
. If you define
target-specific
cppflags
, the global
cppflags
are overridden. You may
import global
cppflags
as with link and sources.
cppflags { # Import global CPPFLAGS cppflags () # Add target-specific CPPFLAGS -D_GNU_SOURCE }
Conditions
All sections in a target description may be conditionalised. The condition must
be explicitly (via
arg_enable
) or implicitly (e.g. via
library
) defined by
the
project
section.
# Add these sources iff GMP is available and enabled sources if GMP { gmp_math.c }
You may even conditionalise the entire target. Then all sections inside the
target, except
extra_dist
, are implicitly conditionalised.
program pcregrep if PCRE { ... }
Install targets
By default, programs are installed into
$bindir
and libraries are installed
into
$libdir
. You can change this by using the arrow operator.
# install to $pkglibexecdir program cc1plus -> pkglibexec { ... }
TODO: There is no way to define custom install directories, for now.