如何使用makefile独立编译和更新一个文件夹中的所有文件

stc*_*eng 2 c c++ makefile

我有一个包含几个.cpp 文件的文件夹,例如A.cpp、B.cpp 和C.cpp。它们都是相互独立的。我可以将 A.cpp 编译为 Ao,然后编译为二进制文件 A。B.cpp 和 C.cpp 也是如此。

我想编写一个可以一次性编译所有这些文件的 makefile。并且以后如果有新的文件如D.cpp放入该文件夹中,makefile仍然可以自动处理。

我当前的文件是

CC=g++
CFLAGS=-c -Wall
LDFLAGS=
SOURCES=$(wildcard *.cpp)
OBJECTS=$(SOURCES:.cpp=.o)
EXECUTABLE=$(SOURCES:.cpp=)

all: $(SOURCES) $(OBJECTS) $(EXECUTABLE)

$(OBJECTS): $(SOURCES)  
    $(CC) $(CFLAGS) $(@:.o=.cpp) -o $@

$(EXECUTABLE): $(SOURCES)
    $(CC) $(LDFLAGS) $(@:=.o) -o $@
Run Code Online (Sandbox Code Playgroud)

问题是,一旦一个 .cpp 文件被更改或添加到文件夹中,如果我执行 make,所有其他文件都将被更新并重新编译。

请让我知道如何解决这个问题。

谢谢。

Eta*_*ner 5

您的 makefile 将每个源文件列出为每个可执行文件和每个目标文件的先决条件。

它也不喜欢将目标文件作为可执行文件的先决条件(这意味着 make 无法自动为您构建它们)。

这些就是问题所在。

话虽如此,您根本不需要此 makefile 中的规则。

一个 makefile 只是

CC=g++
CXXFLAGS=-c -Wall
Run Code Online (Sandbox Code Playgroud)

会让你运行make A并构建AA.cpp尽管它不会构建A.o这样做,因为它不需要)。如果您不需要设置或(或者不介意在命令行上设置它们),您甚至根本不需要 makefile 来构建AA.cppCCCXXFLAGS

$ mkdir test
$ cd test
$ ls
$ touch A.cpp
$ make CC=g++ CXXFLAGS='-c -Wall' A
g++ -c -Wall    A.cpp   -o A
Run Code Online (Sandbox Code Playgroud)

但如果你要求它做到,A.o它就会做到。

$ make CC=g++ CXXFLAGS='-c -Wall' A.o
g++ -c -Wall   -c -o A.o A.cpp
Run Code Online (Sandbox Code Playgroud)

此时 make 将尝试AA.o.

$ make CC=g++ CXXFLAGS='-c -Wall' A
g++   A.o   -o A
Run Code Online (Sandbox Code Playgroud)

要重新获得对make构建所有可执行文件的支持,您需要这样的行:

all: $(subst .cpp,,$(wildcard *.cpp))
Run Code Online (Sandbox Code Playgroud)

如果您确实想手动指定所有内容(并强制.o构建),您需要更像这样的东西。(其中使用10.5 定义和重新定义模式规则4.12 静态模式规则。)

CC=g++
CFLAGS=-c -Wall
LDFLAGS=
SOURCES=$(wildcard *.cpp)
OBJECTS=$(SOURCES:.cpp=.o)
EXECUTABLE=$(SOURCES:.cpp=)

all: $(EXECUTABLE)

%.o: %.cpp
    $(CC) $(CFLAGS) $^ -o $@

$(EXECUTABLE): % : %.o
    $(CC) $(LDFLAGS) $^ -o $@
Run Code Online (Sandbox Code Playgroud)

然后,您可以编写代码make来构建所有这些项目以及make A构建特定的项目。