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时,它都会尽职尽责地执行发生在link
myexe
上的规则

为了解决问题,您需要将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
,规则就可以正常工作。