我不理解-Wl,-rpath -Wl的含义。

320

为方便起见,我在下面添加了相关的man页。

首先是我的(误)理解:如果我需要使用,分隔选项,那么第二个 -Wl 不是另一个选项,因为它出现在,之前,这意味着它是-rpath选项的参数。

我不明白-rpath如何有一个-Wl,.的参数!

在我的理解中,这是有道理的:

-Wl,-rpath .

这应该使用-rpath链接器选项和当前目录参数。


man gcc:

-Wl,option

将选项作为选项传递给链接器。如果选项包含逗号,则在逗号处将其拆分为多个选项。您可以使用此语法将参数传递给选项。例如,-Wl,-Map,output.map-Map output.map传递给链接器。当使用GNU链接器时,您也可以通过`-Wl,-Map = output.map'获得相同的效果。

man ld:

-rpath = dir

将目录添加到运行时库搜索路径中。在使用共享对象链接ELF可执行文件时使用此选项。所有-rpath参数都被串联并传递给运行时连接器,它们用于在运行时定位共享对象。在链接中显式包含的共享对象需要使用共享对象时,也会使用-rpath选项。


3
标题末尾不是缺少了句点字符吗? - Celdor
是的,我怀疑SO软件可能已经将其删除了。 - i336_
4个回答

374

-Wl,xxx选项用于gcc,将逗号分隔的标记作为以空格分隔的参数列表传递给链接器

gcc -Wl,aaa,bbb,ccc

最终变成链接器调用

ld aaa bbb ccc

在您的情况下,您想要说"ld -rpath .",因此您将此传递给gcc作为-Wl,-rpath,. 或者,您可以指定-Wl的重复实例:

gcc -Wl,aaa -Wl,bbb -Wl,ccc
请注意,aaa 和第二个 -Wl 之间没有逗号。
或者,在您的情况下,为 -Wl,-rpath -Wl,.

6
我明白了,传递给链接器的选项或参数没有区别,它们只是字符串。所以第二个“-Wl”是多余的!谢谢 :) - Blub
32
@Blub:这并不是多余的!它是一种备选形式,你 要么 写成 -Wl,-rpath,. 要么 写成 -Wl,-rpath -Wl,.。必须选其中一种,不能省略任何内容。 - Kerrek SB
如果您想指定多个rpath,语法会是什么样子?-Wl,-rpath -Wl,. -Wl,-rpath -Wl,/my/lib - Hintron
2
@Hintron:是的,或者-Wl,-rpath,dir1,-rpath,dir2,或者-Wl,-rpath=dir1,-rpath=dir2 - Kerrek SB
3
如果有人像我一样浪费了几分钟来搞清楚这个问题,我想提醒大家一下:在 -W 后面的字符是小写字母 'L',而不是数字 '1'!哎呀! - Jack Kelly
显示剩余2条评论

76

你也可以写成

-Wl,-rpath=.
为了消除那个烦人的空格。这比添加额外逗号更易读(它正是传递给ld的内容)。

3
从 https://gcc.gnu.org/onlinedocs/gcc/Link-Options.html#Link-Options 中的 -Wl,option 选项下可以看出:"_当使用GNU链接器时_,您也可以使用 -Wl,-Map=output.map 实现相同的效果。" 对我来说,这似乎表明,如果你使用的是除了GNU链接器以外的其他链接器,则 = 语法可能不被支持。 - Hintron
你救了我的一天。我看到的其他建议都说要使用-rpath='$ORIGIN',但这对我从来没有起作用,而-rpath=.却完美地解决了问题。+1给你。 - leisheng

45

还有一件事。你可能也需要指定-L选项 - 例如:

-Wl,-rpath,/path/to/foo -L/path/to/foo -lbaz

否则你可能会遇到类似这样的错误

ld: cannot find -lbaz

13

手册已经表述得很明确了。如果你想要向链接器传递两个参数(-rpath.),你可以这样写:

-Wl,-rpath,.
或者,另一种选择。
-Wl,-rpath -Wl,.
你建议的参数-Wl,-rpath .在我看来是没有意义的。gcc怎么知道你的第二个参数(.)应该传递给链接器而不是正常解释?唯一能够知道的方法是如果它拥有所有可能的链接器参数的内部知识,这样它就知道-rpath需要其后跟一个参数。

不难想象,gcc会分析参数,如果某些参数没有意义,它会自动进行分组。 - Blub
1
@Blub 如果 . 是对于 gcc 来说一个无意义的参数,那么这个(9岁时)的争论就有道理了。但事实并非如此,你可能会因为各种有效的原因将 . 作为参数传递给 GCC 本身。这就是为什么,除非在其前面加上 -Wl, 重定向标志引入它,否则 . (或任何其他参数)不会被包括在链接器命令行中的原因,因为在没有显式的 -Wl, 或其他子命令重定向的情况下,自然而然地 gcc 将默认消耗每个参数。 - FeRD

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接