3

我在 /opt/my_prog/lib 和 /home/user1/lib 中有一个共享库的 libmyworld.so,无论我在 LD_LIBRARY_PATH (LD_LIBRARY_PATH=/home/user1/lib;/opt/myprog/lib) 中指定的顺序如何;我的二进制文件应该总是在 /opt/my_prog/lib 中寻找 libmyworld.so FIRST;

这可以在编译期间使用 GCC 来完成吗?无需修改 my_prog 二进制文件。提前致谢。

4

4 回答 4

6

Linux 中动态库的搜索顺序(来自 ld.so 手册页)如下

  • 使用二进制文件的 DT_RPATH 动态部分属性(如果存在)并且 DT_RUNPATH 属性不存在。不推荐使用 DT_RPATH。
  • 使用环境变量 LD_LIBRARY_PATH。除非可执行文件是 setuid/setgid 二进制文件,在这种情况下它会被忽略。
  • 使用二进制文件的 DT_RUNPATH 动态部分属性(如果存在)。
  • 来自缓存文件 /etc/ld.so.cache,其中包含先前在扩充库路径中找到的候选库的编译列表。但是,如果使用 -z nodeflib 链接器选项链接二进制文件,则会跳过默认库路径中的库。
    • 在默认路径 /lib 中,然后是 /usr/lib。如果二进制文件使用 -z nodeflib 链接器选项链接,则跳过此步骤。

链接时,设置

  • DT_RUNPATH:使用 -Wl,--enable-new-dtags -Wl,-R$(RUNPATH)
  • DT_RPATH:使用 -Wl,--disable-new-dtags -Wl,-R$(RPATH)

理论上,最好使用 DT_RUNPATH 作为用户可以控制的 LD_LIBRARY_PATH 优先。但是这里要避免用户控制,所以使用DT_RPATH。在您的链接行中:

-Wl,--disable-new-dtags -Wl,-R/opt/my_prog/lib
于 2012-11-29T10:25:10.413 回答
0

你总是可以启动你的二进制文件(这里称为foo

$ LD_LIBRARY_PATH=/opt/my_prog/lib foo

或使用上面的行制作一个 shell 脚本。

于 2012-11-29T09:35:18.290 回答
0

编译源代码时使用以下命令 gcc -o [desired_executable_file_name] -L [Your shared library path] -l [your shared library name] -I [Header file path]

例如在你的情况下 gcc -o my_word_exe -L /opt/my_prog/lib -lmyworld -I [header path if they]

然后它会在 /opt/my_prog/lib 这个路径中使用 libmyworld.so

于 2012-11-29T12:05:45.290 回答
-2

使用 LD_PRELOAD。

LD_PRELOAD=/home/lib/libmyworld.so mybinary

优点是您不必摆弄 LD_LIBRARY_PATH - 您的二进制文件可能依赖于其他共享库,并且可能需要适当的LD_LIBRARY_PATH/ld.so.conf/whatever.

PS。这是侵入性最小且灵活的解决方案,因为不影响其他库的加载,也不会对用户可执行文件中的路径进行硬编码。

于 2012-11-29T09:49:59.800 回答