为啥 GNU make 总是重新链接我的项目?
Posted
技术标签:
【中文标题】为啥 GNU make 总是重新链接我的项目?【英文标题】:Why does GNU make always re-link my project?为什么 GNU make 总是重新链接我的项目? 【发布时间】:2014-04-29 17:15:08 【问题描述】:我在一个充满 .cpp
和 .h
文件的目录中有以下 Makefile:
CFLAGS=-g -std=c++0x -Wall -pedantic -Wextra -D __STDC_LIMIT_MACROS -D __STDC_FORMAT_MACROS -O0
CXX=g++
LDFLAGS=-lgmp -lmathsat -lz3
all: Foo.o Bar.o
$(CXX) $(CFLAGS) -o myexe Foo.o Bar.o $(LDFLAGS)
depend: .depend
.depend: $(wildcard *.cpp)
rm -f ./.depend
$(CXX) $(CFLAGS) -MM $^ > ./.depend
include .depend
%.o: %.cpp
$(CXX) $(CFLAGS) $(INCLUDE) $< -c
clean:
rm -f *.o myexe
当我点击make
时,即使.o
文件都没有更改,它也会始终执行最后一步(链接)。我怎样才能防止make
这样做?我希望make
输出Everything up-to-date
或类似的东西。
我在 i686 GNU/Linux 机器上使用 GNU Make 3.82 和 g++ 版本 4.8.2。
【问题讨论】:
【参考方案1】:Make 重新链接您的项目,因为它尝试构建 all
。 all
的规则不会创建任何名为 all
的文件。相反,它产生myexe
。下次你运行 make 时,它会发现没有 all
,但是有一个构建规则,所以它尽职尽责地执行该规则,每次运行 make 时都会链接 myexe
。
为了解决您的问题,您需要将您的 makefile 更改为大致如下所示:
all: myexe
echo Build done
myexe: <myexe dependencies go here>
$(CXX) $(CFLAGS) -o myexe $(wildcard *.o) $(LDFLAGS)
【讨论】:
请问为什么编辑被拒绝了?我提出这个是为了与问题同步,现在编辑不是指$(wildcard *.o)
,而是指Foo.o Bar.o
。现在的答案看起来好像是 ArtemB 先生建议使用$(wildcard *.o)
。我编辑了我的问题,以免给人们带来不好的想法,因为通配符通常是。
@Hinton 对不起,我不知道编辑拒绝。在任何情况下,他们的关键是确保 make 规则生成与规则匹配的文件。您的 myexe 是否具有通配符或显式 .o 文件在很大程度上无关紧要。
完全没有,是给审稿人的意见。您可以尝试自己重做编辑并将$(wildcard *.o)
替换为Foo.o Bar.o
,因为通配符仅在.o 文件已经存在时才有效。
您还应该将 'all' 标记为虚假目标(添加一行:.PHONY: all
),因为规则不会生成名为 all 的文件。
你是对的,但只要没有人创建文件all
,规则就应该可以正常工作。【参考方案2】:
Make 总是尝试构建***规则。对你来说,这是all
。由于您的 all
规则实际上并没有创建 all
文件,因此它将始终运行。
您可能希望您的 all
规则成为 myexe
规则,如果您想要明确的 all
规则,请使用仅依赖规则:all: myexe
。
(使用 GNU Make,您可能希望使用 .PHONY
规则显式声明那些不应生成真实文件的目标。例如 .PHONY: all depend clean
。)
【讨论】:
太糟糕了,我不能接受两个答案。 ArtemB 提供了一个代码示例,所以我接受了他的。【参考方案3】:make
是一个基于规则的专家系统。
你给它一堆规则和一个目标(默认目标是列出的第一个),然后它会构建一个完整的依赖关系树。 如果它们不存在,所有部分都将被重建。递归地比它们的依赖项更早。
您遇到的规则是:因为目标all
没有创建输出文件all
,所以make 调用了不存在或过时的规则。
您可以通过使目标all
不执行任何工作而仅依赖于输出文件来纠正此问题。将其标记为.PHONY
也是一个好主意。
【讨论】:
以上是关于为啥 GNU make 总是重新链接我的项目?的主要内容,如果未能解决你的问题,请参考以下文章