使用 gmake 自动标头依赖关系

发布于 2024-12-03 18:59:11 字数 688 浏览 0 评论 0原文

已编辑

我试图重新编译源文件,而不必在 makefile 中为每个 CPP 指定头文件。

我的想法是:

#CoreObj1.cpp(and .h)
#CoreObj2.cpp(and .h)

#This is the makefile.

CORE_COMPONENT_OBJECTS = \
  obj/CoreObj1.o \
  obj/CoreObj2.o \

# Objects
obj/%.o: %.cpp obj/%.d
        @mkdir -p obj
        $(CXX) $(CXX_CFLAGS) -c $*.cpp -o $@

# Dependencies
obj/%.d: %.cpp
        @mkdir -p obj
        $(CXX) $(CXX_CFLAGS) -MM -MF $@ $<

DEPS = $(CORE_COMPONENT_OBJECTS:.o=.d)

ifneq ($(MAKECMDGOALS),clean)
-include $(DEPS)
endif   

但是修改头文件不会触发包括它在内的源文件被重新编译。

注意:事实上,如果我的 .o、.d 和 .cpp 位于同一文件夹中,它就可以工作。但如果我的 .d 和 .o 位于 obj/ 文件夹中,它不会触发重新编译。

EDITED

I'm trying to have source files recompiled without having to specify header files for each CPP in the makefile.

I'm down to :

#CoreObj1.cpp(and .h)
#CoreObj2.cpp(and .h)

#This is the makefile.

CORE_COMPONENT_OBJECTS = \
  obj/CoreObj1.o \
  obj/CoreObj2.o \

# Objects
obj/%.o: %.cpp obj/%.d
        @mkdir -p obj
        $(CXX) $(CXX_CFLAGS) -c $*.cpp -o $@

# Dependencies
obj/%.d: %.cpp
        @mkdir -p obj
        $(CXX) $(CXX_CFLAGS) -MM -MF $@ 
lt;

DEPS = $(CORE_COMPONENT_OBJECTS:.o=.d)

ifneq ($(MAKECMDGOALS),clean)
-include $(DEPS)
endif   

But modifying a header files does not trigger the source files including it to be recompiled.

NOTE: In fact, it works if my .o, .d and .cpp are in the same folder. But if my .d and .o are in a obj/ folder, it doesn't trigger the recompile.

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

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

发布评论

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

评论(3

夜清冷一曲。 2024-12-10 18:59:11

人们经常有这样的依赖生成规则,但它们确实没有必要。

第一次构建项目时不需要依赖项,因为它无论如何都会构建所有源。只有后续构建才需要先前构建的依赖项来检测需要重建的内容。

因此,依赖项实际上是编译的副产品。您的规则应如下所示:

#CoreObj1.cpp(and .h)
#CoreObj2.cpp(and .h)

#This is the makefile.

CORE_COMPONENT_OBJECTS = \
  obj/CoreObj1.o \
  obj/CoreObj2.o \

# Objects
obj/%.o: %.cpp
        @mkdir -p obj
        $(CXX) $(CXX_CFLAGS) -c -o $@ -MD -MP -MF ${@:.o=.d} 
lt;

DEPS = $(CORE_COMPONENT_OBJECTS:.o=.d)

ifneq ($(MAKECMDGOALS),clean)
-include $(DEPS)
endif   

作为旁注,mkdir -p 不是并行 make 友好的。例如,当两个或多个进程竞相创建 /a/b/c//a/b/cc/ 时,/a/b/< /code> 不存在,一个 mkdir 进程可能会失败,并出现 EEXIST 尝试创建 /a/b/

People often have such rules for dependency generation, but they are really unnecessary.

The first time a project is built no dependencies are necessary since it builds all sources anyway. It is only the subsequent builds that require the dependencies from the previous build to detect what needs to be rebuild.

Therefore, the dependencies are really a by-product of compilation. Your rules should look like the following:

#CoreObj1.cpp(and .h)
#CoreObj2.cpp(and .h)

#This is the makefile.

CORE_COMPONENT_OBJECTS = \
  obj/CoreObj1.o \
  obj/CoreObj2.o \

# Objects
obj/%.o: %.cpp
        @mkdir -p obj
        $(CXX) $(CXX_CFLAGS) -c -o $@ -MD -MP -MF ${@:.o=.d} 
lt;

DEPS = $(CORE_COMPONENT_OBJECTS:.o=.d)

ifneq ($(MAKECMDGOALS),clean)
-include $(DEPS)
endif   

As a side note, mkdir -p is not parallel make friendly. For example, when two or more processes race to create /a/b/c/ and /a/b/cc/ when /a/b/ doesn't exist, one mkdir process may fail with EEXIST trying to create /a/b/.

半边脸i 2024-12-10 18:59:11

您没有依赖文件作为编译规则的先决条件。应该是这样的:

#This is the rule for creating the dependency files
src/%.d: src/%.cpp
    $(CXX) $(CXX_CFLAGS) -MM -MF $(patsubst obj/%.o,obj/%.d,$@) -o $@ 
lt;

obj/%.o: %.cpp %.d
    $(CXX) $(CXXFLAGS) -o $@ -c 
lt;

-include $(SRC:%.cpp=%.d)

最后一个字符串添加了对标头的依赖。

编辑

我看到你有

-include $(DEPS)

,但检查 $(warning DEPS = $(DEPS)) 是否真的包含现有文件,否则就默默地忽略这些文件。

You don't have dependency file as a prerequisite for compilation rule. Should be something like this:

#This is the rule for creating the dependency files
src/%.d: src/%.cpp
    $(CXX) $(CXX_CFLAGS) -MM -MF $(patsubst obj/%.o,obj/%.d,$@) -o $@ 
lt;

obj/%.o: %.cpp %.d
    $(CXX) $(CXXFLAGS) -o $@ -c 
lt;

-include $(SRC:%.cpp=%.d)

The last string adds dependency on headers.

EDIT

I see you have

-include $(DEPS)

but check with $(warning DEPS = $(DEPS)) whether you really include existing files, otherwise make just silently ignore these.

╰沐子 2024-12-10 18:59:11

使用 SCons/CMake/bjam 解决“头依赖问题”比使用 make 更好

It's better to use SCons/CMake/bjam to solve "header dependencies problem" than use make

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