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

Makefile 使用gcc-MM标志在单个文件中生成所有项目依赖项,makefile,dependencies,Makefile,Dependencies,我想通过Makefile生成一个依赖项文件,其中包含使用gcc-M标志的源文件的所有依赖项。我在谷歌上搜索过这个解决方案,但提到的所有解决方案都是为多个对象生成多个deps文件 DEPS = make.dep $(OBJS): $(SOURCES) @$(CC) -MM $(SOURCEs) > $(DEPS) @mv -f $(DEPS) $(DEPS).tmp @sed -e 's|.$@:|$@:|' < $(DEPS).tmp > $(DEPS

我想通过Makefile生成一个依赖项文件,其中包含使用gcc-M标志的源文件的所有依赖项。我在谷歌上搜索过这个解决方案,但提到的所有解决方案都是为多个对象生成多个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
DEPS=make.dep
$(OBJS):$(来源)
@$(CC)-MM$(来源)>$(部门)
@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

但它不能正常工作。请告诉我哪里出了错。

我认为这是
gcc-m的预期行为,通常您会这样做:

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

FOO_OBJECTS = $(FOO_SOURCES:.c=.o)
FOO_DEPS = $(FOO_OBJECTS:.o=.d)
(…很多目标…)

注意,
-include
include
,因为依赖项在至少运行一个生成之前显然不存在。不管怎样,依赖项是基于每个模块生成的

还请注意,
gcc-M
并不总是像您期望的那样工作,这主要取决于您使用的gcc版本


我认为您想要的是一种叫做sed hackery的东西,它在makefile中不使用sed hackery就可以实现您想要的功能。

我使用这些东西在单个文件中获取所有依赖项:

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文件时,将所有用户(而不是系统)依赖项重新构建到单个文件中

+++EDIT++++

从那以后,我找到了更好的做事方式。我为每个源文件生成一个单独的dep文件。以下是基本生成文件:

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
这有两个作用:

  • 如果foo.c依赖的任何文件发生了更改,那么将重建foo.o,而不必重建项目中的其他文件
  • dep文件本身与目标文件具有相同的依赖关系,因此,如果修改了任何dep,也会在检查目标文件dep之前重新生成dep文件本身

  • 非常感谢你。我想这可能是我的新终极生成文件,适用于任何项目。@digy很高兴我能帮上忙:-)
    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