3 ms·
Thanks for the link -- it was really interesting. For other HN readers: The parent works at RedHat (on distro-wide build/packaging? He talks about building Fed
by drothlis 6y ago
Thanks for the link -- it was really interesting.
For other HN readers: The parent works at RedHat (on distro-wide build/packaging? He talks about building Fedora packages) and there are some useful ideas in there.
My own notes & thoughts having just watched the video:
## "Tactic" allows a target that aren't files ##
- For example a target #url("http://xyz/abc" http://xyz/abc"): to "build" it, scp the
dependency to the server.
[Edit: I had to replace * with # in "* url" above because of HN formatting.]
How does it check if the file at the url is out of date? Would be terribly
slow if it had to fetch it each time.
- For example #koji-built("package-name"): used to rebuild fedora packages
in the right dependency order, if needed, using a remote build service.
I suppose you can implement this in make/ninja by creating dummy marker files
like ".url.http_xyz_abc.built" as your target, but it's a hassle.
## Multiple parameters ##
- make rules support a single parameter, i.e. the "%" in "%.o: %.c"
- his tool supports arbitrary parameters:
goal compile (name, debug) =
"%name.%debug.o" : "%name.c" {
if [ % debug = d ]; then f=-DDEBUG=1; fi
...
}
I've been using a python script to generate ninja files, so I achieve the same
by using normal Python functions with arguments; plus ninja's built-in support
for rebuilding the target if the recipe has changed.
## Shell problems in make ##
1. filenames with spaces - his tool supports it by forcing filenames to be
quoted. "some_name" is syntactic sugar for #file("some_name") (see "tactics"
above).
2. make (by default) uses a separate shell per recipe line.
3. dollar interpreted by make so have to use $$var - his tool solves this by
using % as the escape character.
I think ninja solves the first 2 automatically. I solve the 3rd one by doing the
escaping ($ -> $$) in the Python script that generates my ninja files.
## Named goals ##
If you have a "goal" (rule) called "compile" then you can use the goal
invocation as a dependency. For example these 2 are equivalent:
goal link = "prog": "foo.o"
and
goal link = "prog": compile("foo")
THIS IS A BIG DEAL. It means you don't have to come up with artificial target
names (filenames) for intermediate build steps. In my own Python+ninja builds,
each Python function returns the target, which you can use as input to other
functions, and this has turned out to be super useful. For example (Python code):
def build_package(name, build_root_yaml):
build_root = build_container(name, build_root_yaml)
src = tarball_to_ostree(git_archive(repo, sha, prefix="src/"))
return run_command("make -C /src install DESTDIR=/dest",
ostree_combine([build_root, src]),
chroot=True,
out_subdir="/dest")
This snippet creates a filesystem image (build_root), creates a source tarball
using "git archive", unpacks that tarball into the build root, then and chroots
into the build root to run a build command, capturing the tree created in
"/dest" as a new build artifact. The return value is target representing this
build artifact -- you can pass it into other functions. It's still a filename,
but it can be generated automatically, for example as a hash of the inputs.
Note that running this python code doesn't actually do any of this building; it
just writes out a ninja file that will do it. The return value (from the python
function) is the target name. Each of "build_container", "tarball_to_ostree",
"git_archive", "run_command", and "ostree_combine" are Python functions that
behave in a similar way (writing out ninja rules and returning the target).
(I need to do a proper write-up of how we use Python+ninja+ostree in our build
system. I hope the above made some sense at least.)
## Computer sciency things ##
He talks about how his named goals are like functions, that can be called by
name or by pattern matching. I need to think about it a bit more to really
understand the implications.
---
Thanks again for the talk. I hope this doesn't come across as "but you can
already do this in ninja!". I just find it interesting to have new ways & words
to think about various build system features/capatibilies, and to compare how
different build tools tackle it. (In this vein I recommend the "build
systems a la carte" talk/paper mentioned in the OP.)