makefile - 是否可以在 Makefile 的同一目标中具有多个先决条件模式?
问题描述
我有两个这样的目标
$(OBJ1): $(BUILDDIR)/%.o: $(BUILDROOT)/proto/a/%.pb.cc
$(OBJ2): $(BUILDDIR)/%.o: $(BUILDROOT)/proto/a/b/%.pb.cc
是否有可能以某种方式将这两者结合到同一个目标中?
解决方案
这是可能的,但您将需要高级制作功能(宏):
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 在搜索匹配的文件时<pattern>
,它必须探索列出的目录。所以,让我们:
计算所有源文件和相应目标文件的基本名称:
SRC := $(notdir $(shell find $(BUILDROOT)/proto -type f -name '*.cc')) OBJ := $(addprefix $(BUILDDIR)/,$(patsubst %.cc,%.o,$(SRC)))
获取所有目录的列表
$(BUILDROOT)/proto
:DIR := $(shell find $(BUILDROOT)/proto -type d)
现在,我们准备好使用该
vpath
指令了:vpath %.cc $(DIR)
而已。总而言之,以下应该有效:
SRC := $(notdir $(shell find $(BUILDROOT)/proto -type f -name '*.cc'))
DIR := $(shell find $(BUILDROOT)/proto -type d)
OBJ := $(addprefix $(BUILDDIR)/,$(patsubst %.cc,%.o,$(SRC)))
vpath %.cc $(DIR)
compile: $(OBJ)
$(BUILDDIR)/%.o: %.cc
$(CXX) -c $(CXXFLAGS) -o $@ $<
推荐阅读
- vb.net - 在 vb.Net 中 FindInFiles 搜索的字节位置
- android - 改造 2 从 android 客户端空请求正文发送到具有 200 状态的服务器中的弹簧启动,而在邮递员中它工作正常
- windows - 是否有一个简单的 kotlin 编译器适用于没有额外臃肿 IDE 的 Windows?
- javascript - 来自弹出窗口的 Instagram 基本显示 API oauth 授权
- arrays - 如何在 x86 中保留数组或字符串
- php - 显示服务器日期/时间格式的 PHP 动态表
- reactjs - 在 UseEffect 中为两个 API 调用设置 Promise
- django - 检测相关模型或在 django 中创建
- json - 为什么我在 Swift 中的 JSON 代码无法解析?
- elasticsearch - 基于 Elasticsearch 中的现有字段创建字段