【发布时间】:2011-08-28 04:10:54
【问题描述】:
我知道有几个标题相似的问题,但似乎没有一个能提供我需要的答案(如果我错了,请纠正我)。
考虑这个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++ 编译器在一次调用模式下工作得更好,所以我更喜欢使用它。
【问题讨论】:
-
为什么你的
all目标依赖于你的$(SOURCES)?不需要,因为您的$(OBJECTS)已经一一依赖它们。 -
这只是我找到的一个例子。在我们的makefile(它们非常复杂)中,我们确实只依赖于最终的可执行文件。无论哪种方式,这都不是问题所在。
-
gcc 包装器将多次调用 cc1、gas 等。您将保存的唯一程序调用是 gcc 包装器本身。
-
你为什么想要那个?
-
您是否测试了使用和不使用“批处理模式”的编译速度?你看到有多大的不同?如果您没有测试并看到显着差异,您为什么认为这会有所帮助?