views:

88

answers:

2

A requirement for a program I am writing is that it must be able to trust a configuration file. To accomplish this, I am using several kinds of hashing algorithms to generate a hash of the file at compile time, this produces a header with the hashes as constants.

Dependencies for this are pretty straight forward, my program depends on config_hash.h, which has a target that produces it.

The makefile looks something like this :

config_hash.h:
    $(SH) genhash config/config_file.cfg > $(srcdir)/config_hash.h

$(PROGRAM): config_hash.h $(PROGRAM_DEPS)
    $(CC) ... ... ... 

I'm using the -M option to gcc, which is great for dealing with dependencies. If my header changes, my program is rebuilt.

My problem is, I need to be able to tell if the config file has changed, so that config_hash.h is re-generated. I'm not quite sure how explain that kind of dependency to GNU make.

I've tried listing config/config_file.cfg as a dependency for config_hash.h, and providing a .PHONY target for config_file.cfg without success. Obviously, I can't rely on the -M switch to gcc to help me here, since the config file is not a part of any object code.

Any suggestions? Unfortunately, I can't post much of the Makefile, or I would have just posted the whole thing.

+3  A: 

What happened when you added config/config_file.cfg to the dependancies of config_hash.h, and why wasn't it what you expected?

A rule like

config_hash.h:config/config_file.cfg
    $(SH) genhash $< > $@

would regenerate config_hash.h if config/config_file.cfg was more recent. Your gcc generated dependancies would then recompile anything depending on config_hash.h.

The $@ variable is the target, using this ensures you are creating the file you asked for (In your question, if srcdir is defined the rule says it will generate ./config_hash.h, but will actually create ./$(srcdir)/config_hash.h). Similarly $< and $^ give the first and all prerequisites respectively.

I'm assuming you have a makefile like

CPPFLAGS+=-MMD -MP
all:
# etc.
config_hash.h:config/config_file.cfg
    $(SH) genhash $< > $@
%.d %.o:%.c
    $(CC) $(CPPFLAGS) $(CFLAGS) -c -o $*.o $<
%.d %.o:%.cpp
    $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c -o $*.o $<
-include $(wildcard *.d) /dev/null
Scott Wales
+5  A: 

Declaring the file in .PHONY is wrong. Any dependency listed there will not be checked in the filesystem. Just list it as a dependency for the hash header and go from there.

Ignacio Vazquez-Abrams
Thank you, that was the problem. I did not realize that .PHONY alienated dependencies, I thought it should be used on targets that don't actually _build_ anything, even if other targets that do actually depend on them.
Tim Post