在 GNU make 中一次编译多个 **changed** 源文件

标签 c gcc makefile nmake

我知道有几个标题相似的问题,但似乎都没有提供我需要的答案(如果我错了请纠正我)。

考虑这个 makefile:

SOURCES=file1.cpp file2.cpp file3.cpp
OBJECTS=$(SOURCES:.cpp=.o)
EXECUTABLE=myprog

all: $(SOURCES) $(EXECUTABLE)

$(EXECUTABLE): $(OBJECTS)
    $(CXX) -o $@ $(OBJECTS)

file1.o: file1.cpp file1.h
file2.o: file2.cpp file2.h file1.h
file3.o: file3.cpp

.cpp.o:
    $(CXX) $(CXXFLAGS) -c -o $@ $<

如果我更改 file1.h,将运行以下命令:

g++ -c -o file1.o file1.cpp
g++ -c -o file2.o file2.cpp
g++ -o myprog file1.o file2.o file3.o 

我想要的是:

g++ -c file1.cpp file2.cpp
g++ -o myprog file1.o file2.o file3.o 

(我知道我不能用 GCC 指定对象输出目录,但我可以接受;应该可以使用一些 cd 命令来解决。)

在 nmake 中,这是通过双冒号推理规则(所谓的“batch-mode rule"”)完成的。基本上,它将多个目标的推理规则(例如“.obj.cpp:”)分组并调用所有依赖项的编译器,而不是每个文件一次。$< 变量获取依赖项列表,而不仅仅是第一个。

现在我们正在使用并行构建 (make -j),但它有其自身的问题,而 VC++ 编译器在单调用模式下工作得更好,所以我更喜欢使用它。

最佳答案

我不明白你为什么想要这种效果,但这是获得它的方法(在 GNUMake 中):

SOURCES=file1.cpp file2.cpp file3.cpp
OBJECTS=$(SOURCES:.cpp=.o)
EXECUTABLE=myprog

all: $(EXECUTABLE)

$(EXECUTABLE): $(SOURCES)
    $(CXX) $(CXXFLAGS) -c $?
    $(CXX) -o $@ $(OBJECTS)

编辑:
我很惊讶该解决方案有效——我对 Make 所做的事情的想法有问题——但我认为它不会在你的情况下起作用,有头文件依赖性,没有以下的困惑。 (如果没有成功,还有一两种其他方法可能会奏效。)

SOURCES=file1.cpp file2.cpp file3.cpp
OBJECTS=$(SOURCES:.cpp=.o)
EXECUTABLE=myprog

all: $(EXECUTABLE)

$(EXECUTABLE): $(OBJECTS)
    $(CXX) -o $@ $(OBJECTS)

file1.cpp: file1.h
file2.cpp: file2.h file1.h

$(SOURCES):
    @touch $@

$(OBJECTS): $(SOURCES)
    $(CXX) $(CXXFLAGS) -c $?
    @touch $(OBJECTS)

关于在 GNU make 中一次编译多个 **changed** 源文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6047107/

相关文章:

makefile - 铛:警告:-l *:'链接器'输入未使用

c - 段错误,C 文件处理程序

c - 如何以编程方式获取 mac os x macbooks 的电池生命周期?

我可以将 GCC 作为守护进程运行(或将其用作库)吗?

c - 如何告诉 GCC 发出一个由我命名的特定调试符号?

c - 宏中的 GCC 变量类型

linux - gcc-7 在构建 linux 内核时不能与交叉编译一起工作

c - IP头的分解

c - (Osh) Omake 错误 : Unexpected Token: String: {

c++ - Make 找不到我的 .so.2.4.8 文件