我正在尝试将包含特殊字符串 $ORIGIN 的 RPATH 链接到使用 GCC 和 Code::Blocks IDE 构建的可执行文件中。我已经指定
-Wl,-R$ORIGIN
在项目的链接器选项中,但到 GCC 的命令行输出是错误的(为了清楚起见已删除):
g++ -Wl,-R
为 Code::Blocks 指定此参数的正确方法是什么?
我正在尝试将包含特殊字符串 $ORIGIN 的 RPATH 链接到使用 GCC 和 Code::Blocks IDE 构建的可执行文件中。我已经指定
-Wl,-R$ORIGIN
在项目的链接器选项中,但到 GCC 的命令行输出是错误的(为了清楚起见已删除):
g++ -Wl,-R
为 Code::Blocks 指定此参数的正确方法是什么?
决定制作令牌 $ORIGIN 的人是一个邪恶的混蛋,他应该在程序员地狱中占有一席之地。由于 '$' 是 bash 和其他脚本语言(如 make)的特殊字符,因此除非小心转义,否则它会搞砸一切。更糟糕的是,根据您使用的构建环境,如何正确逃脱的细节可能会发生变化。
在 bash 中,您需要在 $ 前面加上一个反斜杠:
-Wl,-R\$ORIGIN
Code::Blocks 显然也将 $ 视为特殊的。然后,无论子进程控制器 Code::Blocks 发送命令以将反斜杠视为特殊的。因此,反斜杠和 $ 都需要加倍才能正确转义。因此,在 Code::Blocks 链接器设置中,您需要指定:
-Wl,-R\\$$ORIGIN
...输出:
-Wl,-R\\$ORIGIN
...到构建日志,但实际上发送了 shell:
-Wl,-R\$ORIGIN
...如上所述会产生所需的结果。
多么痛苦。
除了解决 Code:Blocks 问题的 kblucks 答案之外。对于像我这样偶然发现此页面并寻找如何使用 Make 执行此操作的人。诀窍是使用额外的 $ 符号作为转义字符并用引号将其括起来:
-Wl,-R,'$$ORIGIN/../lib'
完整的解释可以在这里: 使用 ORIGIN for a dynamic runtime library search path
如果您的可执行文件是由一个不是您创建的巨大复杂脚本环境构建的,并且您不想深入研究它,请尝试运行setenv LD_RUN_PATH='$ORIGIN/../lib'
; 如果这不起作用,一种实用的方法是为 ld 创建一个包装器:
#!/bin/sh
exec /usr/bin/ld -R '$ORIGIN/../lib' "$@"
...然后在路径上使用该存根进行构建。在实践中,可能会调用它来构建 .so 文件或其他可执行文件,因此您可能需要将其设为更复杂的脚本,以决定是否插入 RPATH。或者,在没有这个的情况下运行构建,并且使用樱桃挑选。
(这里“/usr/bin/ld”是正常运行的 ld,可能在其他地方。gcc 可能无法从路径中获取 ld,请参阅 gcc 环境变量以覆盖它。里程可能会有所不同。单次使用仅。不保证比任何其他方法都更糟糕)。