为什么这个简单的makefile不能在更改时重新构建源代码



我编写了这个简单的makefile,它工作得很好,直到我想做一些更改并将它们应用到二进制文件中。然后我需要再次执行'make clean'和'make',因为obj。文件将无法重建。虽然这似乎是一个简单的任务,到目前为止,我未能修改它,以使obj。文件重建隐式(所以我只能写'make'当我修改源代码)。

COMPILER=g++-5.3
CXXFLAGS=-std=c++11 -O2 -pedantic
build : a.o
     $(COMPILER) a.o -o a
a.o:
     $(COMPILER) $(CXXFLAGS) -c a.cpp -o a.o
clean :
    rm -f *.o *~ a

编辑:我尝试了Omada建议的更改(在我写这个问题之前我自己也尝试过),这是结果:

me@pc: ~/mypath$ cat a.cpp
#include <iostream>
int main(int argc, char* argv[])
{
    if ( argc!=2 ){
        std::ceaaarr<<"Prrogram expects 1 argumentn";
        return 1;
    }
    return 0;
}me@pc: ~/mypath$ make
g++-5.3 a.o -o a
me@pc: ~/mypath$ cat Makefile
#init
COMPILER=g++-5.3
CXXFLAGS=-std=c++11 -O2 -pedantic
build: a.o
        $(COMPILER) a.o -o a
a.o: a.cpp
        $(COMPILER) $(CXXFLAGS) -c a.cpp -o a.o
clean:
        rm -f *.o *~ a

由于您从未告诉makefile a.o依赖于a.cpp,因此它将无法确定当a.cpp改变时,它应该重建a.o

修改

a.o:
    $(COMPILER) $(CXXFLAGS) -c a.cpp -o a.o

a.o: a.cpp
    $(COMPILER) $(CXXFLAGS) -c a.cpp -o a.o

如果它不工作,请告诉我,我对我的makefiles有点生疏。

如果你告诉make做什么,它就会按照你说的去做。如果您使用构建a.o的目标编写规则,并且没有列出先决条件,则make认为目标没有先决条件:在这种情况下,如果目标(a.o)存在,则make将假定它是最新的。Omada告诉您如何通过添加先决条件来避免这种情况。您也可以不定义自己的规则,而是简单地使用make的内置规则,这些规则已经知道如何从.cpp文件创建目标文件(但是,它使用CXX变量而不是COMPILER)。

同样,如果你定义了一个规则build: a.o,它告诉make为了构建一个名为build的目标,它应该检查一个名为build的文件是否存在,以及a.o是否比它更新。如果文件build不存在,那么它将运行您提供的配方。

因为你的配方,$(COMPILER) $(CXXFLAGS) a.o -o a实际上并没有创建一个名为build的文件,它总是过时的,总是会运行。

您必须确保您的配方实际上创建了您试图构建的目标的名称:

a: a.o
        $(COMPILER) a.o -o a

最新更新