ld:在共享库中使用-rpath、$ORIGIN(递归)

时间:2022-10-22 22:39:17

I just made a basic example of using ld's -rpath option with $ORIGIN here (see 2nd response for a working version). I'm trying to create an example where main.run links to foo.so, which in turn links to bar.so, all using rpath and $ORIGIN.

我刚刚做了一个使用ld的-rpath选项的基本示例,该选项的$ORIGIN在这里(工作版本请参阅第2响应)。我正在尝试创建一个main.run链接到foo的示例。因此,它又链接到bar。所有这些都使用rpath和$ORIGIN。

The run-time file-structure is:

运行时文件结构是:

  • project/
    • lib/
      • dir/
        • sub/
          • bar.so
          • bar.so
        • 子/ bar.so
        • foo.so
        • foo.so
      • dir /子/酒吧。所以foo.so
    • lib /目录/子/酒吧。所以foo.so
    • run/
      • main.run (failing to build)
      • main.run(未能构建)
    • run/ main.run(未构建)
  • 项目/ lib/ dir/ sub/ bar。所以foo。运行/ main.run(无法构建)

I'm building foo.so using:

我是建筑foo。所以使用:

g++ -c -o obj/foo.o src/foo.cpp -fPIC
g++ -shared -o lib/dir/foo.so obj/foo.o -Wl,-soname,foo.so -Wl,-rpath,'$ORIGIN/sub' -Llib/dir/sub -l:bar.so

Which builds fine. ldd lib/dir/foo.so can even find bar.so.

建立好。lib / ldd dir / foo。甚至可以找到barso。

However, when I try to link main.run to foo.so, foo.so can't find bar.so.

但是,当我尝试连接main.run到foo时。所以,foo。所以找不到bar.so。

I'm building main.so using:

我是建筑的主要。所以使用:

g++ -c -o obj/main.o src/main.cpp
g++ -o run/main.run obj/main.o -Wl,-rpath,'$ORIGIN/../lib/dir' -Llib/dir -l:foo.so

This works fine if another version of foo.so is used that doesn't recursively link. (Uncomment lines in make.sh, in project below, to test).

如果是另一个版本的foo,这就很好了。所以使用的不是递归链接。(取消注释行。sh,在下面的项目中测试)。

However, using the normal foo.so I'm getting this error when building main.run:

但是,使用普通的foo。所以在构建main.run时,我得到了这个错误:

/usr/bin/ld: warning: bar.so, needed by lib/dir/foo.so, not found (try using -rpath or -rpath-link)

/usr/bin/ld:警告:酒吧。所以,需要由lib / dir / foo。因此,没有找到(尝试使用-rpath或-rpath-link)

So my questions are:

所以我的问题是:

  1. Does $ORIGIN within foo.so resolve to project/lib/dir (where foo.so is) or project/run (where main.run (the executable linking it) is)?
    ldd would seem to indicate that it's project/lib/dir, which would seem to be the best way (although I tried assuming both).
  2. 并在foo $起源。因此解析为project/lib/dir(此处为foo)。是)还是项目/运行(main.run(可执行链接)?ldd似乎表明它是project/lib/dir,这似乎是最好的方法(尽管我尝试两者都假设)。
  3. How do I get these to link (while preserving relocatability) - preferably without using -rpath-link.
  4. 如何使这些链接(同时保留可重新定位)——最好不要使用- rpathlink。

You can download the project here. It's as simple as I can make it. 4 short sources and a script.
After extracting, just run ./make.sh from within project/.

你可以在这里下载这个项目。这是我能做到的最简单的。4个简短的来源和脚本。提取后,运行。sh /从内部项目。

Note: I'm using -l:. This shouldn't change anything except that the libraries are named like foo.so instead of libfoo.so, and lunk with -l:foo.so instead of -lfoo.

注意:我使用- l:。这应该不会改变任何东西,除非库被命名为foo。所以libfoo。所以,和-l一起吃午饭。所以- lfoo。

5 个解决方案

#1


7  

Well, I have something working. But I do not really understand why it works. This feels like a bug in ld to me.

我有工作要做。但我真的不明白它为什么会起作用。这对我来说就像个臭虫。

I ran strace -f -o /var/tmp/strace.out -- g++ ... for the main.run compilation. The static linker is actually trying to open files whose literal name looks like "$ORIGIN/lib/dir/sub/bar.so", among 20-30 other things. (In other words, it is looking for an actual directory named $ORIGIN. Seriously.)

我跑了strace -f -o /var/tmp/strace。——g++……main.run编译。静态链接器实际上是在尝试打开文件,其字面名称看起来像“$ORIGIN/lib/dir/sub/bar”。在20-30件事情中。(换句话说,它正在寻找一个名为$ORIGIN的实际目录。认真。)

It also appears to be searching the -rpath-link path for the name "lib/dir/sub/bar.so", not just "bar.so". I have no clue why.

它似乎还在搜索“lib/dir/sub/bar”的-rpath-link路径。所以”,不仅“bar.so”。我不知道为什么。

Anyway, this is the link for main.run that is working for me:

不管怎样,这是main.run的链接,对我有用:

g++ -o run/main.run obj/main.o -Wl,-rpath,'$ORIGIN/../lib/dir' -Wl,-rpath-link,. -Llib/dir -l:foo.so

It is identical to yours but with -Wl,-rpath-link,. inserted.

它和你的是一样的,但是有-Wl,-rpath-link,插入。

[addendum]

(附录)

OK I think I see what is going on. First, the static linker (GNU ld) simply does not honor $ORIGIN in the libraries it links against.

好的,我想我明白了。首先,静态链接器(GNU ld)不支持它链接到的库中的$ORIGIN。

Second, the behavior when you use -lbar versus -l:bar.so is very different.

第二,当你使用-lbar和-l:bar时的行为。所以是非常不同的。

Run readelf -a on foo.so. In your build, it shows a dependency on "lib/dir/sub/bar.so". This is why setting the rpath-link to "." fixes the build of main.run; it causes the static linker to search "." for "lib/dir/sub/bar.so", which it finds.

运行readelf - on fooso。在您的构建中,它显示了对“lib/dir/sub/bar.so”的依赖。这就是为什么要设置rpath-link到“。”修复main.run的构建;它使静态链接器搜索“。”,用于“lib/dir/sub/bar”。所以“,它发现。

If you rename bar.so to libbar.so, and link foo.so to use -lbar instead of -l:bar.so, the same readelf shows that foo.so now depends on "libbar.so" (with no path component). With that foo.so, you can get the main.run link to work using -Wl,-rpath-link,lib/dir/sub, as you would expect if you knew that the static linker simply does not honor $ORIGIN.

如果你重命名酒吧。libbar。所以,和链接foo。用-lbar代替-l:bar。同样的readelf显示foo。现在取决于libbar。所以(没有路径分量)foo。因此,您可以使用-Wl、-rpath-link、lib/dir/sub来获取main.run链接,如果您知道静态链接器不支持$ORIGIN,那么您可以期望得到这一链接。

By the way, I do not see the -l:bar.so syntax documented anywhere in the GNU ld manual. Out of curiosity, how did you come up with it?

顺便说一下,我没有看到-l:bar。所以在GNU ld手册的任何地方都有语法记录。出于好奇,你是怎么想到的?

Assuming it is a supported feature, this looks a bit like a bug (-l:bar.so creating a dependency on lib/dir/sub/bar.so instead of just bar.so). You can either deal with this bug by setting rpath-link to '.' for main.run, or you can rename stuff in the usual way (libxxx.so).

假设它是一个受支持的特性,这看起来有点像一个bug (-l:bar)。因此,创建对lib/dir/sub/bar的依赖项。所以不只是barso)您可以通过设置rpath-link to '来处理这个bug。“对于main.run,或者您可以按照通常的方式重命名内容(libxxxx .so)。”

#2


7  

From the ld-linux(8) manpage:

:从ld-linux(8)联机帮助页

$ORIGIN and rpath

起源和rpath美元

ld.so understands the string $ORIGIN (or equivalently ${ORIGIN}) in an rpath specification (DT_RPATH or DT_RUNPATH) to mean the directory containing the application executable. Thus, an application located in somedir/app could be compiled with gcc -Wl,-rpath,'$ORIGIN/../lib' so that it finds an associated shared library in somedir/lib no matter where somedir is located in the directory hierarchy. This facilitates the creation of "turn-key" applications that do not need to be installed into special directories, but can instead be unpacked into any directory and still find their own shared libraries.

so理解rpath规范(DT_RPATH或DT_RUNPATH)中的字符串$ORIGIN(或等效的${ORIGIN}),表示包含应用程序可执行文件的目录。因此,位于somedir/app中的应用程序可以使用gcc -Wl、-rpath、'$ORIGIN/.. ..这样它就可以在somedir/lib中找到一个关联的共享库,无论它位于目录层次结构中的哪个位置。这有助于创建“交钥匙”应用程序,这些应用程序不需要安装到特定的目录中,而是可以解压缩到任何目录中,并且仍然可以找到自己的共享库。

Thus, in answer to your first question, there's only one value for $ORIGIN: project/run.

因此,在回答第一个问题时,$ORIGIN只有一个值:project/run。

Therefore, the answer to your second question should be to use the following command to link foo.so:

因此,您的第二个问题的答案应该是使用以下命令链接foo。

g++ -shared -o lib/dir/foo.so obj/foo.o -Wl,-soname,foo.so -Wl,-rpath,'$ORIGIN/../lib/dir/sub' -Llib/dir/sub -l:bar.so

#3


5  

First, there are issues with $ sign expansion that might be causing problems. I'm building Python from source and I do this:

首先,存在可能导致问题的$ sign扩展问题。我从源代码构建Python,我这样做:

export LDFLAGS='-Wl,-rpath,\$${ORIGIN}/../lib -Wl,-rpath,\$${ORIGIN}/../usr/lib -Wl,--enable-new-dtags'

before running make. That works fine and it finds 1st level dependencies. Be careful with single and double quotes when dealing with this type of macro expansion issue.

之前运行。这很好,它找到了一级依赖性。在处理这类宏观扩展问题时,要注意单引号和双引号。

Secondly, if you run objdump -x on a binary or a library, you can see the RPATH header that it actually contains. When I run objdump -x path/to/python |grep RPATH it shows me this.RPATH ${ORIGIN}/../lib:${ORIGIN}/../usr/lib`

其次,如果您在二进制或库上运行objdump -x,您可以看到它实际包含的RPATH头。当我运行objdump -x path/to/python |grep RPATH时,它显示了这一点。起源的RPATH $ { } / . . / lib:$ {起源} / . . / usr / lib”

I suggest that you check your binaries to see what is actually in the RPATH header. Unfortunately, I don't think that this will solve your problem. This is what I see when I run ldd path/to/python:

我建议您检查二进制文件,看看RPATH头中的实际内容。不幸的是,我不认为这能解决你的问题。这就是我运行ldd路径/到/python时看到的:

libpython2.7.so.1.0 => /data1/python27/bin/../lib/libpython2.7.so.1.0 (0x00002ad369d4f000)
libpthread.so.0 => /lib/libpthread.so.0 (0x00002ad36a12f000)
libdl.so.2 => /lib/libdl.so.2 (0x00002ad36a34d000)
libutil.so.1 => /lib/libutil.so.1 (0x00002ad36a551000)
libm.so.6 => /lib/libm.so.6 (0x00002ad36a754000)
libc.so.6 => /lib/libc.so.6 (0x00002ad36a9d8000)
/lib64/ld-linux-x86-64.so.2 (0x00002ad369b2d000)

As you can see, the first level dependency is correctly handled by rpath but the second level dependencies, i.e. the dependencies of libpython, revert to system libraries. And yes, libpython has the exact same RPATH header in its binary. I found your question while googling rpath recursive to try and resolve my problem of making a distro independent package.

正如您所看到的,第一个级别的依赖是由rpath正确处理的,但是第二个级别的依赖关系,即libpython的依赖关系,又恢复到系统库。是的,libpython的二进制文件中也有相同的RPATH头。我在google rpath递归搜索时发现了您的问题,试图解决我制作一个独立于发行版的包的问题。

Added later The rpath headers only change the FIRST path searched for libraries. If they are not found there, then the loader continues to search in the normal places. ldd only lists the actual path of the library that was found as a result of the search. When I copied these libraries to the rpath directory, then everything worked. Basically there is no tidy way to find all the dependencies and copy them, just ldd -v path/to/python and some parsing of that output.

稍后添加的rpath头只会改变搜索库的第一个路径。如果没有找到它们,则加载程序继续在正常的位置进行搜索。ldd只列出搜索结果中找到的库的实际路径。当我将这些库复制到rpath目录时,一切都工作了。基本上没有找到所有依赖项并复制它们的整洁方法,只有ldd -v路径/to/python和对输出的一些解析。

#4


1  

I've been looking into this as well, and as best I can tell you need to use -rpath-link for any path that would use ORIGIN expansion. For example:

我也一直在研究这个问题,我可以告诉你,对于任何路径都需要使用-rpath-link来扩展原点。例如:

CC -shared (other flags) -R'$ORIGIN/../lib/' -o /buildpath/lib/libmylib1.so
CC -shared (other flags) -R'$ORIGIN/../lib/' -lmylib1 -o /buildpath/lib/libmylib2.so
# This fails to link 'somebinary'
CC (various flags) -R'$ORIGIN/../lib/' -lmylib2 -o /buildpath/bin/somebinary
# This works correctly
CC (various flags) -R'$ORIGIN/../lib/' -Wl,-rpath-link,/buildpath/lib/mylib1 -lmylib2 -o /buildpath/bin/somebinary
# The text above the carets to the right is a typo: ------------------^^^^^^
# I'm fairly sure it should read like this (though it has been awhile since I wrote this):
# (...) -Wl,-rpath-link,/buildpath/lib -lmylib1 (...)

ld will not expand $ORIGIN within paths specified using -rpath-link or paths it retrieves from a sub-dependency's RPATH. In the above example, mylib2 depends on mylib1; while linking somebinary, ld attempts to find mylib1 using the literal/unexpanded string $ORIGIN/../lib/ embedded in libmylib2.so. ld.so would at runtime, but not ld.

ld不会在使用-rpath-link指定的路径或从子依赖项的RPATH中检索的路径中扩展$ORIGIN。在上面的例子中,mylib2依赖于mylib1;在链接一些二进制文件时,ld尝试使用文字/未展开字符串$ORIGIN/../lib/嵌入libmylib2.so。在运行时也是如此,但没有ld。

It also won't use paths specified with -L to find the sub-dependency librar(y|ies).

它也不会使用与-L指定的路径来查找子依赖库(y|ies)。

#5


1  

Check my modified version of your make script. Basically, an additional -rpath-link without $ORIGIN should be used, since ld doesn't understand $ORIGIN at all.

检查我修改的make脚本。基本上,应该使用一个没有$ORIGIN的附加-rpath-link,因为ld根本不理解$ORIGIN。

As for your questions.

至于你的问题。

  1. $ORIGIN only works during runtime, and it's w.r.t. each library. So different shared libraries have different $ORIGIN.
  2. $ORIGIN只在运行时有效,每个库都是w.r.t.。所以不同的共享库有不同的$ORIGIN。
  3. I'm afraid the best way is to add rpath-link, and this won't affect your portability, since they are relative, and won't exist in the final executable, as I have shown in my version of make.sh
  4. 恐怕最好的方法是添加rpath-link,这不会影响您的可移植性,因为它们是相对的,并且不会存在于最终的可执行文件中,正如我的版本make.sh所示

Also, this is my own understanding of the whole linking stuff. I hope it helps.

这也是我对整个链接的理解。我希望它有帮助。

#1


7  

Well, I have something working. But I do not really understand why it works. This feels like a bug in ld to me.

我有工作要做。但我真的不明白它为什么会起作用。这对我来说就像个臭虫。

I ran strace -f -o /var/tmp/strace.out -- g++ ... for the main.run compilation. The static linker is actually trying to open files whose literal name looks like "$ORIGIN/lib/dir/sub/bar.so", among 20-30 other things. (In other words, it is looking for an actual directory named $ORIGIN. Seriously.)

我跑了strace -f -o /var/tmp/strace。——g++……main.run编译。静态链接器实际上是在尝试打开文件,其字面名称看起来像“$ORIGIN/lib/dir/sub/bar”。在20-30件事情中。(换句话说,它正在寻找一个名为$ORIGIN的实际目录。认真。)

It also appears to be searching the -rpath-link path for the name "lib/dir/sub/bar.so", not just "bar.so". I have no clue why.

它似乎还在搜索“lib/dir/sub/bar”的-rpath-link路径。所以”,不仅“bar.so”。我不知道为什么。

Anyway, this is the link for main.run that is working for me:

不管怎样,这是main.run的链接,对我有用:

g++ -o run/main.run obj/main.o -Wl,-rpath,'$ORIGIN/../lib/dir' -Wl,-rpath-link,. -Llib/dir -l:foo.so

It is identical to yours but with -Wl,-rpath-link,. inserted.

它和你的是一样的,但是有-Wl,-rpath-link,插入。

[addendum]

(附录)

OK I think I see what is going on. First, the static linker (GNU ld) simply does not honor $ORIGIN in the libraries it links against.

好的,我想我明白了。首先,静态链接器(GNU ld)不支持它链接到的库中的$ORIGIN。

Second, the behavior when you use -lbar versus -l:bar.so is very different.

第二,当你使用-lbar和-l:bar时的行为。所以是非常不同的。

Run readelf -a on foo.so. In your build, it shows a dependency on "lib/dir/sub/bar.so". This is why setting the rpath-link to "." fixes the build of main.run; it causes the static linker to search "." for "lib/dir/sub/bar.so", which it finds.

运行readelf - on fooso。在您的构建中,它显示了对“lib/dir/sub/bar.so”的依赖。这就是为什么要设置rpath-link到“。”修复main.run的构建;它使静态链接器搜索“。”,用于“lib/dir/sub/bar”。所以“,它发现。

If you rename bar.so to libbar.so, and link foo.so to use -lbar instead of -l:bar.so, the same readelf shows that foo.so now depends on "libbar.so" (with no path component). With that foo.so, you can get the main.run link to work using -Wl,-rpath-link,lib/dir/sub, as you would expect if you knew that the static linker simply does not honor $ORIGIN.

如果你重命名酒吧。libbar。所以,和链接foo。用-lbar代替-l:bar。同样的readelf显示foo。现在取决于libbar。所以(没有路径分量)foo。因此,您可以使用-Wl、-rpath-link、lib/dir/sub来获取main.run链接,如果您知道静态链接器不支持$ORIGIN,那么您可以期望得到这一链接。

By the way, I do not see the -l:bar.so syntax documented anywhere in the GNU ld manual. Out of curiosity, how did you come up with it?

顺便说一下,我没有看到-l:bar。所以在GNU ld手册的任何地方都有语法记录。出于好奇,你是怎么想到的?

Assuming it is a supported feature, this looks a bit like a bug (-l:bar.so creating a dependency on lib/dir/sub/bar.so instead of just bar.so). You can either deal with this bug by setting rpath-link to '.' for main.run, or you can rename stuff in the usual way (libxxx.so).

假设它是一个受支持的特性,这看起来有点像一个bug (-l:bar)。因此,创建对lib/dir/sub/bar的依赖项。所以不只是barso)您可以通过设置rpath-link to '来处理这个bug。“对于main.run,或者您可以按照通常的方式重命名内容(libxxxx .so)。”

#2


7  

From the ld-linux(8) manpage:

:从ld-linux(8)联机帮助页

$ORIGIN and rpath

起源和rpath美元

ld.so understands the string $ORIGIN (or equivalently ${ORIGIN}) in an rpath specification (DT_RPATH or DT_RUNPATH) to mean the directory containing the application executable. Thus, an application located in somedir/app could be compiled with gcc -Wl,-rpath,'$ORIGIN/../lib' so that it finds an associated shared library in somedir/lib no matter where somedir is located in the directory hierarchy. This facilitates the creation of "turn-key" applications that do not need to be installed into special directories, but can instead be unpacked into any directory and still find their own shared libraries.

so理解rpath规范(DT_RPATH或DT_RUNPATH)中的字符串$ORIGIN(或等效的${ORIGIN}),表示包含应用程序可执行文件的目录。因此,位于somedir/app中的应用程序可以使用gcc -Wl、-rpath、'$ORIGIN/.. ..这样它就可以在somedir/lib中找到一个关联的共享库,无论它位于目录层次结构中的哪个位置。这有助于创建“交钥匙”应用程序,这些应用程序不需要安装到特定的目录中,而是可以解压缩到任何目录中,并且仍然可以找到自己的共享库。

Thus, in answer to your first question, there's only one value for $ORIGIN: project/run.

因此,在回答第一个问题时,$ORIGIN只有一个值:project/run。

Therefore, the answer to your second question should be to use the following command to link foo.so:

因此,您的第二个问题的答案应该是使用以下命令链接foo。

g++ -shared -o lib/dir/foo.so obj/foo.o -Wl,-soname,foo.so -Wl,-rpath,'$ORIGIN/../lib/dir/sub' -Llib/dir/sub -l:bar.so

#3


5  

First, there are issues with $ sign expansion that might be causing problems. I'm building Python from source and I do this:

首先,存在可能导致问题的$ sign扩展问题。我从源代码构建Python,我这样做:

export LDFLAGS='-Wl,-rpath,\$${ORIGIN}/../lib -Wl,-rpath,\$${ORIGIN}/../usr/lib -Wl,--enable-new-dtags'

before running make. That works fine and it finds 1st level dependencies. Be careful with single and double quotes when dealing with this type of macro expansion issue.

之前运行。这很好,它找到了一级依赖性。在处理这类宏观扩展问题时,要注意单引号和双引号。

Secondly, if you run objdump -x on a binary or a library, you can see the RPATH header that it actually contains. When I run objdump -x path/to/python |grep RPATH it shows me this.RPATH ${ORIGIN}/../lib:${ORIGIN}/../usr/lib`

其次,如果您在二进制或库上运行objdump -x,您可以看到它实际包含的RPATH头。当我运行objdump -x path/to/python |grep RPATH时,它显示了这一点。起源的RPATH $ { } / . . / lib:$ {起源} / . . / usr / lib”

I suggest that you check your binaries to see what is actually in the RPATH header. Unfortunately, I don't think that this will solve your problem. This is what I see when I run ldd path/to/python:

我建议您检查二进制文件,看看RPATH头中的实际内容。不幸的是,我不认为这能解决你的问题。这就是我运行ldd路径/到/python时看到的:

libpython2.7.so.1.0 => /data1/python27/bin/../lib/libpython2.7.so.1.0 (0x00002ad369d4f000)
libpthread.so.0 => /lib/libpthread.so.0 (0x00002ad36a12f000)
libdl.so.2 => /lib/libdl.so.2 (0x00002ad36a34d000)
libutil.so.1 => /lib/libutil.so.1 (0x00002ad36a551000)
libm.so.6 => /lib/libm.so.6 (0x00002ad36a754000)
libc.so.6 => /lib/libc.so.6 (0x00002ad36a9d8000)
/lib64/ld-linux-x86-64.so.2 (0x00002ad369b2d000)

As you can see, the first level dependency is correctly handled by rpath but the second level dependencies, i.e. the dependencies of libpython, revert to system libraries. And yes, libpython has the exact same RPATH header in its binary. I found your question while googling rpath recursive to try and resolve my problem of making a distro independent package.

正如您所看到的,第一个级别的依赖是由rpath正确处理的,但是第二个级别的依赖关系,即libpython的依赖关系,又恢复到系统库。是的,libpython的二进制文件中也有相同的RPATH头。我在google rpath递归搜索时发现了您的问题,试图解决我制作一个独立于发行版的包的问题。

Added later The rpath headers only change the FIRST path searched for libraries. If they are not found there, then the loader continues to search in the normal places. ldd only lists the actual path of the library that was found as a result of the search. When I copied these libraries to the rpath directory, then everything worked. Basically there is no tidy way to find all the dependencies and copy them, just ldd -v path/to/python and some parsing of that output.

稍后添加的rpath头只会改变搜索库的第一个路径。如果没有找到它们,则加载程序继续在正常的位置进行搜索。ldd只列出搜索结果中找到的库的实际路径。当我将这些库复制到rpath目录时,一切都工作了。基本上没有找到所有依赖项并复制它们的整洁方法,只有ldd -v路径/to/python和对输出的一些解析。

#4


1  

I've been looking into this as well, and as best I can tell you need to use -rpath-link for any path that would use ORIGIN expansion. For example:

我也一直在研究这个问题,我可以告诉你,对于任何路径都需要使用-rpath-link来扩展原点。例如:

CC -shared (other flags) -R'$ORIGIN/../lib/' -o /buildpath/lib/libmylib1.so
CC -shared (other flags) -R'$ORIGIN/../lib/' -lmylib1 -o /buildpath/lib/libmylib2.so
# This fails to link 'somebinary'
CC (various flags) -R'$ORIGIN/../lib/' -lmylib2 -o /buildpath/bin/somebinary
# This works correctly
CC (various flags) -R'$ORIGIN/../lib/' -Wl,-rpath-link,/buildpath/lib/mylib1 -lmylib2 -o /buildpath/bin/somebinary
# The text above the carets to the right is a typo: ------------------^^^^^^
# I'm fairly sure it should read like this (though it has been awhile since I wrote this):
# (...) -Wl,-rpath-link,/buildpath/lib -lmylib1 (...)

ld will not expand $ORIGIN within paths specified using -rpath-link or paths it retrieves from a sub-dependency's RPATH. In the above example, mylib2 depends on mylib1; while linking somebinary, ld attempts to find mylib1 using the literal/unexpanded string $ORIGIN/../lib/ embedded in libmylib2.so. ld.so would at runtime, but not ld.

ld不会在使用-rpath-link指定的路径或从子依赖项的RPATH中检索的路径中扩展$ORIGIN。在上面的例子中,mylib2依赖于mylib1;在链接一些二进制文件时,ld尝试使用文字/未展开字符串$ORIGIN/../lib/嵌入libmylib2.so。在运行时也是如此,但没有ld。

It also won't use paths specified with -L to find the sub-dependency librar(y|ies).

它也不会使用与-L指定的路径来查找子依赖库(y|ies)。

#5


1  

Check my modified version of your make script. Basically, an additional -rpath-link without $ORIGIN should be used, since ld doesn't understand $ORIGIN at all.

检查我修改的make脚本。基本上,应该使用一个没有$ORIGIN的附加-rpath-link,因为ld根本不理解$ORIGIN。

As for your questions.

至于你的问题。

  1. $ORIGIN only works during runtime, and it's w.r.t. each library. So different shared libraries have different $ORIGIN.
  2. $ORIGIN只在运行时有效,每个库都是w.r.t.。所以不同的共享库有不同的$ORIGIN。
  3. I'm afraid the best way is to add rpath-link, and this won't affect your portability, since they are relative, and won't exist in the final executable, as I have shown in my version of make.sh
  4. 恐怕最好的方法是添加rpath-link,这不会影响您的可移植性,因为它们是相对的,并且不会存在于最终的可执行文件中,正如我的版本make.sh所示

Also, this is my own understanding of the whole linking stuff. I hope it helps.

这也是我对整个链接的理解。我希望它有帮助。