Generate all project dependencies in a single file using gcc -MM flag
I want to generate a single dependency file which consists of all the dependencies of source files using gcc -M flags through Makefile. I googled for this solution but, all the solutions mentioned are for generating multiple deps files for multiple objects.
DEPS = make.dep
$(OBJS): $(SOURCES)
@$(CC) -MM $(SOURCEs) > $(DEPS)
@mv -f $(DEPS) $(DEPS).tmp
@sed -e 's|.$@:|$@:|' < $(DE开发者_如何学JAVAPS).tmp > $(DEPS)
@sed -e 's/.*://' -e 's/\\$$//' < $(DEPS).tmp | fmt -1 | \
sed -e 's/^ *//' -e 's/$$/:/' >> $(DEPS)
@rm -f $(DEPS).tmp
But it is not working properly. Please tell me where i'm making the mistake.
Something along these lines is what I use to get all my dependencies in a single file:
program_H_SRCS := $(wildcard *.h)
program_C_SRCS := $(wildcard *.c)
DEPS = make.deps
make.deps: $(program_C_SRCS) $(program_H_SRCS)
$(CC) $(CPPFLAGS) -MM $(program_C_SRCS) > make.deps
include $(DEPS)
This basically causes all the user ( as opposed to system ) dependencies to be rebuilt into a single file whenever any C or H file in the project is modified.
+++++++++ EDIT +++++++++++
I've since found a better way of doing things. I generate a separate dep file for each source file. Here is the basic makefile:
program_NAME := myprogram
program_SRCS := $(wildcard *.c)
program_OBJS := ${program_SRCS:.c=.o}
clean_list += $(program_OBJS) $(program_NAME)
# C Preprocessor Flags
CPPFLAGS +=
# compiler flags
CFLAGS += -ansi -Wall -Wextra -pedantic-errors
.PHONY: all clean distclean
all: $(program_NAME)
clean:
@- $(RM) $(clean_list)
distclean: clean
# Generate dependencies for all files in project
%.d: $(program_SRCS)
@ $(CC) $(CPPFLAGS) -MM $*.c | sed -e 's@^\(.*\)\.o:@\1.d \1.o:@' > $@
clean_list += ${program_SRCS:.c=.d}
$(program_NAME): $(program_OBJS)
indent -linux -brf $(program_SRCS)
splint $(program_SRCS)
$(LINK.c) $(program_OBJS) -o $(program_NAME)
ifneq "$(MAKECMDGOALS)" "clean"
# Include the list of dependancies generated for each object file
-include ${program_SRCS:.c=.d}
endif
This does two things:
- If any of the files that foo.c depend on change then foo.o is rebuilt without having to rebuild other files in the project.
- The dep file itself has the same dependencies as the object file, so that if any of the deps are modified the dep file itself is also regenerated, before the object file deps are checked.
I think is is expected behaviour for gcc -M
, where typically you'd do something like this:
FOO_SOURCES= \
src/foo.c \
src/bar.c
FOO_OBJECTS = $(FOO_SOURCES:.c=.o)
FOO_DEPS = $(FOO_OBJECTS:.o=.d)
(... lots of targets ...)
-include $(FOO_DEPS)
Note, -include
not include
as the dependencies will obviously not exist until at least one build has been run. Regardless, dependencies are generated on a per module basis.
Also note that gcc -M
does not always work as you would expect it to work, broadly depending on what version of gcc you happen to be using.
I think what you want is something called makedep, which does what you want without sed hackery in the makefile.
精彩评论