问题描述
注意:下面是完整的工作示例。原来的问题如下:
我在使用ld的 -rpath
参数时遇到问题, $ ORIGIN
。
因为我找不到完整的示例,所以我想我会自己写一个,以便我和其他人可以稍后使用它。一旦我得到它的工作,我会整理它。
我下载该项目
文件结构(构建之前):
项目/
src /
foo.cpp
main.cpp
make.sh
project / src / foo.cpp
int foo()
{return 3; }
从 文件结构(建立后): 目前,这只有部分工作。 检查 AFAICT 我试过 注意:我使用 有人知道为什么这不起作用吗? There's most of your problem: the (Your rpath is wrong too. Think about it: from the shell, if you were currently in the directory where your executable is, how would you get to the directory where your library is? Here, you'd need to If you built your object as Change the link line for the library to explicitly set the SONAME for your library to just Fix the rpath: It's useful to run (the lack of any 这篇关于构建一个简单的(hello-world-esque)示例,使用$ ORIGIN使用ld的选项-rpath的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! project / src / main.cpp
$ $ p $
$ f $($)
#include< iostream>
int main()
{
std :: cout<< foo()<<的std :: ENDL;
返回0;
project / make.sh code>
#制作目录:
mkdir -p -v obj
mkdir -p -v lib
mkdir -p -v run
#构建库:
g ++ -c -o obj / foo.o src / foo.cpp -fPIC
g ++ -shared -o lib / foo.sh obj / foo.o
#生成可执行文件:
g ++ -c -o obj / main。 o src / main.cpp
g ++ -o run / main.run obj / main.o -Wl,-rpath,'$ ORIGIN /../../ lib'-Llib -l:foo.sh
$ / code>
项目
目录下运行
b $ b make.sh
(确保它是可执行的)。
项目/
src /
foo.cpp
main.cpp
obj /
foo.o
main.o
lib /
foo.so
运行/
main.run
$ b $ b
run / main.run
现在应该加载<$
$在执行时,从任何地方执行c $ c> lib / foo.sh 问题
文件编译并链接正常,但运行时无法链接从项目
(这是练习的要点)之外的任何目录。
main.run
with readelf -d
显示:
0x0000000000000001(需要)共享库:[ lib / foo.sh]
0x000000000000000f(RPATH)库rpath:[$ ORIGIN /../../ lib]
看起来很接近(我宁愿 [foo.sh]
比 [lib / foo.sh]
但我会稍后解决)。
-Wl中的
表示 $ ORIGIN
,-rpath,'$ ORIGIN /../../ lib' project / run / main.run
,所以这个rpath应该变成 project / lib
。
$ ORIGIN /..
, $ ORIGIN /../ lib
, $ ORIGIN /../..
, $ ORIGIN /../../ lib
无效。
-l:
这需要完整的库文件名(除其他原因外,当所有函数采用相同的名称格式时,使用变量进行脚本更容易)。
或者,有谁知道有一个完整的工作示例?/
in the name stops the dynamic linker from doing the rpath magic.cd ../lib
. So your rpath should be $ORIGIN/../lib
.)libfoo.so
and linked with -Llib -lfoo
, the linker would work out what you were intending, and do the right thing. But if you're going to use unusual naming conventions, you'll have to help it out:foo.sh
:g++ -shared -Wl,-soname,foo.sh -o lib/foo.sh obj/foo.o
g++ -o run/main.run obj/main.o -Wl,-rpath,'$ORIGIN/../lib' -Llib -l:foo.sh
ldd main/main.run
to see what's going on. In your original failing case, you'll see something like: lib/foo.sh (0xNNNNNNNN)
=> /some/resolved/path
showing that it's not done any path resolution). In the fixed case, you'll see something like: foo.sh => /your/path/to/run/../lib/foo.sh (0xNNNNNNNN)