我有一个基本的,最小的makefile来编译C ++源代码;精简版本看起来像这样:
TARGET = main
OBJ = $(patsubst %.cpp,%.o,$(wildcard *.cpp))
CPPFLAGS = -std=c++11 -Wall
build: $(TARGET)
$(TARGET): $(OBJ)
@echo "$? --> $@"
g++ $(CPPFLAGS) -o $@ $?
@echo
%.o: %.cpp
@echo "$< --> $@"
g++ $(CPPFLAGS) -c $<
@echo
从头开始构建时,一切都按预期工作:
clock.cpp --> clock.o
g++ -std=c++11 -Wall -c clock.cpp
main.cpp --> main.o
g++ -std=c++11 -Wall -c main.cpp
clock.o main.o --> main
g++ -std=c++11 -Wall -o main clock.o main.o
在更改其中一个源文件后,make
会重建相应的目标文件,但由于某种原因,在尝试链接时会跳过现有(未更改的)目标文件(clock.o --> main
而不是{{ 1}}):
clock.o main.o --> main
再次运行clock.cpp --> clock.o
g++ -std=c++11 -Wall -c clock.cpp
clock.o --> main
g++ -std=c++11 -Wall -o main clock.o
,而不更改任何文件时,链接按预期工作:
make
这种行为的原因是什么,以及如何防止这种行为?
我在i686 Linux 4.4上运行GNU Make 4.1
答案 0 :(得分:2)
您在g++ $(CPPFLAGS) -o $@ $?
食谱中使用了错误的自动变量。
https://www.gnu.org/software/make/manual/html_node/Automatic-Variables.html:
<强> $吗
比目标更新的所有先决条件的名称, 它们之间有空格。
因此,Make完全按照您的要求执行操作:将主要目标与所有更新的先决条件相关联,并跳过未触及的先决条件。
g++ $(CPPFLAGS) -o $@ $^
食谱将解决问题。