makefile - 从使用 eval 设置的变量定义生成文件目标
问题描述
我必须定义一个包含版本号的目标,该版本号又是从 git 检索的某个文件(此目标的先决条件)中提取的。
我首先尝试的是设置一个变量eval
并在名称中使用它,就像这样。
version_file:
@checkout
version: version_file
@eval version := get version from version_file
file_$(version):
@echo file_$(version)
final_target: file_$(version)
@echo $@
这行不通:make
在第一遍中读取 makefile 并没有找到变量dynamic_prerequisite
,因此创建的目标只是命名为file_
。
但是当我尝试动态创建规则时,在设置变量之后,像这样
...
define rule_file_version
file_$(version):
@echo version: $@
endef
version: version_file
@eval version := get version from version_file
$(eval $(rule_file_version))
...这给了我错误信息:
makefile:12: *** 无法在配方中定义先决条件。
当然,我不能将eval
目标移到配方之外,因为我遇到了和以前一样的问题。
有没有办法实现我想要的gnu make
?
解决方案
我发现问题可以通过使用构造的包含文件来解决。
为了构建文件本身,我创建了一个简单的 shell 脚本,它将动态设置的变量作为参数:
#!/bin/bash
read -r -d '' MAKE <<EOF
file_$1:
@echo version: $1
final_target: file_$1
@echo final_target: $1
EOF
echo "$MAKE" > rules.mk
这用于makefile
创建包含的 makefile rules.mk
,如下所示:
version_file:
@checkout
version: version_file
@eval version := get version from version_file
rules.mk: version
$(shell ./create_rules_mk.sh $(version))
-include rules.mk
当我运行make final_target
它时,它会根据需要创建rules.mk
。
对我来说,最重要的是,目标名称本身依赖于其他目标必须使用生成文件的动态创建。
推荐阅读
- splunk - 如何使用 splunk 监控 WAN 中的数据流量?
- android - 后台代码不再在 Android 10 中执行
- c# - 帧数标签出现在数据集中但不在 DICOMDIR C# 中
- redis - 使用 Redis 作为缓存的 ApolloServer
- amazon-web-services - SSH 隧道 - 在远程端查找端口转发
- joomla - Joomla 4 - 与多个父母一起查看
- julia - 优化对大字符串的循环以减少分配
- sql-server - 在两个不同的数据库之间同步表
- firebase - 为什么 Firestore 无法进行聚合操作?
- flutter - 需要在使用 Flutter 的 OnDestroy 应用程序上执行一些代码