我有一个这样的makefile:
EXT = .cc
BLD = .build
all: bin/analyses/test
bin/analyses/test: $(BLD)/object.o
.SECONDEXPANSION:
$(DEPS): $(BLD)/%.d: src/%$(EXT) | $(BLD)/$$(dir %)
$(CXX) $(CPPFLAGS) -MM -MT '$(@:.d=.o)' $< -MF $@
$(BLD)/%.o: | $(BLD)
$(CXX) $(CXXFLAGS) -c $(filter %$(EXT),$^) -o $@
bin/%: $(BLD)/%.o | $$(dir bin/%)
$(CXX) $(LDFLAGS) $(filter %.o,$^) -o $@ $(LDLIBS)
bin/%/ $(BLD)/%/:
mkdir -p $@
如果第6行看起来是这样,则一切正常。 bin/analyses/test:
和bin/%:
规则都被使用。但是如果我将第6行更改为
bin/analyses/%: $(BLD)/object.o
仅采用bin/%:
规则。
如何使多个模式规则匹配同一目标?
答案 0 :(得分:1)
首先,Make有时会从目标中删除尾部斜杠,这可能会引起一些混乱。在这种情况下,至少在某些情况下,您将使用规则bin/%/ $(BLD)/%/: ...
(您明确打算将其用于目录)并将其用于文件。通过在其他规则中使用mkdir -p
,可以很容易地在没有显式目录规则的情况下进行操作。
第二,Make不会像处理普通规则那样组合模式规则。它找到一个模式规则并使用它。在这种相对简单的情况下,我们可以编写一条规则来完成我们想要的事情:
all: bin/analyses/test
$(BLD)/%.o:
mkdir -p $(dir $@)
$(CXX) $(CXXFLAGS) -c $^ -o $@
bin/analyses/%: $(BLD)/analyses/%.o $(BLD)/object.o
mkdir -p $(dir $@)
$(CXX) $(LDFLAGS) $^ -o $@ $(LDLIBS)
bin/%: $(BLD)/%.o
mkdir -p $(dir $@)
$(CXX) $(LDFLAGS) $^ -o $@ $(LDLIBS)
(在后两个规则中有一些明显的冗余,我不明白如何在不使makefile可读性降低的情况下进行熨烫,但它按预期工作。)