微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

gcc在指定的path中链接共享库,但不在标准path中

我遇到了一个奇怪的问题,当使用gcc链接共享库在指定的path,但不是在标准的path。

当我下载GNU readline库版本6.3 ,并成功地编译path$ HOME / Downloads

GNU readline库需要链接libtinfo ,所以我用sudo apt-get install libtinfo 。

之后,我创build了一个名为rl.c的小样本testing来检查它。 为了构build我的示例项目,我还创build了两个符号链接,如下所示:

.so和.a文件有什么区别?

在Linux上放置/查找debugging库的位置?

使用共享库的问题

如何使用copy_from_user?

如何指定链接时使用的库版本?

$ ls -lrt ~/Downloads/ drwxr-xr-x 6 sfzhang sfzhang 4096 Mar 2 15:45 readline-6.3 lrwxrwxrwx 1 sfzhang sfzhang 12 Mar 2 16:00 readline -> readline-6.3 $ ls -lrt ~/Downloads/readline-6.3/shlib/ -rwxr-xr-x 1 sfzhang sfzhang 833856 Mar 2 15:36 libreadline.so.6.3 lrwxrwxrwx 1 sfzhang sfzhang 18 Mar 2 16:28 libreadline.so -> libreadline.so.6.3

要使用新build的readline库,我将path导出到LD_LIBRARY_PATH

$ echo $LD_LIBRARY_PATH /home/sfzhang/Downloads/readline/shlib

而且,我使用下面的命令编译了rl.c

$ gcc -o rl rl.c -I$HOME/Downloads -L$HOME/Downloads/readline/shlib -lreadline -ltinfo

检查rl链接库:

$ ldd rl linux-vdso.so.1 => (0x00007fffe09a3000) libreadline.so.6 => /lib/x86_64-linux-gnu/libreadline.so.6 (0x00007fe22d243000) libtinfo.so.5 => /lib/x86_64-linux-gnu/libtinfo.so.5 (0x00007fe22d01a000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fe22cc8d000) /lib64/ld-linux-x86-64.so.2 (0x00007fe22d492000)

我也尝试了另一个命令,但得到了相同的结果:

gcc -o rl rl.c -I$HOME/Downloads -L$HOME/Downloads/readline/shlib -lreadline -ltinfo -Wl,-rpath,$HOME/Downloads/readline/shlib

那么,为什么rl喜欢/lib/x86_64-linux-gnu/libreadline.so.6而不是$ HOME / Downloads / readline / shlib / libreadline.so

操作系统:Linux Debian 3.2.0-4-amd64#1 SMP Debian 3.2.65-1 + deb7u1 x86_64 GNU / Linux

gcc:gcc版本4.7.2(Debian 4.7.2-5)

ldd:ldd(Debian EGLIBC 2.13-38 + deb7u6)2.13

LSB AppChecker:GCC与未使用的库链接

-finstrument-functions不适用于dynamic加载的g ++共享对象(.so

Linux上的MATLAB MEX文件无法在libpython.2.7.so中find符号

如何在linux中不使用dlsym挂接

了解使用gcc的共享库

您还需要一个名为libreadline.so.6的符号链接,而不仅仅是libreadline.so 。 原因是libreadline.so.6.3的soname是libreadline.so.6 。

soname是图书馆本身嵌入的“通用”名称。 当你连接到一个拥有soname的共享库时,就是这个名字被嵌入到你的可执行文件中,之后被动态链接器查找。 (对于没有sonames的共享库,文件名被用来代替,虽然这是不常见的。)你可以通过运行来告诉soname是什么

objdump -p <library> | grep SONAME

soname的意义在于让你的可执行文件和最通用的库名称应该是兼容的(通常这个是只有主版本的库名 – 在这个例子中是6)而不仅仅是您偶然发现的特定版本(例如,小错误修复版本)。

ldd的输出也告诉你它正在寻找libreadline.so.6 。

如果你真的想要在可执行文件中硬编码一个库的路径,你需要将以下内容传递给gcc:

-Wl,-rpath=$HOME/Downloads/readline/shlib

不建议设置自定义LD_LIBRARY_PATH,如果要使用它,请将其用作执行参数。

LD_LIBRARY_PATH=$HOME/Downloads/readline/shlib ./rc

这是解决您的问题的替代方法

链接.so完整路径。 例如

$ gcc -o rl rl.c -I$HOME/Downloads $HOME/Downloads/readline/shlib/readline.so.6.3 -ltinfo

正如@Ulfalizer所说,你可能需要另一个符号链接,只有主要的数字。

如果您正在使用LD_LIBRARY_PATH请不要忘记导出它。

当使用-L<path>也使用ld.so.2 -Wl,<path> ,以便运行时链接程序ld.so.2在与ld相同的路径中查找共享库,例如:

$ gcc -o rl rl.c -I$HOME/Downloads -L$HOME/Downloads/readline/shlib -Wl,$HOME/Downloads/readline/shlib -lreadline -ltinfo

在调试链接器问题时,使用readelf -d <binary>命令查看共享库<binary>需要的确切版本(NEEDED属性)以及在查找标准链接器目录之前查找它们的位置(RPATH属性)等/ ld.so.conf中/)。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐