我知道有几个问题有类似的标题,但似乎没有提供我需要的答案(纠正我,如果我错了)。
考虑这个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 ++编译器在一次调用模式下运行得更好,所以我更喜欢使用它。
答案 0 :(得分:1)
我不明白为什么你想要这个效果,但是这里是如何得到它的(在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的看法有些不对劲 - 但是我不认为它会在你的情况下工作,具有标题依赖性,没有以下kludge。 (如果不能解决这个问题,可能会有一两种其他方法可行。)
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)
答案 1 :(得分:1)
您可以通过在构建规则中收集要重建的文件,然后在链接时实际构建它们,使GNUmake执行您想要的操作:
SOURCES=file1.cpp file2.cpp file3.cpp
OBJECTS=$(SOURCES:.cpp=.o)
EXECUTABLE=myprog
all: $(EXECUTABLE)
.PHONY: build_list
build_list:
-rm -f build_list
$(OBJECTS): %.o: %.cpp | build_list
echo $< >> build_list
$(EXECUTABLE): build_list $(OBJECTS)
if [ -r build_list ]; then $(CXX) $(CXXFLAGS) -c `cat build_list`; fi
$(CXX) -o $@ $(OBJECTS)
file1.o: file1.h
file2.o: file2.h file1.h