views:

118

answers:

2

Hi,

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.

Please let me know if you need any additional information.

Regards

Shishir

A: 

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
Beano
A: 

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.

Jon
Thanks for the detailed reply. Now taking your example, if make encountered that bar.h had changed, would it then restart itself in order to compile foo.o again or would it simply make a note of that in its internal database and compile it next? And would this action occur on files that were not .c as well?
Also I tried changing the target in the .d file but it didn't seem to work. I'll try playing around with those values again and post my findings. Thanks again :)
If bar.h changes, and that makes it newer than foo.o, then foo.o will be rebuilt. The timestamps used for this are from the initial invocation of make, it does not restart. As long as your dependencies are correct, it doesn't matter what kind of files they are. Perhaps you should create a very short sample makefile and .d file and post them...
Jon