makefile - 您如何在构建规则中使用(GNU)make 的“简单扩展”变量而不得到最后的定义?
问题描述
我需要编写一组复杂的规则来生成相当多的“参数化”输出文件,并认为,与其手动将它们全部展开,我可以反复“包含”一个带有规则集的模板文件和使用 (GNU)make 的工具来允许“简单扩展”的变量来避免痛苦。
(过去我一直在使用“递归扩展”变量方法,所以这对我来说是新的)
作为我认为可行的一个简单示例,我尝试将以下内容放入 Makefile
Targ:=A
Param1:=Pa
Param2:=Qa
$(Targ):
@echo expect A, get $(Targ), Target is $@. Params are $(Param1) and $(Param2)
Targ:=B
Param1:=Pb
Param2:=Qb
$(Targ):
@echo expect B, get $(Targ), Target is $@. Params are $(Param1) and $(Param2)
Targ:=C
Param1:=Pc
Param2:=Qc
$(Targ):
@echo expect C, get $(Targ), Target is $@. Params are $(Param1) and $(Param2)
最终的计划是用包含许多不同规则的包含文件替换规则,每个规则都引用各种“参数”变量。
然而,我得到的是...
prompt> make A
expect A, get C, Target is A. Params are Pc and Qc
prompt> make B
expect B, get C, Target is B. Params are Pc and Qc
从本质上讲,与每个规则的目标不同,每个规则的目标是获取预期的定义,每个规则的命令$(Targ)
中的, $(Param1)
, 和是使用最终定义运行的。$(Param2)
有谁知道如何防止这种情况发生,即如何强制命令在 Makefile 中遇到定义时使用它?
解决方案
简单与递归扩展在这里没有区别;无论您使用哪个,您都会看到相同的行为。GNU make 变量是全局变量,显然只能有一个值。
您必须了解何时扩展变量。该文档提供了对此的详细描述。读入 makefile 时扩展目标和先决条件,因此Targ
使用正在解析 makefile 的值。
当配方被调用时,配方会被扩展,直到所有的 makefile 都被解析并且 make 开始构建目标。在那个时候,当然变量Targ
有它的最后一个设定值。
在不知道您的 makefile 真正做什么的情况下,很难提出替代方案。一种选择是使用特定于目标的变量:
Targ := A
$(Targ): LocalTarg := $(Targ)
$(Targ):
@echo expect A, get $(LocalTarg), Target is $@
另一种选择是使用构造变量名称:
Targ := A
Targ_$(Targ) := $(Targ)
$(Targ):
@echo expect A, get $(Targ_$@), Target is $@
推荐阅读
- python-3.x - 警告安装 SqlAlchemy
- security - 在 Electron 中使用 webview 标签是否安全?
- java - 无法使用 sprint WebClient 发布请求:总是 400
- reactjs - react中外部链接重定向时如何保存和传递用户名和密码
- node.js - 如何在nodejs中开玩笑地存根/模拟方法/构造函数的参数以进行单元测试?
- excel - 抓取网站的源代码在 VDI 上不起作用
- javascript - 设置动态值 css 动画 stroke-dashoffset
- android - React-Native,Pdf 在 android 模拟器上显示,但在实际的 android 设备上出现错误
- javascript - 使用 javascript + octave 进行音频分析,“audiocontext 解码器和 octave 之间的通道数据结果不同”?
- sql - 如何通过 JAVA 或 SQL 查询根据系统(Windows)格式转换日期格式?