Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GCC dependency generation for a different output directory

Tags:

I'm using GCC to generate a dependency file, but my build rules put the output into a subdirectory. Is there a way to tell GCC to put my subdirectory prefix in the dependency file it generates for me?

gcc $(INCLUDES) -E -MM $(CFLAGS) $(SRC) >>$(DEP) 
like image 412
KPexEA Avatar asked Sep 18 '08 21:09

KPexEA


2 Answers

I'm assuming you're using GNU Make and GCC. First add a variable to hold your list of dependency files. Assuming you already have one that lists all our sources:

SRCS = \         main.c \         foo.c \         stuff/bar.c  DEPS = $(SRCS:.c=.d) 

Then include the generated dependencies in the makefile:

include $(DEPS) 

Then add this pattern rule:

# automatically generate dependency rules  %.d : %.c         $(CC) $(CCFLAGS) -MF"$@" -MG -MM -MP -MT"$@" -MT"$(<:.c=.o)" "$<"  # -MF  write the generated dependency rule to a file # -MG  assume missing headers will be generated and don't stop with an error # -MM  generate dependency rule for prerequisite, skipping system headers # -MP  add phony target for each header to prevent errors when header is missing # -MT  add a target to the generated dependency 

"$@" is the target (the thing on the left side of the : ), "$<" is the prerequisite (the thing on the right side of the : ). The expression "$(<:.c=.o)" replaces the .c extension with .o.

The trick here is to generate the rule with two targets by adding -MT twice; this makes both the .o file and the .d file depend on the source file and its headers; that way the dependency file gets automatically regenerated whenever any of the corresponding .c or .h files are changed.

The -MG and -MP options keep make from freaking out if a header file is missing.

like image 180
Don McCaughey Avatar answered Oct 13 '22 05:10

Don McCaughey


The answer is in the GCC manual: use the -MT flag.

-MT target

Change the target of the rule emitted by dependency generation. By default CPP takes the name of the main input file, deletes any directory components and any file suffix such as .c, and appends the platform's usual object suffix. The result is the target.

An -MT option will set the target to be exactly the string you specify. If you want multiple targets, you can specify them as a single argument to -MT, or use multiple -MT options.

For example, -MT '$(objpfx)foo.o' might give

$(objpfx)foo.o: foo.c 
like image 30
bk1e Avatar answered Oct 13 '22 04:10

bk1e