Makefile 中的括号 $() 和大括号 $ 语法有啥区别?
Posted
技术标签:
【中文标题】Makefile 中的括号 $() 和大括号 $ 语法有啥区别?【英文标题】:What's the difference between parenthesis $() and curly bracket $ syntax in Makefile?Makefile 中的括号 $() 和大括号 $ 语法有什么区别? 【发布时间】:2014-09-30 21:03:24 【问题描述】:用$var
和$(var)
语法调用变量有什么不同吗?例如,变量将被扩展的方式或其他什么?
【问题讨论】:
我有一个模糊的回忆,在 make 的一些早期版本中,只有括号 ($(...)) 会在 make 中扩展,而 not 大括号 ( $...)。然后可以将带有大括号的变量用于将由 shell 扩展的操作中;在某些情况下,这种区别可能是相关的。 【参考方案1】:没有区别——它们的意思完全相同(在 GNU Make 和 POSIX make 中)。
我认为$(round brackets)
看起来更整洁,但这只是个人喜好。
(其他答案指向 GNU Make 文档的相关部分,请注意,您不应在单个表达式中混合语法)
【讨论】:
我在 make 中使用$()
以避免在 make 和 shell 变量之间造成混淆(比已经存在的更多)。 GNU Make documentation on variable references.
感谢用户 @Eloy 建议扩展此答案,尽管我拒绝了他们的纲要,而只是简单地指出其他答案中有价值的额外点。
有些工具可能不尊重它们的相同性。 IntelliJ IDEA 将 deploy: $DEPS
突出显示为我的语法错误,但将 deploy: $(DEPS)
显示为正确,即使在 make
中调用时两种拼写具有相同的效果。
ifeq
条件要求使用圆括号进行相等检查。您不能在该行上安全地使用花括号。因此,我倾向于$(round brackets)
。【参考方案2】:
来自GNU make
文档状态的Basics of Variable References section 没有差异:
要替换变量的值,请写一个美元符号,后跟 括号或大括号中的变量名称:
$(foo)
或$foo
是对变量 foo 的有效引用。
【讨论】:
【参考方案3】:正如已经正确指出的那样,没有区别但请注意不要混合使用这两种分隔符,因为这可能会导致像 GNU make example by unomadh 这样的神秘错误。 p>
来自the GNU make manual on the Function Call Syntax(强调我的):
[…] 如果参数本身包含其他函数调用或变量引用,则对所有引用使用相同类型的分隔符是最明智的;写
$(subst a,b,$(x))
,而不是$(subst a,b,$x)
。这是因为它更清晰,并且因为只匹配一种类型的分隔符才能找到引用的结尾。
【讨论】:
【参考方案4】:如果您设置了相应的环境变量,则 $ 样式允许您在 shell 中测试 make 规则,因为这与 bash 兼容。
【讨论】:
【参考方案5】:其实,好像还挺不一样的:
, = ,
list = a,b,c
$(info $(subst $(,),-,$(list))_EOL)
$(info $(subst $,,-,$(list))_EOL)
输出
a-b-c_EOL
md/init-profile.md:4: *** unterminated variable reference. Stop.
但到目前为止,我仅在 $... 中的变量名包含逗号时才发现这种差异。我首先认为 $... 将逗号扩展为值的一部分,但事实证明我无法以这种方式破解它。我还是不明白...如果有人有解释,我很乐意知道!
【讨论】:
基于 Edouard 的回答,其中指出 GNU make 文档声明没有区别,我猜这可能只是一个错误。 正如 Alexandre Perrin 的回答中所指出的,这两种语法不应在同一行中混合使用。【参考方案6】:如果表达式包含不平衡的括号会有所不同:
$info $subst ),(,:-)
$(info $(subst ),(,:-)))
->
:-(
*** insufficient number of arguments (1) to function 'subst'. Stop.
对于变量引用,这对于函数或包含括号的变量名(坏主意)会有所不同
【讨论】:
以上是关于Makefile 中的括号 $() 和大括号 $ 语法有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章