在GNU make中一次编译多个**已更改的**源文件

Igo*_*sky 8 c gcc nmake makefile

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

考虑这个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 $@ $<
Run Code Online (Sandbox Code Playgroud)

如果我更改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 
Run Code Online (Sandbox Code Playgroud)

我想拥有的是:

g++ -c file1.cpp file2.cpp
g++ -o myprog file1.o file2.o file3.o 
Run Code Online (Sandbox Code Playgroud)

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

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

现在我们正在使用并行构建(make -j),但它有自己的问题,VC++编译器在一次调用模式下运行得更好,所以我更喜欢使用它.

Bet*_*eta 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)
Run Code Online (Sandbox Code Playgroud)

编辑:
我很惊讶这个解决方案有效——我对 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)
Run Code Online (Sandbox Code Playgroud)