jamplus:link 命令行对于 osx 来说太长了

jamplus: link command line too long for osx

我正在使用 jamplus 构建供应商的跨平台项目。 osx,C 工具的命令行(通过 clang 提供给 ld)太长。

响应文件是对太长命令行的经典回答:jamplus 在手册中指出可以即时生成它们。

example in the manual 看起来像这样:

actions response C++
{
    $(C++) @@(-filelist @($(2)))
}

快到了!如果我专门吹出 C.Link 命令,像这样:

actions response C.Link
{
    "$(C.LINK)" $(LINKFLAGS) -o $(<[1]:C) -Wl,-filelist,@($(2:TC)) $(NEEDLIBS:TC) $(LINKLIBS:TC))
}

在我的 jamfile 中,我得到了传递给 linker 的我需要的命令行,但是响应文件不是换行符终止的,所以 link 失败了(osx ld 需要以换行符分隔的条目)。

  1. 有没有办法扩展用换行符连接的 jamplus 列表?我试过使用连接扩展 $(LIST:TCJ=\n) 但没有成功。 $(LIST:TCJ=@(\n)) 也不行。如果我能做到这一点,生成的文件应该是正确的。
  2. 如果没有,我可以使用什么 jamplus 代码来覆盖 clang 的 link 命令,并从列表中动态生成内容?我正在寻找处理这个问题的侵入性最小的方法 - 理想情况下,直接 modifying/overriding 工具,而不是在需要 link 的地方添加新的间接目标 - 因为它是我们供应商的代码库,尽可能少的编辑可能是需要的。
  1. 我放弃了在字符串连接中使用转义换行符和其他语言特定字符的尝试。也许有一个很棒的方法可以做到这一点,但发现起来太棘手了。

  2. 对多个临时文件使用多步 shell 命令。

对于 jamplus(可能还有其他 jam 变体),花括号之间的 actions response {} 部分成为内联 shell 脚本。响应文件语法 @(<value>) returns 可以在 shell 脚本中分配的文件名,内容设置为 <value>.

因此,代码如下:

actions response C.Link
{
    _RESP1=@($(2:TCJ=#)#$(NEEDLIBS:TCJ=#)#$(LINKLIBS:TCJ=#))
    _RESP2=@()
    perl -pe "s/[#]/\n/g" < $_RESP1 > $_RESP2
    "$(C.LINK)" $(LINKFLAGS) -o $(<[1]:C) -Wl,-filelist,$_RESP2
}

创建一对临时文件,分配给 shell 变量名称 _RESP1_RESP2。路径 _RESP1 处的文件被分配了扩展序列的内容,并以 # 字符连接。搜索和替换是用一个 perl 一行到 _RESP2 中完成的。 link 按计划进行,jamplus 清理了中间文件。

我无法使用像 :;\n 这样的字符来执行此操作,但是 # 只要没有相邻的空格就可以工作。不完全满意,但继续前进。

您要查找的语法是:

newLine = "
" ;

actions response C.Link
{
    "$(C.LINK)" $(LINKFLAGS) -o $(<[1]:C) -Wl,-filelist,@($(2:TCJ=$(newLine))) $(NEEDLIBS:TC) $(LINKLIBS:TC))
}

为了清楚起见(我不确定 Whosebug 将如何格式化上面的内容),newLine 变量应该通过键入来定义:

newLine = "" ;

然后将克拉放在两个引号之间并按回车键。您可以对某些其他字符使用相同的技术,即

tab = "    " ;

同样,从 newLine = "" 开始,然后将 carat 放在引号之间并点击制表符。在上面实际上是 4 个空格是错误的,但希望你明白了。另一个有用的是:

dollar = "$" ;

最后一个很有用,因为 $ 通常用于指定变量,因此当您实际想要指定美元文字时,拥有一个美元变量很有用。对于它的价值,我正在使用的 Jambase(我正在使用的 JamPlus 附带的那个)具有:

SPACE = " " ;
TAB = " " ;
NEWLINE = "
" ;

第 28 行附近...