在Makefile中,一个目标是否可以有多个先决条件模式?

3
我有两个像这样的目标。
$(OBJ1): $(BUILDDIR)/%.o: $(BUILDROOT)/proto/a/%.pb.cc

$(OBJ2): $(BUILDDIR)/%.o: $(BUILDROOT)/proto/a/b/%.pb.cc

有可能将这两个东西以某种方式合并到同一个目标中吗?
1个回答

2
这是可能的,但你需要高级的制作功能(宏):
SRC := $(shell find $(BUILDROOT)/proto -type f -name '*.cc')
OBJ := $(addprefix $(BUILDDIR)/,$(patsubst %.cc,%.o,$(notdir $(SRC))))

compile: $(OBJ)

# $(1) is the cc source file
define MY_rule
$$(BUILDDIR)/$$(patsubst %.cc,%.o,$$(notdir $(1))): $(1)
    $$(CXX) -c $$(CXXFLAGS) -o $$@ $$<
endef
$(foreach f,$(SRC),$(eval $(call MY_rule,$(f))))

演示:
$ ls -R proto
proto:
dira

proto/dira:
a.cc  dirb

proto/dira/dirb:
b.cc
$ make BUILDROOT=. BUILDDIR=build compile
g++ -c -o build/a.o proto/dira/a.cc
g++ -c -o build/b.o proto/dira/dirb/b.cc   

请查看GNU make手册中关于eval函数的章节,以获取完整的解释。 最新更新:您先前删除的类似问题的评论建议使用vpath指令。这也是一个棘手的方法,并且增加了一个重要的限制条件,即所有源文件必须具有不同的基本名称。为了完整起见,并假设满足该限制条件,这里提供另一种基于vpath的解决方案:
vpath <pattern> dira dirb dirc:...

告诉make,在搜索与

是的,你说得对。在我编辑了一些文件并重新运行make之后,我的先前解决方案不起作用了。我会研究这个解决方案。谢谢! - Venkat Krishnan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接