假设我有一个简单的Makefile
,如下所示:
CXXFLAGS+=-O3 -Wall -pednatic -MMD -Isrc
SRCS=$(shell find src -name '*.cpp')
OBJS=${SRCS:.cpp=.o}
TEST_SRCS=$(shell find test -name '*.cpp')
TEST_OBJS=${TEST_SRCS:.cpp=.o}
all: bin/product
bin/product: $(OBJS)
$(CXX) ($CXX_FLAGS) -o $@ $^
test: test/runner
./test/runner
test/runner: $(TEST_OBJS) $(OBJS)
$(CXX) ($CXX_FLAGS) -o $@ $^
-include ${OBJS:.o=.d}
-include ${TEST_OBJS:.o=.d}
.PHONY: all test
这里要注意的重要一点是,我有两个单独的二进制目标(一个使用src/
中的对象进行生产,另一个使用src/
和test/
中的对象进行测试)。我只想为测试中的目标(CXXFLAGS
,也为test/runner
)更改test/foo_test.o
,而不是src
中的目标。我当然可以定义自己的规则来覆盖隐式规则(请注意添加的-Itest
,这是我希望编译测试方式的众多差异之一):
test/%.o: test/%.cpp
$(CXX) $(CXXFLAGS) -Itest -c -o $@ $^
但是不幸的是,这会覆盖*.d
创建的包含的-MMD
文件中的依赖项。例如test/foo_test.d
:
test/foo_test.o: test/foo_test.cpp src/foo.o
有什么方法可以覆盖test/
中对象的隐式规则而又不会丢失依赖项?
答案 0 :(得分:1)
您可以基于每个目标定义或修改make变量(请参见GNU make documentation):
$(TEST_OBJS): CXX_FLAGS += -Itest
注意:
CXX_FLAGS
进行编译和链接。选项是不同的。例如,您没有将-I...
选项传递给链接器。使用LDFLAGS
进行链接。CXXFLAGS
和CXX_FLAGS
。您的问题中有错别字吗?将选项传递给C ++编译器的标准make变量是CXXFLAGS
,而不是CXX_FLAGS
。