Target templates
Templates define common flags and sources for targets. They do not define targets, by themselves. Templates offer a better structured way to inheriting sources and libraries.
# Build a program that does some math program prog { sources { main.c math.c } link { -lm } } # Build a program that does the same math but with GMP program gmpprog { sources { # Import prog's sources sources (prog) # except math.c exclude { math.c } # because we reimplement it using GMP gmpmath.c } link { # Import prog's link section link (prog) # And link against GMP -lgmp } }
The above example can be better written as follows:
template math-program { sources { main.c } link { -lm } } # Inherit from the "math-program" template. program prog : math-program { sources { math.c } } program gmpprog : math-program { sources { gmpmath.c } link { -lgmp } }
Both programs inherit the sources and link blocks from
math-program
and add
their own sources to it. This method is better structured but less flexible.
Templates can inherit from other templates. It is still possible to import
sources from other templates and even targets.
Note that templates also have their own namespace, so that it is possible to declare a template with the same name as a target.
It is not possible to exclude inherited
sources
,
link
, etc. Template
inheritance forms an
is-a relationship.
Multiple inheritance
Multiple templates can be inherited. Order of inheritance does not matter and conflicts are flagged as an error. Two templates linking against the same library or listing the exact same source file is not a conflict. Targets can not serve as a base, so a target or template cannot inherit from another target, only from templates. Inheriting from a template more than once, even implicitly through another base, is an error.
template math-program { sources { math-support.c } link { -lm } } template system-program { sources { system-support.c } link { -lutil } } program sysprog : math-program, system-program { sources { main.c } }
Filtering
As we learned in
variables, one may filter the
$(prog.link)
variable by
locally built libraries. Templates take this one step further by allowing you to
filter by template.
template math-library { ... } library mathsupport : math-library { ... } program mathprog { sources { ... } link { # Link against two support libraries mathsupport support # Also link against libm -lm } }
In the above example, the
$(mathprog.link)
variable would expand to
"
mathsupport support -lm
". The expansion of
$(mathprog.link : library)
would be "
mathsupport support
", and expanding the pseudo-variable
$(mathprog.link : math-library)
results in just "
mathsupport
". This is
especially useful in
pattern rules.