使用gcc -MM标志在单个文件中生成所有项目依赖项

时间:2009-12-30 18:08:01

标签: makefile dependencies

我想生成一个依赖文件,该文件包含源文件的所有依赖项,使用gcc -M标志通过Makefile。我搜索了这个解决方案但是,提到的所有解决方案都是为多个对象生成多个deps文件。

DEPS = make.dep

$(OBJS): $(SOURCES)
    @$(CC) -MM $(SOURCEs) > $(DEPS)
    @mv -f $(DEPS) $(DEPS).tmp
    @sed -e 's|.$@:|$@:|' < $(DEPS).tmp > $(DEPS)
    @sed -e 's/.*://' -e 's/\\$$//' < $(DEPS).tmp | fmt -1 | \
      sed -e 's/^ *//' -e 's/$$/:/' >> $(DEPS)
    @rm -f $(DEPS).tmp

但它无法正常工作。请告诉我我在哪里弄错了。

2 个答案:

答案 0 :(得分:7)

我使用的方法是将所有依赖项放在一个文件中:

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)

这基本上会导致所有用户(而不是系统)依赖项在项目中的任何C或H文件被修改时重建为单个文件。

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

我已经找到了更好的做事方式。我为每个源文件生成一个单独的dep文件。这是基本的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

这有两件事:

  1. 如果foo.c的任何文件依赖于更改,则重建foo.o而不必重建项目中的其他文件。
  2. dep文件本身与目标文件具有相同的依赖关系,因此如果修改了任何deps,则在检查目标文件deps之前,还会重新生成dep文件本身。

答案 1 :(得分:1)

我认为是gcc -M的预期行为,通常你会做这样的事情:

FOO_SOURCES= \
    src/foo.c \
    src/bar.c

FOO_OBJECTS = $(FOO_SOURCES:.c=.o)
FOO_DEPS = $(FOO_OBJECTS:.o=.d)

(......很多目标......)

-include $(FOO_DEPS)

注意,-include不是include,因为在至少运行一个构建之前,依赖项显然不会存在。无论如何,依赖关系是基于每个模块生成的。

另请注意,gcc -M并不总是像您期望的那样有效,大致取决于您恰巧使用的gcc版本。

我认为你想要的是一个名为makedep的东西,它可以在makefile中没有sed hackery的情况下做你想要的。