是否有一种简单的方法可以将单个配方应用于多个模式规则?
考虑这个目录结构
|- src
| - file1.cpp
|- test
| - file2.cpp
| - file3.cpp
| - metrics
| - file4.cpp
| - file5.cpp
我想编写一个模式规则来编译测试目录中的所有.cpp文件。这就是我现在所拥有的:
$(OBJS)/%.o: test/%.cpp
@mkdir -p $(OBJS)
g++ $(FLAGS) $(CPPFLAGS) -c $< -o $@
$(OBJS)/%.o: test/metrics/%.cpp
@mkdir -p $(OBJS)
g++ $(FLAGS) $(CPPFLAGS) -I test -c $< -o $@
TEST_CPP := $(wildcard test/*.cpp) $(wildcard test/**/*.cpp)
TEST_OBJ := $(addprefix $(OBJS)/,$(notdir $(TEST_CPP:.cpp=.o)))
$(BIN)/testRunner: $(TEST_OBJ)
@mkdir -p $(BIN)
g++ $(FLAGS) $(CPPFLAGS) $^ $(LIBS) -o $@
我想避免重复目标文件的配方。我想解决方案看起来像这样:
$(OBJS)/%.o: test/%.cpp
$(OBJS)/%.o: test/metrics/%.cpp
@mkdir -p $(OBJS)
g++ $(FLAGS) $(CPPFLAGS) -c $< -o $@
(目前,objs目录是平的;但是,如果简化了makefile,我就不会有重复源目录结构的问题。)
答案 0 :(得分:3)
没有办法做你想做的事。最接近的是将配方放入变量并在每个配方中使用相同的变量,如下所示:
define BUILD_O
@mkdir -p $(OBJS)
g++ $(FLAGS) $(CPPFLAGS) -c $< -o $@
endef
$(OBJS)/%.o : test/%.cpp
$(BUILD_O)
$(OBJS)/%.o : test/metrics/%.cpp
$(BUILD_O)
作为替代方案,因为您希望所有对象都进入同一目录但从不同目录中查找源,您可以使用VPATH而只编写单个模式规则,如下所示:
VPATH = test test/metrics
$(OBJS)/%.o : %.cpp
@mkdir -p $(@D)
g++ $(FLAGS) $(CPPFLAGS) -c $< -o $@
我强烈建议您重新编写makefile以使用标准变量名称;对于C ++编译器选项,使用$(CXX)
,而不是g++
,而$(CXXFLAGS)
,而不是$(FLAGS)
。
修改强>
如果您需要自定义标记,那么通常的方法是通过target-specific variables或通过constructed macro names
特定于目标的变量如下所示:
test: $(test_targets)
test: FLAGS += -Dtest
production: $(production_targets)
production: FLAGS += -Dproduction
然后当您运行make test
时,您会添加-Dtest
;当您运行make production
时,您将获得-Dproduction
。但是这里有一些问题:如果你运行make myfoo.o
,那么你就不会添加这些(参见文档)。
构造的宏名称如下所示:
test_FLAGS = -Dtest
production_FLAGS = -Dproduction
rootdir = $(firstword $(subst /, ,$1))
VPATH = test test/metrics production production/widgets
$(OBJS)/%.o : %.cpp
@mkdir -p $(@D)
g++ $(FLAGS) $(CPPFLAGS) $($(call rootdir,$(<D))_FLAGS) -c $< -o $@