views:

212

answers:

1

I'd like to create a Makefile.am file which generates one header file mentioned in a xxx.c file.

Let's say that xxx.c contains:

#include <version.h>
...

and that I have a rule to create it at the end of Makefile.am:

version.h:
       echo '#define VERSION "'`hg id`'"' > version.h.tmp
       cmp version.h.tmp version.h || mv version.h.tmp version.h

What do I have to change to make the xxx.c compilation depend on version.h? I tried nodist_progname_SOURCES=version.h, but that doesn't seem to do it.

+2  A: 
BUILT_SOURCES = version.h

All files mentioned as BUILT_SOURCES will be built before any of the normal compilation rules run.

However, this will create a slight problem: As version.h will need to be rebuilt on every make invocation, the recompilation of every foo.c file which #includes version.h will be triggered again on every make run. We would prefer if the recompilation only happens when there is actually something that has changed.

To get around this problem, use a BUILT_SOURCES dependency on a stamp file which is "created" every time (it never is actually created, so the build rule runs every time). The build rule for that stamp file creates a new version.h file as version.h.tmp, and only copies version.h.tmp to version.h if version.h.tmp is actually different from version.h (just like your version.h rule does). So if nothing has changed in version.h, its timestamp (mtime) remains the same, and no build of objects depending on version.h is triggered:

BUILT_SOURCES = version.stamp

version.stamp:
        echo '#define VERSION "'`hg id`'"' > version.h.tmp
        cmp version.h.tmp version.h || mv version.h.tmp version.h

This solution will do what you are asking for.

Unfortunately though, there will be a slight problem when you are building from a dist tarball: Then hg id will give you bogus information, and there probably is no version.h in your tarball, so the build will fail or contain bogus version information.

I have solved this issue for a the xf86-video-radeonhd project which is using git. The git-version.h file generated in this solution contains some more version information than just a single version number. You can see this update-only-if-different solution of mine at the end of git_version.sh and the BUILT_SOURCES hookup (including handling of hopefully all out-of-source-tree and from-dist-tarball build cases) in RadeonHD.am if you are interested.

ndim

related questions