Probiotic is a simple preprocessor for evoldoers/biomake that works around certain GNU Make incompatibilities and provides minimalistic templating capabilities.
sudo yarn global add git@github.com:rulatir/probiotic.git
probiotic
reads a Makefile.pb
, writes preprocessed output to Biomakefile
in the
same directory, and passes it to biomake
.
Simple invocation without arguments reads Makefile.pb
in the current directory and invokes
biomake
without specifying a goal, resulting in building the default goal.
Biomakefile
s are regenerated upon every invocation of probiotic
. Don't commit them to
version control.
Each include
statement in Makefile.pb
that resolves to an existing file relatively to
the directory of the current file results in also preprocessing the included
file
recursively; the resulting Biomakefile
is written beside the include
d file, and
the include
statement itself is altered accordingly in preprocessed output.
probiotic
has a rudimentary templating capability: it lets you define special variables that are expanded
during further preprocessing.
The syntax to define them is similar to that of GNU Make's =
definition, except the variable name
ends with the special sigil §
(the section sign U+00A7, compose,s,o):
SOME_VARIABLE§ = value
These variables can be referred to using the normal GNU Make variable reference syntax, including the § sign that is considered to be part of the name:
TOOL§ = my-favorite-tool --some-complicated-flag --another-complicated-flag
goal: file.in
$(TOOL§) $^ > $@
The above gets transformed to:
goal: file.in
my-favorite-tool --some-complicated-flag --another-complicated-flag $^ > $@
During preprocessing, the §
-variable assignments are executed imperatively in order of occurrence. The assigned
value is in effect for all subsequent usages in the same file and in files subsequently included from it. However,
reassignments in an included file do not normally propagate to the including file: include
introduces a scope.
See the example in examples/variable-scope
.
When performing a §
-variable assignment, the right-hand side is only minimally expanded; specifically,
only the recursive occurrences of the variable being reassigned are expanded, in an effort to avoid infinite
recursion. Other than that, the §
-variable references in variable definitions remain unexpanded, which
makes rudimentary templating possible.
See the example in examples/templating
.
Preceding a §
-variable definition with the export
keyword causes the assignment to be propagated one level up,
to the directly including file. It will be in effect from the point where the file that contains the export
ed
assignment is include
d. This is equivalent to the assignment being placed in the including file as a regular
assignment without the export
keyword.
This makes it possible to move complicated template definitions to separate files. Each such file must be
include
d exactly once in a scope that contains all the scopes where the definition will be used.
See the example in examples/macro-library
, which is based on the templating example but moves template definitions
to a separate file.
Two §
-variables are automatically defined by probiotic
.
-
HERE§
- Absolute path of the directory that contains the current file.
-
REL§
-
This variable contains the path to the directory that contains the current file, relative
to the directory that contains the top-level
Makefile.pb
on whichprobiotic
was run.
The REL§
variable is initialized to .
for the top-level file, and computed accordingly for every included file.
This variable can be manually overwritten to .
anywhere, in which case subsequent includes from that file will have
the value of REL§
computed relative to the directory of the file where the REL§ = .
assignment was done;
normal scope rules apply. If your project's main Makefile.pb
does the REL§ = .
assignment at the very beginning,
and you build out-of-tree, then you can put a convenience Makefile.pb
in your build directory that includes
the main Makefile.pb
and lets you invoke probiotic
form within the build directory without
having to specify -f path/to/main/Makefile.pb
.