【发布时间】:2022-01-08 16:35:09
【问题描述】:
我参考this site 创建了以下makefile 来尝试自动生成依赖项。当我使用 GNU Make 3.81(macOS 附带的那个)运行它时,我的 makefile 工作正常。但是,如果我使用较新版本的 GNU Make(4.3,通过 Homebrew 安装)运行它,则每次运行 make 时都会重新创建所有对象和依赖文件,即使源文件没有变化。
CXX := clang++
CXXFLAGS := -Wall -Werror -std=c++11
ICUROOT := ${HOME}/opt/icu4c
XERCESCROOT := ${HOME}/opt/xercesc
CPPFLAGS := -I$(ICUROOT)/include -I$(XERCESCROOT)/include
LDFLAGS := -lxerces-c -licuuc
LDLIBS := -L$(ICUROOT)/lib -L$(XERCESCROOT)/lib
OBJDIR := obj
DEPDIR := $(OBJDIR)/.deps
DEPFLAGS = -MT $@ -MMD -MP -MF $(DEPDIR)/$*.d
SRCS = $(wildcard *.cpp)
.PHONY: all
all: DOMPrint
COMPILE.cc = $(CXX) $(DEPFLAGS) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c
$(OBJDIR)/%.o: %.cpp
$(OBJDIR)/%.o: %.cpp $(DEPDIR)/%.d | $(DEPDIR)
$(COMPILE.cc) $(OUTPUT_OPTION) $<
$(DEPDIR): ; @mkdir -p $@
DEPFILES := $(SRCS:%.cpp=$(DEPDIR)/%.d)
$(DEPFILES): ;
DOMPrint: $(addprefix $(OBJDIR)/,DOMPrint.o DOMPrintFilter.o DOMPrintErrorHandler.o DOMTreeErrorReporter.o)
$(CXX) $(CXXFLAGS) $(LDLIBS) $(LDFLAGS) -o $@ $^
-include $(wildcard $(DEPFILES))
从make --debug(partial)打印的调试信息,显示依赖文件比目标文件新,重建目标文件:
GNU Make 4.3
Built for arm-apple-darwin21.1.0
Copyright (C) 1988-2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Reading makefiles...
Updating makefiles....
Updating goal targets....
File 'all' does not exist.
Prerequisite 'obj/.deps/DOMPrintErrorHandler.d' is newer than target 'obj/DOMPrintErrorHandler.o'.
Must remake target 'obj/DOMPrintErrorHandler.o'.
clang++ -MT obj/DOMPrintErrorHandler.o -MMD -MP -MF obj/.deps/DOMPrintErrorHandler.d -Wall -Werror -std=c++11 -I/Users/chunwaichan/opt/icu4c/include -I/Users/chunwaichan/opt/xercesc/include -c -o obj/DOMPrintErrorHandler.o DOMPrintErrorHandler.cpp
Successfully remade target file 'obj/DOMPrintErrorHandler.o'.
...
但是,查看下面(部分)make -p 输出中的最后修改时间,依赖文件并不比目标文件更新,但自动变量 ? 确实表明它更新。
obj/DOMPrintErrorHandler.o: DOMPrintErrorHandler.cpp obj/.deps/DOMPrintErrorHandler.d ...
# Implicit rule search has been done.
# Implicit/static pattern stem: 'DOMPrintErrorHandler'
# Last modified 2022-01-08 10:50:25.517904773
# File has been updated.
# Successfully updated.
# automatic
# ? := obj/.deps/DOMPrintErrorHandler.d
obj/.deps/DOMPrintErrorHandler.d:
# Implicit rule search has not been done.
# Last modified 2022-01-08 09:45:13.890973263
# File has been updated.
# Successfully updated.
# recipe to execute (from 'Makefile', line 32):
我已经用 GNU Make 3.81 到 4.3 测试了这个 makefile,从 4.0 版开始,这个问题发生了。我想知道较新版本的 GNU Make 中的哪些更改/增强功能导致了此问题,以及如何修复我的 makefile 以使其兼容。
【问题讨论】:
-
您确定在其他地方(例如编译器)不会出现行为差异吗?因为我的第一个倾向是猜测
make关于 depfile 比目标文件更新的说法是正确的,因此(相对于所提供的 makefile)重建目标文件是正确的。 -
另请注意,您引用的页面提到这是一个可能的问题并提供了解决方案。向下滚动到“处理异常情况”部分。
-
@JohnBollinger 我在同一个目录中运行 GNU Make 3.81 和 4.3,makefile/compiler(clang++) 也是一样的。我会尝试
gcc看看它是否会给出不同的结果。