'How are dependency files in Makefile with include resolved
I have a few questions about makefiles. I have defined my own version of a dependency file (.d) by creating it in code and called it say .dd (Looks just like a normal .c dependency file except that this is for some internal file format). Now this file I have included in the makefile with the include statement. (There are a whole bunch of these files so I've defined this as a rule which uses subst to replace the extension as required.)
Now suppose that file X depends on file Y i.e. X.dd contains a reference to file Y. Now from my understanding, whenever I run make and the program goes through the include and finds that Y has been updated, it somehow recompiles this so as to reflect the changes in X.
My question and problem is when this timestamp change in Y is noticed, does make restart itself so as to include the changes. How exactly are dependency files of this sort resolved. Also file X is not a typical .c or .cc file. So how would the file be treated when its dependency changes.
The problem I'm facing is that if file Y is changed/touched, file X does not recompile. Also if I touch file X, it recompiles just fine. Also as expected, if the makefile is touched, everything recompiles appopriately.
This bug has me scratching my head for a few days now so any help whatsoever would be appreciated.
Solution 1:[1]
Presuming that an X.boy is generated from an X.src (and Y.boy from Y.src) then to following works:
Makefile: all: X.boy Y.boy
# for the example I will generate .boy with cp
%.boy: %.src
cp $< $@
include X.dd
X.dd: X.boy: Y.src
This then gives:
$make
cp X.src X.boy
cp Y.src Y.boy
$touch X.src
$make
cp X.src X.boy
$touch Y.src
$make
cp X.src X.boy
cp Y.src Y.boy
Solution 2:[2]
My question and problem is when this timestamp change in Y is noticed,does make restart itself so as to include the changes.
GNU make reads the timestamps of files once, when it starts up. If you don't explicitly re-invoke it (e.g. by calling make or $MAKE from within the makefile), it won't re-check the timestamps after running commands.
So how would the file be treated when its dependency changes.
All files are treated identically; make just has a few built in rules for some types of files. Dependencies are handled the same way for all file types.
It sounds like your included .d file is creating a dependency on the source file(s), and not the target file. You can verify this by printing the rules make is using with make -p.
I'll use c files as an example, since you already know how their dependencies should work. Lets assume you have a file foo.c (source) which gets compiled to foo.o (target) and whos dependencies are specified in foo.d. For this example, lets say if bar.h or baz.h change, we want foo.o to be rebuilt.
foo.d should then contain something like:
foo.o : bar.h baz.h
And your makefile would read
%.o:%.c
$(CC) -c $< -o $@
include foo.d
Your symptoms sound like you have instead got a foo.d containing:
foo.c: bar.h baz.h
^
Or something totally unrelated on the left hand side, such that make does not see a dependency on foo.o. If you run make -p and search for foo.o in the output, you will see what make thinks it depends on from your makefile contents.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Beano |
| Solution 2 | Jon |
