views:

421

answers:

1

Hi,

I'm playing around with make files and the VPATH variable. Basically, I'm grabbing source files from a few different places (specified by the VPATH), and compile them into the current directory using simply a list of .o-files that I want.

So far so good, now I'm generating dependency information into a file called '.depend' and including that. Gnumake will attempt to use the rules defined so far to create the included file if it doesn't exist, so that's ok. Basically, my makefile looks like this.

VPATH=A/source:B/source:C/source

objects=first.o second.o third.o

executable: $(objects)

.depend: $(objects:.o=.c)
    $(CC) -MM $^ > $@

include .depend

Now for the real question, can I suppress the generation of the .depend file in any way? I'm currently working in a clearcase environment -> sloooow, so I'd prefer to have it a bit more under control when to update the dependency information.

It's more or less an academic exercise as I could just wrap the thing in a script which is touching the .depend file before executing make (thus making it more recent than any source file), but it'd interesting to know if I can somehow suppress it using 'pure' make.

I cannot remove the dependency to the source files (i.e. using simply .depend:), as I'm depending on the $^ variable to do the VPATH resolution for me.

If there'd be any way to only update dependencies as a result of updated #include directives, that'd be even better of course.. But I'm not holding my breath for that one.. :)

+2  A: 

If you don't want to remake .depend every time, you mustn't have a rule for it. Note that whenever you really need to remake the dependencies file, you must also remake an object file (this is not my insight, it comes from Advanced Auto-Dependency Generation, and it took me some time to grasp it). So construct .depend in the linking rule, using a PHONY target:

DEPEND_FILE = .depend
# put this command in the executable rule
    $(MAKE) DEPENDENCIES

.PHONY: DEPENDENCIES
DEPENDENCIES: $(objects:.o=.c)
    $(CC) -MM $^ > $(DEPEND_FILE)

-include $(DEPEND_FILE)

You can make things more efficient by having seperate depend files, one for each object, so that when one changes you don't have to recalculate the dependencies of all the objects:

# put this command in the %.o rule
    $(CC) -MM $< > $*.d

-include *.d

(EDIT: just corrected a dumb mistake.)

Beta
ooh.. that last thing is pretty good thinking. there's a flag to gcc (-MD) to generate dependency files while compiling too, so you don't need to run it through the preprocessor twice.
roe
I've accepted this as it inspired me to do what I did, that is have separate .d-files for each object, compiling each object with -MMD. And the `-include *.d`. This causes recompilation to be triggered when needed, producing dependencies as byproduct. No work is done when not needed. Excellent!
roe