C++ 为什么GNU总是重新链接我的项目?
我在一个满是C++ 为什么GNU总是重新链接我的项目?,c++,gcc,makefile,g++,C++,Gcc,Makefile,G++,我在一个满是.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: .
.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
CFLAGS=-g-std=c++0x-Wall-pedantic-Wextra-D\u STDC\u LIMIT\u MACROS-D\u STDC\u FORMAT\u MACROS-O0
CXX=g++
LDFLAGS=-lgmp-lmathsat-lz3
全部:Foo.o Bar.o
$(CXX)$(CFLAGS)-o myexe Foo.o Bar.o$(LDFLAGS)
依赖:。依赖
.depend:$(通配符*.cpp)
rm-f./.取决于
$(CXX)$(CFLAGS)-MM$^>/.dependent
包括,取决于
%.o:%.cpp
$(CXX)$(CFLAGS)$(包括)$<-c
清洁:
rm-f*.o myexe
当我点击make
时,它总是执行最后一步(链接),即使.o
文件没有更改。如何防止make
这样做?我希望make
输出所有最新的或类似的东西
我在一台i686 GNU/Linux机器上,使用GNU Make 3.82和g++版本4.8.2。Make总是尝试构建顶级规则。对于您来说,这是all
。由于您的all
规则实际上并不生成all
文件,因此它将始终运行
您可能希望您的all
规则成为myexe
规则,并且,如果您想要显式的all
规则,请使用仅依赖项的规则:all:myexe
(使用GNU Make,您可能希望使用.PHONY
规则明确声明那些不应该生成真实文件的目标。例如.PHONY:all depend clean
)Make
是一个基于规则的专家系统
您给它一堆规则和一个目标(默认目标是列出的第一个目标),然后它构建一个完整的依赖关系树。
如果所有零件都不存在,则重新构建它们。比它们的依赖项更早,递归地
您遇到的规则是:由于目标all
不创建输出文件all
,make将调用不存在或过时的规则
您可以通过使目标all
不做任何工作而仅仅依赖于输出文件来纠正这一点。标记它.PHONY
也是一个好主意。Make会重新链接您的项目,因为它试图构建所有
。all
的规则不会创建任何名为all
的文件。相反,它会生成myexe
。下次运行make时,它会看到没有all
,但是有一个规则来构建一个,所以每次运行make时,它都会尽职尽责地执行发生在linkmyexe
上的规则
为了解决问题,您需要将makefile更改为大致如下所示:
all: myexe
echo Build done
myexe: <myexe dependencies go here>
$(CXX) $(CFLAGS) -o myexe $(wildcard *.o) $(LDFLAGS)
all:myexe
回声建立完成
myexe:
$(CXX)$(CFLAGS)-o myexe$(通配符*.o)$(LDFLAGS)
很遗憾,我不能接受两个答案。ArtemB提供了一个代码示例,所以我接受了他的一个。请问为什么编辑被拒绝?我提出这个问题是为了与这个问题保持同步,现在对这个问题的编辑不是指$(通配符*.o)
,而是指Foo.o Bar.o
。现在的答案似乎是阿泰姆先生建议使用$(通配符*.o)
。我编辑我的问题是为了不让人们产生不好的想法,因为通配符通常是。@Hinton抱歉,我不知道编辑拒绝。在任何情况下,它们的关键是确保生成与规则匹配的文件。您的myexe是否有通配符或显式.o文件在很大程度上是无关紧要的。一点也不重要,这是供审阅者评论的。您可以尝试自己重新编辑并将$(wildcard*.o)
替换为Foo.o Bar.o
,因为只有当.o文件已经存在时,通配符才起作用。您还应该将“all”标记为虚假目标(添加一行:.phony:all
),因为名为all的文件不是根据规则生成的。您是正确的,尽管只要没有人创建文件all
,规则就可以正常工作。