makefile - Makefile 变量扩展未按预期工作
问题描述
我想根据变量列表自动创建生成文件规则(在我的用例中,我想有选择地构建一组文件)。但是我在扩展名称时遇到问题。
我创建了以下 Makefile 作为示例(M(not)WE):
FILES_A=a1 a2 a3
FILES_B=b1 b2 b3
TARGET_BASES=A B
define test
FILES := $(value FILES_$1)
build_$1: $(addsuffix .ext, $(FILES))
build_dummy_$1: $(FILES)
endef
$(foreach target, $(TARGET_BASES), $(eval $(call test,$(target))))
运行make -p|grep build
我希望得到以下输出:
[...]
build_A: a1.ext a2.ext a3.ext
build_dummy_A: a1 a2 a3
build_B: b1.ext b2.ext b3.ext
build_dummy_B: b1 b2 b3
但相反我得到
build_A:
build_dummy_A:
build_B: a1.ext a2.ext a3.ext
build_dummy_B: a1 a2 a3
同时我不知道为什么。有人可以阐明我在这里缺少的东西吗?
解决方案
理解围绕 eval 和 call 的扩展可能会令人困惑。这就是为什么它们被认为是高级项目,只有在没有更容易理解的设施能够解决问题的情况下才应该使用它们。
这里的问题是您的宏test
首先由call
函数评估,然后再传递给eval
函数。在该评估期间,该变量FILES
尚未设置,因此它解析为上次运行 eval 时设置的任何内容:第一次评估为空,第二次评估为第一次运行后的结果,等等.
基本上规则是,您想要扩展的任何变量都call
应该只有一个$
,并且您想要扩展的任何变量都eval
需要使用$$
. 所以:
define test
FILES := $$(value FILES_$1)
build_$1: $$(addsuffix .ext, $$(FILES))
build_dummy_$1: $$(FILES)
endef
推荐阅读
- docker - Nginx 配置问题:k8s 集群上的 vue.js 历史模式
- python - 使用 python 添加 bfd 对等体
- python - AttributeError:“int”对象没有属性“encode”HDF5
- python - PyGame 检测碰撞,即使它们没有发生
- javascript - 如何在 handlebars.java 的同一页面上创建部分或 CTA 的链接或 ID?
- java - 同一应用程序中的 Spring Boot 管理客户端和服务器
- typescript - Typescript 可扩展类型定义
- php - WooCommerce:仅限特定类别免费送货超过 500 英镑
- woocommerce - 在 WooCommerce 中的某个订单状态后自动执行“按钮按下”的操作
- bash - Bash/shell 脚本:带有 URL 的表达式中的 bash 语法错误