1
votes

I would like to know how to add a prerequisite to a rule with an empty recipe in GNU make. Here is a short example I made in order to explain the problem. I have a Test.c file which depends on a certain file header1.h, which includes another file header2.h. This is the make file:

Test : Test.c header1.h
    gcc -o Test Test.c

header1.h : header2.h

The last row is not empty it contains a tab character. Now assume I run make and Test is created. Afterwards I change header2.h. If I run make again, make says that Test is already updated. I expected make to remake Test since header2.h is newer than header1.h.

If I add a trivial recipe to the last rule like this

Test : Test.c header1.h
    gcc -o Test Test.c

header1.h : header2.h
    echo foo

make behaves as I expected. I also tried adding a semicolon after header2.h in the prerequisite list but this did not help.

2

2 Answers

1
votes

You've told make that Test depends on Test.c and header1.h, so it won't run the recipe unless either of the timestamps for those two files are newer than the one for Test.

You could add touch $@ as a recipe for header1.h but logically it doesn't really depend on the content of header2.h, Test does, so you should add header2.h as a dependency of Test.

Ideally however you'd avoid manually specifying all this and use GCC's dependency generating flags, you can also take advantage of make's built-in rules, an absolutely minimal example for something like this with a single source file would be

CFLAGS := -MMD
Test:
-include *.d
0
votes

Others already provided appropriate solutions: Compiler generated dependency files.

This does not answer the part of the question, why adding a "trivial recipe" (echo foo) changes anything. This probably is related to the following make bug.

As OP already found out, the bug can be circumvented by adding a trivial recipe (eg. @true). This causes make to re-evaluate the targets' "timestamp" which is why dependencies are respected expectedly.