我在 /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 二进制文件。提前致谢。
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 作为用户可以控制的 LD_LIBRARY_PATH 优先。但是这里要避免用户控制,所以使用DT_RPATH。在您的链接行中:
-Wl,--disable-new-dtags -Wl,-R/opt/my_prog/lib
你总是可以启动你的二进制文件(这里称为foo)
$ LD_LIBRARY_PATH=/opt/my_prog/lib foo
或使用上面的行制作一个 shell 脚本。
编译源代码时使用以下命令 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
使用 LD_PRELOAD。
LD_PRELOAD=/home/lib/libmyworld.so mybinary
优点是您不必摆弄 LD_LIBRARY_PATH - 您的二进制文件可能依赖于其他共享库,并且可能需要适当的LD_LIBRARY_PATH/ld.so.conf/whatever
.
PS。这是侵入性最小且灵活的解决方案,因为不影响其他库的加载,也不会对用户可执行文件中的路径进行硬编码。