I've prototyped an simple approach to having conditionals and templating
in Baserock definitions.
You can see what I'm proposing in this branch:
Files that need templating are now called .morph.in, rather than .morph.
Before using definitions.git, you need to run `./configure`, which
generates the real .morph files. You can run ./configure multiple times
to create different configurations. For example, run `./configure
x86_64-generic` to create build-system.x86_64-generic.morph, and then
run `./configure jetson` to create build-system.jetson.morph.
The 'configure' script has various named configurations built into it
based on what already existed in the repo. It's also possible to specify
custom configurations, e.g:
./configure armv8l64-chroot --arch=armv8l64 --bsp=None
There are not many config flags right now, and it should stay that way,
but we can see a few more useful ones, like x11/wayland flags for the
GNOME system. Underneath it uses Jinja2 templates to substitute
variables for their values. You can probably do quite clever stuff with
them, i've kept it simple in this example, but more can be done.
I have two questions in my mind right now...
1. is the Jinja2 template language a good one? Should we use a different
preprocessor system, like GNU m4? Or should we use Nix expression
language? Should we try and come up with our own simple DSL for
I don't feel too strongly about this, except that we should avoid
having generic looping constructs or any kind of side effects.
2. Should this be built into definitions format, rather than being
The Baserock definitions format is currently a good serialization of the
actual build+integration instructions, in a way that can be used more or
less directly by tools. The addition of conditionals, branching and
templating means that is no longer true. For tools to be able to work
on the data, there needs to be a step that goes from the human-readable
input to the machine-readable data. Right now that's the 'configure'
script. If we encode these templating rules into the spec, then
effectively each tool that wants to access the definitions data needs to
have the 'configure' script built into itself.
On the other hand, code generation is a bit ugly, and indeed it can lead
to the most horrific toppling towers of hacks: see the GNU Autotools.
There have been a couple of previous thoughts on this. Tristan proposed
'flavours': those allow definining multiple variants of a component in a
single chunk .morph file, and merging the 'forks' in the dependency
graph that result. I still like that idea, and I think what I'm
proposing doesn't really conflict. It's discussed here:
A discussion of templating from 2014 is here:
Let me know what you think. I haven't tested the resulting branch
very hard, I will definitely have broken stuff. I do have the
minimal-system.x86_64-generic.morph system building with YBD though and
it seems to be going fine so far.
Sam Thursfield, Codethink Ltd.
Office telephone: +44 161 236 5575