运行程序时找不到共享对象库,但在编译期间已链接

Kar*_*kan 4 c++ linux linker g++

更新:问题已解决。该库是为 Armv7a CPU 设计的,但它是“软浮动”而不是“硬浮动”。好像我的机器是 HF 而不是 SF 兼容

我的程序依赖于一个名为 libMyLib.so 的外部构建 .so 库。当我这样编译程序时:

$ g++ -std=c++11 main.cpp -o run -pthread
Run Code Online (Sandbox Code Playgroud)

它报告有很多未定义的引用,显然是因为我在编译时没有包含 libMyLib.so。所以编译器知道他需要什么来编译程序。当我像这样编译程序时:

$ g++ -std=c++11 main.cpp -o run -pthread -lMyLib
Run Code Online (Sandbox Code Playgroud)

它不会报告任何错误并创建文件“运行”。请注意,libMyLib.so 已经在 /usr/local/lib 中,并且在编译时它看起来像是链接的,因为现在定义了引用并创建了“运行”文件。但是当我运行文件时,会发生这种情况:

$ ./run
    ./run: error while loading shared libraries: libMyLib.so: cannot open shared object file: No such file or directory
Run Code Online (Sandbox Code Playgroud)

我已经检查过 ldd ,它显示了这个:

$ ldd run
    ...
    libMyLib.so => not found
    ...
Run Code Online (Sandbox Code Playgroud)

所以 ldd 在执行时找不到库,但在编译时找到了。我对 Linux 和链接库很陌生,所以我不知道该怎么做。

此外,在 .so 文件上运行 ldd 会返回:

$ ldd /usr/local/lib/libMyLib.so
    not a dynamic executable
Run Code Online (Sandbox Code Playgroud)

我已经检查过在错误的平台上运行 .so 文件时可能会出现此消息。但我已经检查过,该库是为 arm 编译的(我在树莓派上运行 -> arm):

$  objdump -f /usr/local/lib/libMyLib.so | grep ^architecture
    architecture: arm, flags 0x00000150:
Run Code Online (Sandbox Code Playgroud)

我还更新了链接器:

$ sudo ldconfig -v
...
/usr/local/lib:
    libwiringPi.so -> libwiringPi.so.2.44
    libwiringPiDev.so -> libwiringPiDev.so.2.44
    libMyLib.so -> libMyLib.so.1
...
Run Code Online (Sandbox Code Playgroud)

我真的不知道为什么这可能还会发生。谁能帮我?

Mik*_*han 6

/usr/local/lib是链接器默认搜索使用-l选项指定的库的目录之一,因此您的链接成功。

然而,在运行时,程序加载器默认在以下位置搜索链接库:-

  • /lib/usr/lib以及名称和位置已缓存在ldconfig缓存中的库中,/etc/ld.so.cache.
  • 环境变量的值中列出的目录LD_LIBRARY_PATH,在当前 shell 中。

ldconfig当缓存仅仅更新ldconfig运行。见ldconfig

加载器libMyLib.so在运行时无法找到,因为ldconfig自从您将该库放入后您就没有运行过,/usr/local/lib并且您也没有正确添加/usr/local/libLD_LIBRARY_PATH 您尝试运行该程序的同一个 shell 中。

需要一个特殊的设置LD_LIBRARY_PATH来使程序能够运行是不方便的,否则是不可取的 。

要使加载程序能够找到您的库,请ldconfig以 root 身份运行。如果/usr/local/lib中列出/etc/ld.so.conf,或包含在/etc/ld.so.conf. 如果不是,那么您可以/usr/local/lib通过ldconfig /usr/local/lib以 root 身份运行 ,来显式缓存共享库。


skr*_*skr 5

首先检查 LD_LIBRARY_PATH 变量是否具有库目录的路径

$ echo $LD_LIBRARY_PATH
Run Code Online (Sandbox Code Playgroud)

如果不存在则更新库路径。

$ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/path/to/library
Run Code Online (Sandbox Code Playgroud)

使用strace进行调试。

strace -f ./run
Run Code Online (Sandbox Code Playgroud)