gcc之链接 so a 库

本文详细介绍了在GCC中链接SO库时,如何使用-rpath和-L选项指定链接器搜索路径。讨论了LD_LIBRARY_PATH、LD_RUN_PATH的区别,并通过实例解释了为何在某些情况下需要使用-Wl,-rpath来指定运行时库的路径。同时,文章提到了如何检查和修改已编译库的rpath信息,以及链接顺序对结果的影响。" 102913214,8581114,阁楼提升机操作流程,"['物流技术', '仓储管理', '机械设备']

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

(一)

GOOGLE:  gcc compile time search lib path environment;


http://xahlee.info/UnixResource_dir/_/ldpath.html   文章说:
很早以前:LD_LIBRARY_PATH 可以作为linker的搜索路径 在 -L 参数 之后被搜索!
现在:a) LD_LIBRARY_PATH不被作为linker的搜索路径, 而引入 LD_RUN_PATH 来实现linker搜索环境变量;
   b) Nowadays you specify the run-time path for an executable at link stage with the 「-R」 (or sometimes 「-rpath」) flag to “ld”.
  gcc 参数 -R  和 -rpath 等效。


下面贴子中的作者,估计就是用到了支持LD_LIBRARY_PATH作为linker搜索路径的版本。
http://stackoverflow.com/questions/1904990/what-is-the-difference-between-ld-library-path-and-l-at-link-time

我机器上的linker就不支持LD_LIBRARY_PATH作为linker搜索路径: 

[wyh@ appimp 22:04:48]$echo $LD_LIBRARY_PATH
/home/wyh/embtv_part_2/konka_broadcom/konka_app_example/kweb_aTo_so:./
[wyh@ appimp 22:05:40]$export LD_RUN_PATH=$LD_LIBRARY_PATH
[wyh@ appimp 22:13:40]$make
mipsel-linux-g++ -L/home/wyh/embtv_part_2/konka_broadcom/usr/local/lib -lz -ldirect -ldirectfb -lfusion -Wl,-O1 -Wl,-rpath,/home/wyh/embtv_part_2/konka_broadcom/usr/local/lib -Wl,-rpath,/home/wyh/embtv_part_2/konka_broadcom/usr/qt/lib -Wl,-rpath,/usr/qt/lib -Wl,-rpath,/usr/qt/lib -o cntv_konka build/main_konka.o    -L/usr/qt/lib -L. -L../bin -lbxsurf -L../cdn/bin -lbxcdn_dir -L/home/wyh/embtv_part_2/konka_broadcom/konka_app_example/main_playerDemo/mcc/ -ltplayer -L/home/wyh/embtv_part_2/konka_broadcom/konka_app_example/main/applib -lswport -L/home/wyh/embtv_part_2/konka_broadcom/usr/local/lib/ -lnexus -linit -lpthread -lQtWebKit -lQtGui -lQtNetwork -lQtCore
/home/wyh/embtv_part_2/konka_broadcom/stbgcc-4.5.3-1.3/bin/../lib/gcc/mipsel-linux-uclibc/4.5.3/../../../../mipsel-linux-uclibc/bin/ld: warning: libbxWebPlugin.so.1, needed by ../bin/libbxsurf.so, not found (try using -rpath or -rpath-link)
../bin/libbxsurf.so: undefined reference to `bxWeb_open_url'
../bin/libbxsurf.so: undefined reference to `bxWeb_create_view'
collect2: ld returned 1 exit status
make: *** [cntv_konka] Error 1
[wyh@ appimp 22:13:45]$   后来,还参照 http://gcc.gnu.org/onlinedocs/gcc/Environment-Variables.html 官方稳当,设置了 LIBRARY_PATH环境变量,
也不管用 ---- 是在补上了  -lbxWebPlugin 来编译 cntv_konka. 

==>  最后: 在exe的链接参数中:不使用 -lbxWebPlugin, 而是增加了 -Wl,-rpath,/xxx/yyy/zzz 指向存放libbxWebPlugin.so的路径, 就编译通过了!

[wyh@ appimp 23:04:08]$mipsel-linux-g++ -L/home/wyh/embtv_part_2/konka_broadcom/usr/local/lib -lz -ldirect -ldirectfb -lfusion -Wl,-O1 -Wl,-rpath,/home/wyh/embtv_part_2/konka_broadcom/usr/local/lib -Wl,-rpath,/home/wyh/embtv_part_2/konka_broadcom/usr/qt/lib -Wl,-rpath,/usr/qt/lib -Wl,-rpath,/usr/qt/lib -Wl,-rpath,/home/wyh/embtv_part_2/konka_broadcom/konka_app_example/kweb_aTo_so -o cntv_konka build/main_konka.o    -L/usr/qt/lib -L. -L../bin -lbxsurf -L../cdn/bin -lbxcdn_dir -L/home/wyh/embtv_part_2/konka_broadcom/konka_app_example/main_playerDemo/mcc/ -ltplayer -L/home/wyh/embtv_part_2/konka_broadcom/konka_app_example/main/applib -lswport -L/home/wyh/embtv_part_2/konka_broadcom/usr/local/lib/ -lnexus -linit -lpthread -lQtWebKit -lQtGui -lQtNetwork -lQtCore
   在 http://ftp.gnu.org/old-gnu/Manuals/ld-2.9.1/html_node/ld_3.html 文章中也说了: “The -rpath option is also used when locating shared objects which are needed by shared objects explicitly included in the link; see the description of the -rpath-link option.” 即-rpath同时也作为linker的搜索路径。

例如: http://www.castaglia.org/proftpd/doc/README.AIX.html 说 “Unlike other Unix systems, by default the IBM linker automatically will use the compile time library search path as the runtime shared library search path. ” IBM的linker会自动将编译时的搜索路径作为运行时的搜索路径!

 

 修正:LIBRARY_PATH 变量是能用的,但有条件: 对于native编译才有用。 我之前测试没起作用,因为我用的是交叉编译工具链。   gcc文档就是这么说的:

“The value of  LIBRARY_PATH is a colon-separated list  of directories, much like PATH. When  configured as a native compiler, GCC  tries the directories thus specified  when searching for special linker  files, if it can't find them using  GCC_EXEC_PREFIX. Linking using GCC  also uses these directories when  searching for ordinary libraries for  the -l option (but directories  specified with -L come first).”   注意其中的 native 字。 在优先级上, -L 指定的目录优先, 其次是 LIBRARY_PATH。

 


(二)-rpath 进阶


可是,现在-lbxsurf.so已经编译好了,假设不再编译新版本的话,能否用工具修改的-rpath信息呢? 

 ==〉  可以的: 下面是 http://www.eyrie.org/~eagle/notes/rpath.html 文章中摘出来的: 

Checking the binaries // 可以检查一个 so 中已经hardcoded的 rpath:

To verify that a binary is doing the right thing, use the command ldd on the binary. This will list all of the libraries and either where they came from (if found) or something like "(not found)" if the library wasn't found. On Mac OS X, use otool -L.

Solaris has the very useful -s option to ldd that will additionally show the full library search path, so you can confirm that you encoded the right rpath in the binary.

A partial equivalent under Linux is:
    readelf -d <binary> | grep RPATH
but note that this only shows the rpath for a particular binary (executable or library). If a shared library depends on other shared libraries, those shared libraries may be searched for using the rpath of the shared library that is loading them. To make sure that the search path is correct on Linux, you may need to use the above readelf command on the binary and all libraries other than system libraries that it uses. readelf comes with binutils, so if you're compiling software you will probably already have it installed.

Changing the rpath  //还可以修改so中的rpath信息: 

On Linux, a utility called patchelf is available that can modify or remove the rpath or add one if one was not already present. This utility replaces the older chrpath utility, which appears to no longer be maintained.

patchelf won't compile on Solaris out of the box. For it, you may still need chrpath. The maintainer's FTP site used to be atftp://ftp.hungry.com/pub/hungry/chrpath/ but has been unreachable for some time. At this point, the best source is probably the Debian package.

(三) 关于链接顺序不同的结果:
http://stackoverflow.com/questions/10585225/some-questions-about-search-order-of-gcc-linker?rq=1    很好的例子!

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值