gnu 在字符串中间制作哈希符号

gnu make hash symbol in the middle of string

我试图在执行时打印出 make 文件的 perforce 文件版本。我正在使用 $Id$ 标签,它扩展为 $Id: //repository/path/check.make#6 $ 等,我想将 //repository/path/check.make#6 打印到一个文件(当前使用 echo)。我不知道如何让 make 将 # 作为字符串的一部分而不是评论的开头。我试过了:

str1 = $(subst \#,\\#,'$Id: //repository/path/check.make#6 $')

和其他变体,但我不断得到:

 unterminated call to function `subst': missing `)'.  Stop.

如果您能提供您想要的完整示例,将会有所帮助。我真的不明白你为什么要 subst 一个带有反斜杠散列的散列。如果您向我们展示了一个完整的示例,包括您如何获取字符串以及您想要对变量做什么 ar1,我们实际上可以给您建议。

但是,在 GNU make 中使用散列的方法是将它们放入变量中:

HASH := \#

$(info HASH = $(HASH))

我只能说这么多,没有更多信息。

预计到达时间

是的,我非常熟悉关键字扩展...它起源于 SCCS/RCS 当天:)。

我明白了,你的意思是,你想将 $Id$ 放入你的 makefile 中,然后当你的 makefile 被签出时,该值将被替换。我不清楚。

很抱歉,您想做的事几乎不可能。问题是您无法转义 makefile 中的值,因为您没有将值写入 makefile,Perforce 是。 Perforce 并没有逃避它。

你只有两个选项,我可以看到:

首先,不要试图将其放入 make 变量中。有很多方法可以做到这一点,这取决于你真正想要什么。一种方法是创建一个包含 const char* foo = "$Id$"; 的头文件并替换它。如果你真的想要makefile的ID,但你只需要在某个recipe中,你可以直接把它放到那个recipe中:

myrecipe: ; echo '$$Id$$'

(我不确定这里的 $$ 技巧是否有效,这取决于 Perforce 如何替换东西...如果不行,你可以使用 echo '$Id$x' 你会输美元符号,但保留其余部分)。

唯一的其他选择是将您的 GNU make 版本升级到最新版本 (4.3)。在该版本中,修复了 $(shell ...) 函数中散列字符的一些错误处理,这意味着您可以使用:

var1 := $(shell echo '$$Id$$')

它会起作用(同样的注意事项和解决方案,对于 $$ 如上所述)。

您不能在 make 赋值中使用未转义的文字 # 并且不将其解释为注释字符。但是作为一种 hack,您可以让 shell 从当前 Makefile.

中提取此标记
# $Id: //repository/path/check.make#6 $
str1 := $(shell sed '/[$$]Id[$$:]/!d;s/^\# [$$]Id: \(.*\) [$$].*//' Makefile)

sed 脚本通过正则表达式在 Makefile 本身 中查找 $Id$$Id: 标记 匹配自身;双美元符号是您在 Makefile 中放置文字美元符号的方式。它提取字段的内容,make 将输出分配给 str1。因为在分配变量的代码中没有文字 #,所以不需要进一步转义。

演示:https://ideone.com/hWjnCp

这需要 GNU Make,但这显然是您已经在使用的。 (请将此类问题明确标记为 。)

也许我没听懂你的意思,但以下适用于外部演员替换 $Id$ 而不转义:

define PERFORCE_ID
$Id$
endef

PERFORCE_ID := $(word 2,$(value PERFORCE_ID))
$(info $(PERFORCE_ID))

作为测试,我自己简单地输入了 Perforce 的文本替换:

define PERFORCE_ID
$Id: //repository/path/check.make#6 $                                                                                                                                                      
endef

PERFORCE_ID := $(word 2,$(value PERFORCE_ID))                                                                                                                                              
$(info Perforce id is: $(PERFORCE_ID))

输出:

Perforce id is: //repository/path/check.make#6