我试图根据this blog post上找到的模板,为C ++项目的源外构建设置Makefile。但是,出于某种原因,模式匹配目标$(BUILD_DIR)/$.cpp.o:
似乎不起作用,因为我得到的错误就像"没有规则来制作目标' build / somefile.cpp。 O'"
这是我的Makefile,其中删除了一些不必要的细节。请注意,SRCS变量是由其他变量构建的,因为最终我想使用不同的源文件集支持不同的目标,但是现在SRCS只有一个定义,可以在一行中定义。
CXX = g++
RM = rm -f
MKDIR_P ?= mkdir -p
SRC_DIR := ./src
BUILD_DIR := ./build
CPPFLAGS := -std=c++14 -g3 -O0 -Wall
LFLAGS := -L"./libraries/mutils"
INCLUDES := -I"$(SRC_DIR)/" -I"./libraries/"
LIBS := -lmutils -lpthread
OBJS = $(SRCS:$(SRC_DIR)/%=$(BUILD_DIR)/%.o)
DEPS = $(OBJS:.o=.d)
COMMON_SRCS := sourcefile1.cpp sourcefile2.cpp sourcefile3.cpp sourcefile4.cpp
COMMON_SRCS := $(addprefix $(SRC_DIR)/,$(COMMON_SRCS))
COMMON_SRCS += $(shell find $(SRC_DIR)/util -name *.cpp)
SIM_SRCS := $(shell find $(SRC_DIR)/simulation -name *.cpp)
SIM_SRCS += $(SRC_DIR)/SimulationMain.cpp
$(BUILD_DIR)/%.cpp.o: %.cpp
$(MKDIR_P) $(dir $@)
$(CXX) $(CPPFLAGS) $(INCLUDES) -c $< -o $@
SRCS = $(COMMON_SRCS) $(SIM_SRCS)
build/simulation: $(OBJS)
$(CXX) $(LFLAGS) $(OBJS) -o $@ $(LIBS)
.PHONY: clean
clean:
$(RM) -r $(BUILD_DIR)
-include $(DEPS)
如果我尝试使用make build/simulation
运行此操作,我会得到*** No rule to make target 'build/sourcefile1.cpp.o', needed by 'build/simulation'. Stop.
这是OBJS列表中的第一个文件,因此似乎Make扩展了所有变量,但后来无法匹配单个目标文件到规则。这里可能出现什么问题?
我的第一个想法是问题是BUILD_DIR中的./
,并且Make无法将build/sourcefile1.cpp.o
与规则./build/%.cpp.o : %.cpp
匹配,但如果我得到完全相同的错误,我从BUILD_DIR和SRC_DIR中删除了./
。
答案 0 :(得分:3)
问题是由这一行引起的:
$(BUILD_DIR)/%.cpp.o: %.cpp
根据左侧, %
将为sourcefile1
,因此展开的行看起来像这样,模式会被忽略:
$(BUILD_DIR)/sourcefile1.cpp.o: sourcefile1.cpp
您需要在右侧获取src/sourcefile1.cpp
才能使此规则有效。
您可以将行更改为:
$(BUILD_DIR)/%.cpp.o: $(SRC_DIR)/%.cpp
或者让对象文件的路径包含src/
(即,不要从其路径中删除$(SRC_DIR)
部分):
OBJS = $(SRCS:%=$(BUILD_DIR)/%.o)
两种解决方案都应该是等效的,它们只是调整规则的不同部分。