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

发布于 2024-08-16 13:19:18 字数 462 浏览 3 评论 0原文

我想通过 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

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

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|.$@:|$@:|' < $(DEPS).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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

倦话 2024-08-23 13:19:18

沿着这些思路,我用来将所有依赖项放入单个文件中:

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 文件本身与目标文件具有相同的依赖关系,因此,如果任何 dep 被修改,则在检查目标文件 deps 之前,dep 文件本身也会重新生成。

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:

  1. 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.
  2. 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.
随梦而飞# 2024-08-23 13:19:18

我认为这是 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 来完成你想要的事情。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文