Make 始终针对目标"all"运行,即使没有任何要更新的内容

Make always runs for target "all", even when there's nothing to update

本文关键字:任何 更新 目标 Make 运行 all      更新时间:2023-10-16

我有这些文件

  • Test.cpp
  • Point.h
  • Point.cpp
  • Triangle.h
  • Triangle.cpp

,我想有一个makefile,允许我通过在需要时发出make Pointmake Triangle来单独构建每个类PointTriangle(头文件或源文件已经更改)。make all应该编译所有内容,并在需要时构建输出程序Test

这是我目前想到的:

CXX=g++
CXXFLAGS=-std=c++11 -Wall -pedantic
OBJS=Test.o Point.o Triangle.o
all : $(OBJS)
    $(CXX) $(CXXFLAGS) $(OBJS) -o Test

Point.o : Point.cpp Point.h
    $(CXX) $(CXXFLAGS) -c Point.cpp
Point : Point.o

Triangle.o : Triangle.h Triangle.cpp Point.h
    $(CXX) $(CXXFLAGS) -c Triangle.cpp
Triangle : Triangle.o

clean:
    rm *.o Test

.PHONY : Point Triangle

它似乎工作,但问题是,当我运行make all(或只是make)多次它运行命令,即使没有任何变化,给出以下输出:

g++ -std=c++11 -Wall -pedantic Test.o Point.o Triangle.o -o Test

我希望它说"Nothing to be done for 'all'."或类似的东西,就像它对其他目标一样。我错过了什么?

all对输出文件Test一无所知。因为它不知道任何特定的目标文件,所以它不能比较目标的时间戳和依赖项。这就是为什么它总是运行这个命令。您需要告诉make,通过all,您实际上是要生成文件Test。你可以这样做:

all : Test
Test : $(OBJS)
    $(CXX) $(CXXFLAGS) $(OBJS) -o Test

除了这个问题,你还需要为Test.o指定规则

猜测make的行为会浪费你很多宝贵的时间。我看到人们花了几个小时或几天的时间在无休止的重建循环中,每次都得到不同的结果。

这是好消息。几乎每一个make工具都有一个"explain"特性(gnu的make使用——debug),使用这个特性你可以确定重新构建的原因。

没有为Test.o定义规则