【问题标题】:When dynamically linking, where will it search for the library, and how to change this?动态链接时,它将在哪里搜索库,以及如何更改?
【发布时间】:2013-10-21 12:21:48
【问题描述】:

当我在基于 Unix/Linux 的系统上动态链接时,当我执行程序时它会在哪里尝试查找库文件,我该如何更改?我正在使用 GNU/G++ 编译器。

【问题讨论】:

    标签: unix g++ shared-libraries dynamic-linking


    【解决方案1】:

    程序运行的系统定义了在哪里搜索动态库。程序本身只是命名库(没有路径)。

    在 Linux 系统上,有一个系统范围的默认搜索位置,您可以通过将环境变量 LD_LIBRARY_PATH 设置为以冒号分隔的库路径列表来覆盖它:

    $ LD_LIBRARY_PATH=/path/to/my/libs/:/another/path/to/libs/of/mine/
    $ export LD_LIBRARY_PATH
    $ ./path/to/my/executable
    

    或更短:

    $ LD_LIBRARY_PATH=/path/to/my/libs/:/another/path/to/libs/of/mine/ ./path/to/my/executable
    

    系统默认使用ldconfig 配置,通常基于/etc/ld.so.conf(指向/etc/ld.so.conf.d)和/etc/ld.so.cache 找到的文件。

    可以使用ldd 检查给定的可执行文件需要哪些动态库:

    $ ldd /bin/ls
        linux-vdso.so.1 =>  (0x00007fffc83ff000)
        libselinux.so.1 => /lib/x86_64-linux-gnu/libselinux.so.1 (0x00007fbe1306b000)
        librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007fbe12e63000)
        libacl.so.1 => /lib/x86_64-linux-gnu/libacl.so.1 (0x00007fbe12c5a000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fbe1289b000)
        libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fbe12697000)
        /lib64/ld-linux-x86-64.so.2 (0x00007fbe132ae000)
        libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fbe12479000)
        libattr.so.1 => /lib/x86_64-linux-gnu/libattr.so.1 (0x00007fbe12274000)
    

    您还可以在启动可执行文件时使用strace 的输出来查看系统在哪里查找库:

    $ strace ls 2>&1 | grep '^open.*\.so'
    open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
    open("/lib/x86_64-linux-gnu/libselinux.so.1", O_RDONLY|O_CLOEXEC) = 3
    open("/lib/x86_64-linux-gnu/librt.so.1", O_RDONLY|O_CLOEXEC) = 3
    open("/lib/x86_64-linux-gnu/libacl.so.1", O_RDONLY|O_CLOEXEC) = 3
    open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
    open("/lib/x86_64-linux-gnu/libdl.so.2", O_RDONLY|O_CLOEXEC) = 3
    open("/lib/x86_64-linux-gnu/libpthread.so.0", O_RDONLY|O_CLOEXEC) = 3
    open("/lib/x86_64-linux-gnu/libattr.so.1", O_RDONLY|O_CLOEXEC) = 3
    

    【讨论】:

    • 所以我可以做类似#define LD_LIBRARY PATH "/usr/lib;/usr/local/lib;./lib" 之类的事情?
    • 不,LD_LIBRARY_PATH 是一个环境变量。在启动可执行文件之前,在 shell 中设置并导出它。我会相应地扩展我的答案。
    • 无法在可执行文件中指定搜索动态库的位置。这与它背后的想法背道而驰。
    • 请注意:有些 UNIX 系统的变量名称不同,例如。在 AIX 上:LIBPATH
    • 是的,感谢 Ingo 的补充。我的回答中说的是Linux系统上的特定情况。其他系统也可能不允许通过环境变量重新路由。有太多的味道无法确定。
    猜你喜欢
    • 2017-12-26
    • 2023-03-14
    • 2012-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多