我有一个包含几个.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,所有其他文件都将被更新并重新编译。
请让我知道如何解决这个问题。
谢谢。
您的 makefile 将每个源文件列出为每个可执行文件和每个目标文件的先决条件。
它也不喜欢将目标文件作为可执行文件的先决条件(这意味着 make 无法自动为您构建它们)。
这些就是问题所在。
话虽如此,您根本不需要此 makefile 中的规则。
一个 makefile 只是
CC=g++
CXXFLAGS=-c -Wall
Run Code Online (Sandbox Code Playgroud)
会让你运行make A并构建A(A.cpp尽管它不会构建A.o这样做,因为它不需要)。如果您不需要设置或(或者不介意在命令行上设置它们),您甚至根本不需要 makefile 来构建A。A.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 将尝试A从A.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构建特定的项目。
| 归档时间: |
|
| 查看次数: |
2299 次 |
| 最近记录: |