I want to write a rule that looks something like this:
foo.out: (out of date if foo.in is newer than foo.out.stamp)
# update foo.out if and only if the new foo.out has different contents
# than the old foo.out (a change to foo.in may or may not change foo.out)
&& touch foo.out.stamp
I can’t do this:
foo.out.stamp: foo.in
# update foo.out if and only if the new foo.out has different contents
# than the old foo.out (a change to foo.in may or may not change foo.out)
&& touch foo.out.stamp
foo.out: foo.out.stamp
Because if foo.in changes, but the recipe for foo.out.stamp does not change foo.out, make will always view foo.out as out of date.
Is there any way to write this kind of rule?
Edit: Explanation of why I don’t unconditionally touch foo.out:
I am working with Vala. The Vala compilation process looks something like this:
- For each
.valafile, generate a.vapifile (similar to a header file). - For each
.valafile, generate a.cfile (this requires the individual.valafile and every.vapifile to be given to the compiler) - Continue the typical
.c -> .o -> executable/libraryprocess.
For steps #1 and #2, the Vala compiler only updates the .vapi/.c file if its contents have been changed. This is to prevent needless .c -> .o recompilation.
In makefile terms:
- A
.vapifile is out of date if the.valafile has changed since the last time the Vala compiler regenerated the.vapifile (not the last time that the.vapifile was modified). - A
.cfile is out of date if the.valaor any.vapifile has changed since the last time the Vala compiler regenerated the.cfile (not the last time that the.cfile was modified).
I ended up solving this by adding a top-level rule that ensures the stamps are always up to do, and empty rules for the real output files:
Technically that isn’t exactly what I did, because I am not writing the Makefiles by hand (I am working with cmake). In CMake terms, I added a custom target that depends on all the
.vapi.stampand.dep(similar to a.c.stamp) files. The CMake target that builds the executable/library from the.cfiles depends on this target.