在不干扰-MMD的情况下覆盖某些目标的隐式规则

时间:2018-07-12 02:32:12

标签: makefile gnu-make

假设我有一个简单的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/中对象的隐式规则而又不会丢失依赖项?

1 个答案:

答案 0 :(得分:1)

您可以基于每个目标定义或修改make变量(请参见GNU make documentation):

$(TEST_OBJS): CXX_FLAGS += -Itest

注意:

  • 您不应使用相同的CXX_FLAGS进行编译和链接。选项是不同的。例如,您没有将-I...选项传递给链接器。使用LDFLAGS进行链接。
  • 您的Makefile使用CXXFLAGSCXX_FLAGS。您的问题中有错别字吗?将选项传递给C ++编译器的标准make变量是CXXFLAGS,而不是CXX_FLAGS