编译参数-Wl和rpath的理解
-Wl参数的理解gcc的-Wl,xxx选项将逗号分隔的标记列表作为空格分隔的参数列表传递给链接器,即:gcc -Wl,aaa,bbb,ccc最终变成了linker的用法:ld aaa bbb ccc如果是想把ld -rpath通过-Wl传递给gcc,可以是-Wl,-rpath,xxx,也可以指定-Wl的重复实例:gcc -Wl,aaa -Wl,bbb -Wl,ccc类似的参数-Wa,<opt
-Wl参数的理解
gcc的-Wl,xxx
选项将逗号分隔的标记列表作为空格分隔的参数列表传递给链接器,即:
gcc -Wl,aaa,bbb,ccc
最终变成了linker的用法:
ld aaa bbb ccc
如果是想把ld -rpath
通过-Wl
传递给gcc,可以是-Wl,-rpath,xxx
,也可以指定-Wl的重复实例:
gcc -Wl,aaa -Wl,bbb -Wl,ccc
类似的参数
-Wa,<options> Pass comma-separated <options> on to the assembler
-Wp,<options> Pass comma-separated <options> on to the preprocessor
-Wl,<options> Pass comma-separated <options> on to the linker
rpath的说明
- 參考:
https://stackoverflow.com/questions/13617137/what-is-the-difference-between-ld-library-path-and-rpath
the
-rpath
option encodes the path in the binary, either asDT_RPATH
orDR_RUNPATH
通常,您不需要它,事实上,最好不要在可执行文件中对库搜索路径进行编码(使用-rpath选项将路径编码为二进制,可以是DT_rpath或DR_RUNPATH)
注:我自己的一般方法是在可执行文件位于构建树中,并依赖于构建树中的其他库时,将其与–rpath选项链接,以便于调试,但在安装(make install,building packages)时,需要在不使用–rpath选项的情况下重新链接,并将查找共享库的任务留给目标平台的适当动态链接器配置,例如ld.so.conf。
我的问题
在GStreamer插件注册时候发现依赖的libgstaudiosink.so找不到,而实际上系统上是有的,检查环境变量后发现和rpath配置有关。
(gst-plugin-scanner:20804): GStreamer-WARNING **: 14:35:57.201: Failed to load plugin '/usr/lib/gstreamer-1.0/libgstwestonsink.so': libgstaudiosink.so: cannot open shared object file: No such file or directory
加上-Wl到LDFLAGS后编译运行,发现就可以了。
rpath参数的写法
这里面-Wl,-rpath -Wl
rpath后面是没有逗号的,这是-Wl的另外一种写法:
-Wl,-rpath -Wl,/usr/lib/gstreamer-1.0
写成下面这样是错的:
-Wl,rpath,/usr/lib/gstreamer-1.0
完整的LDFLAGS如下:
export LDFLAGS="${LDFLAGS} -lgstaudiosink -L${SYSROOT}/usr/lib/gstreamer-1.0 -L${SYSROOT}/usr/lib/gstreamer-1.0 -Wl,-rpath -Wl,/usr/lib/gstreamer-1.0"
这样libgstwestonsink加载的时候就能顺利找到libgstaudiosink.so了,所以-Wl,-rpath -Wl,/usr/lib/gstreamer-1.0
指定了运行时的so搜索路径。
通过测试发现,-Wl,-rpath
下面这三种写法都是可以的:
-Wl,-rpath -Wl,/usr/lib/gstreamer-1.0
-Wl,-rpath,/usr/lib/gstreamer-1.0
-Wl,-rpath=/usr/lib/gstreamer-1.0
链接选项和路径
现代连接器在处理动态库时将链接时路径(Link-time path)和运行时路径(Run-time path)分开,用户可以通过-L指定连接时库的路径,通过-R(或-rpath)指定程序运行时库的路径,大大提高了库应用的灵活性。
链接器ld的选项有 -L,-rpath 和 -rpath-link,看了下 man ld,大致是这个意思:
-L: “链接”的时候,去找的目录,也就是所有的 -l 选项里的库,都会先从 -L 指定的目录去找,然后是默认的地方。编译时的-L选项并不影响环境变量LD_LIBRARY_PATH,-L只是指定了程序编译连接时库的路径,并不影响程序执行时库的路径,系统还是会到默认路径下查找该程序所需要的库,如果找不到,还是会报错,类似cannot open shared object file。
-rpath-link:这个也是用于“链接”的时候的,例如你显示指定的需要 FOO.so,但是 FOO.so 本身是需要 BAR.so 的,后者你并没有指定,而是 FOO.so 引用到它,这个时候,会先从 -rpath-link 给的路径里找。
-rpath: “运行”的时候,去找的目录。运行的时候,要找 .so 文件,会从这个选项里指定的地方去找。对于交叉编译,交叉编译链接器需已经配置 –with-sysroot 选项才能起作用。也就是说,-rpath指定的路径会被记录在生成的可执行程序中,用于运行时查找需要加载的动态库。
参考
动态库的链接和链接选项-L,-rpath-link,-rpath
I don’t understand -Wl,-rpath -Wl,
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)