Triggering SCM info generation and ninja rules

506 views
Skip to first unread message

Maxim Kalaev

unread,
Jul 16, 2012, 4:10:57 AM7/16/12
to ninja...@googlegroups.com
I want my final executable to contain info about GIT commits and unmodified files included in it to be able to know exactly which GIT version was used to build it (could be a nice addition for ninja executable itself, BTW).
This can be accomplished running a couple of git commands and generating scm_info.c file with a versioning info string to be included into the final executable (e.g., git rev-parse HEAD, git status -uno --short + some scripts to make this into C array).

Then comes the question when to run this scripts to generate the information. My options are:
- on each build attempt, including noop: define a phony rule running these commands always - silly - no noop builds.
- when any input to the final executable changes: better, but still annoying: makes scm_info.c deplist annoyingly long (and incorrect, actually), and as a result - can't create scm_info.c it in parallel to other commands while I could. - at least I have a noop build here.
- adding to ninja a 'build_info' variable which will make edge dirty IFF any non 'build_info' target is dirty, or may be, introducing a new type of 'trigger dependency', being an opposite of 'order-only' dependencies, meaning - independent in terms of order, but becomes dirty if any of the dependants are dirty.

What would you suggest?

Nico Weber

unread,
Jul 16, 2012, 6:10:53 AM7/16/12
to ninja...@googlegroups.com
- from a scm postcommit hook, or postsync hook
- don't include this information in your executable

None of the options is the Obvious Best Option, so you get to pick
your tradeoff. Ninja picks the last option. In chromium, we currently
use a scm post sync hook.

Nico

Evan Martin

unread,
Jul 16, 2012, 11:17:15 PM7/16/12
to ninja...@googlegroups.com
build version-info.c: extract-from-git | [git ls-files output here]

This is incorrect when you've added files, but fundamentally if you
want to include information only tracked by git you'll need to ask
git. Thankfully git the relevant git commands are rather fast and do
much of the same work ninja does (so will share kernel caches of file
state with ninja).

Maxim Kalaev

unread,
Jul 18, 2012, 4:27:01 PM7/18/12
to ninja...@googlegroups.com
Nico, Evan thanks for the ideas.
Evan's hint to make scm_info.c dependent on .c files (as opposite to .o files which I've did originally) led me to the pattern which I find pretty suffisticated:

$my_smcinfo_script = blabla

rule ScmInfoBuildTool
    command = (echo $out: \\ ; git ls -z | while read -rd '' f; do printf '%q \\\n' "$$f"; done) > $out.d && $my_smcinfo_script
    depfile = $out.d

build version_info/scm_info.c: ScmInfoBuildTool  |  ||

It only runs when something changes in the buid tree, runs in parallel to build commands and it seems to track addition and removal of files pretty well.
For perfection it's possible to extend it a bit to make it dependendent on '$$(git rev-parse --git-dir)/$$(git rev-parse --symbolic-full-name HEAD)' file to catch git history rewrites which change nothing in the build tree. ;)
Reply all
Reply to author
Forward
0 new messages