GNU Make 将空格转换为冒号

Posted

技术标签:

【中文标题】GNU Make 将空格转换为冒号【英文标题】:GNU Make Convert Spaces to Colons 【发布时间】:2012-05-21 05:57:44 【问题描述】:

给定一个以冒号分隔的路径列表,使用 GNU Make 获得一个以空格分隔的列表很简单:

CPATHS := /usr/bin/foo:/usr/bin/baz:/usr/bin/baz
SPATHS := $(subst :, ,$(CPATHS))

但是,我找不到相反方向的好方法。以下 hack 确实有效(至少在安装了 sed 的情况下),但我很确定仅使用 Make 的内部函数会有更好的方法来解决这个问题。

SPATHS := /usr/bin/foo /usr/bin/baz /usr/bin/baz
CPATHS := $(shell echo $(SPATHS) > tmp; sed 's/ \+/:/g' tmp; rm tmp)

【问题讨论】:

【参考方案1】:

获得文字空间的最短方法是通过$() $()。因此:

$(subst $() $(),:,$(CPATHS))

或者,为了简洁:

_=$() $()
$(subst $(_),:,$(CPATHS))

同样的技巧也适用于 cmake 的宏,这可能是一个有趣的好奇心,即 $ 是一个分隔符,但它本身没有引入空格。

【讨论】:

【参考方案2】:

这里唯一棘手的部分是定义一个文字空间:

space := $(subst ,, )

SPATHS := /usr/bin/foo /usr/bin/baz /usr/bin/baz
CPATHS := $(subst $(space),:,$(SPATHS))

【讨论】:

我更喜欢使用empty := 然后space := $(empty) $(empty)。只是更清楚一点,不依赖于副作用。但两者都可以。 酷,谢谢。我想我会使用SPACE := $(eval) $(eval) 来获取空间令牌。我在想subst 单独对单词进行操作,因此看不到它们之间的空格。 另一种选择是使用space := $(subst ,, ) 最好的答案是:SPACE := $() $() 因为它适用于每个版本的 make 并且只需要一行 :)。您的答案在 make 4.2.x 上运行良好,但在 make 4.3 上不起作用: * 警告:向后不兼容!以前使用 '+=' 附加到一个空变量会导致一个以空格开头的值。现在只有当变量已经包含一些值时才添加初始空间。同样,附加一个空字符串不会添加尾随空格。 @jakson 谢谢,我不知道。我更新了使用$(subst ,, ) 的答案。虽然您的 sn-p 也可以工作,但我怀疑它会在使用 make 启动 --warn-undefined-variables 时引起警告。

以上是关于GNU Make 将空格转换为冒号的主要内容,如果未能解决你的问题,请参考以下文章

用空格替换“:”符号(冒号)

GNU make 中的递归通配符?

使用 JSON.stringify 将冒号转换为 unicode

如何将字符串冒号分隔的列转换为 MapType?

如何将字符串冒号分隔列转换为MapType?

将 tz-offset 内没有冒号的 ISO 日期字符串转换为 XMLGregorianCalendar