运行-时间链接器问题:"error while loading shared libraries"
Run-time linker issue: "error while loading shared libraries"
我正在处理一个由多个类似程序组成的 C++ 项目。每个都使用各种头文件和二进制文件,大约 80 个。我设法编译了每个程序,并成功 运行 每个程序,但其中一个名为 VerifyServer。当我尝试 运行 时,出现以下错误:
./VerifyServer:加载共享库时出错:libboost_system.so.1.57.0:无法打开共享对象文件:没有这样的文件或目录
然而,奇怪的是:
我在尝试 运行 其他程序时遇到了一个非常相似的错误,但后来我添加了
-Wl,-rpath=$(BOOST_LIB_HEADER_PATH)/stage/lib
我的每个编译器参数,它起作用了。我设法 运行 每个程序,甚至 VerifyServer 错误消息中指示的文件都发生了变化。请注意,变量 BOOST_LIB_HEADER_PATH 已正确分配给我的 boost 库的路径。
因为我的 运行 时间 linker 未能找到这个二进制文件以正确地 link 它与我的程序,我尝试检查它无法找到哪些依赖项,所以当我运行
ldd VerifyServer | grep boost
(为简单起见,我使用 grep)
我收到这条消息:
libboost_thread.so.1.57.0 => /path/to/boost_1_57_0/stage/lib/libboost_thread.so.1.57.0 (0x00007f34c9b36000)
libboost_serialization.so.1.57.0 => /path/to/boost_1_57_0/stage/lib/libboost_serialization.so.1.57.0 (0x00007f34c9ad1000)
libboost_system.so.1.57.0 => 未找到
所以,到目前为止,我假设系统二进制文件与其他二进制文件不在同一目录中。当我手动检查时,我发现很奇怪,它就在那里!所以我决定在 运行 没有任何问题的程序之一上做同样的事情,我使用
ldd IdentityProviderServer | grep boost
我收到以下消息:
libboost_thread.so.1.57.0 => /path/to/boost_1_57_0/stage/lib/libboost_thread.so.1.57.0 (0x00007f97b6094000)
libboost_serialization.so.1.57.0 => /path/to/boost_1_57_0/stage/lib/libboost_serialization.so.1.57.0 (0x00007f97b602f000)
libboost_system.so.1.57.0 => /path/to/boost_1_57_0/stage/lib/libboost_system.so.1.57.0 (0x00007f97b602a000)
libboost_filesystem.so.1.57.0 => /path/to/boost_1_57_0/stage/lib/libboost_filesystem.so.1.57.0 (0x00007f97b600d000)
当我看到系统二进制文件可以在与其他文件相同的位置找到时,我感到很困惑。我不知道这里有什么问题。关于 linker 的工作原理,我是否遗漏了什么?
请注意,我这里必须使用1.57.0版本的boost。我无法更新到当前版本,我怀疑我的问题与boost版本有什么关系。
这可能是因为链接器无法找到瞬态依赖项。如果您直接链接到 EG:libboost_thread,那么应用程序运行时链接器将使用您在编译时定义的 -rpath 路径。
但是,libboost_thread 可能需要它自己的库,libboost_system。问题是,libboost_thread 库的运行时链接器是否应该使用您的应用程序 -rpath?或者忽略它并使用它自己的系统搜索路径??您必须明确告诉运行时链接程序它应该做什么。请注意,默认的运行时链接器搜索行为会根据您的编译器版本而变化。 Google、RUNPATH 与 RPATH 和 -Wl,--disable-new-dtags
我已经在另一个类似的问题中回答过这个问题:
虽然该用户正在使用 CMake 构建他们的应用程序,但潜在的问题也可能发生在这里。
我正在处理一个由多个类似程序组成的 C++ 项目。每个都使用各种头文件和二进制文件,大约 80 个。我设法编译了每个程序,并成功 运行 每个程序,但其中一个名为 VerifyServer。当我尝试 运行 时,出现以下错误:
./VerifyServer:加载共享库时出错:libboost_system.so.1.57.0:无法打开共享对象文件:没有这样的文件或目录
然而,奇怪的是:
我在尝试 运行 其他程序时遇到了一个非常相似的错误,但后来我添加了
-Wl,-rpath=$(BOOST_LIB_HEADER_PATH)/stage/lib
我的每个编译器参数,它起作用了。我设法 运行 每个程序,甚至 VerifyServer 错误消息中指示的文件都发生了变化。请注意,变量 BOOST_LIB_HEADER_PATH 已正确分配给我的 boost 库的路径。
因为我的 运行 时间 linker 未能找到这个二进制文件以正确地 link 它与我的程序,我尝试检查它无法找到哪些依赖项,所以当我运行
ldd VerifyServer | grep boost
(为简单起见,我使用 grep)
我收到这条消息:
libboost_thread.so.1.57.0 => /path/to/boost_1_57_0/stage/lib/libboost_thread.so.1.57.0 (0x00007f34c9b36000)
libboost_serialization.so.1.57.0 => /path/to/boost_1_57_0/stage/lib/libboost_serialization.so.1.57.0 (0x00007f34c9ad1000)
libboost_system.so.1.57.0 => 未找到
所以,到目前为止,我假设系统二进制文件与其他二进制文件不在同一目录中。当我手动检查时,我发现很奇怪,它就在那里!所以我决定在 运行 没有任何问题的程序之一上做同样的事情,我使用
ldd IdentityProviderServer | grep boost
我收到以下消息:
libboost_thread.so.1.57.0 => /path/to/boost_1_57_0/stage/lib/libboost_thread.so.1.57.0 (0x00007f97b6094000)
libboost_serialization.so.1.57.0 => /path/to/boost_1_57_0/stage/lib/libboost_serialization.so.1.57.0 (0x00007f97b602f000)
libboost_system.so.1.57.0 => /path/to/boost_1_57_0/stage/lib/libboost_system.so.1.57.0 (0x00007f97b602a000)
libboost_filesystem.so.1.57.0 => /path/to/boost_1_57_0/stage/lib/libboost_filesystem.so.1.57.0 (0x00007f97b600d000)
当我看到系统二进制文件可以在与其他文件相同的位置找到时,我感到很困惑。我不知道这里有什么问题。关于 linker 的工作原理,我是否遗漏了什么?
请注意,我这里必须使用1.57.0版本的boost。我无法更新到当前版本,我怀疑我的问题与boost版本有什么关系。
这可能是因为链接器无法找到瞬态依赖项。如果您直接链接到 EG:libboost_thread,那么应用程序运行时链接器将使用您在编译时定义的 -rpath 路径。
但是,libboost_thread 可能需要它自己的库,libboost_system。问题是,libboost_thread 库的运行时链接器是否应该使用您的应用程序 -rpath?或者忽略它并使用它自己的系统搜索路径??您必须明确告诉运行时链接程序它应该做什么。请注意,默认的运行时链接器搜索行为会根据您的编译器版本而变化。 Google、RUNPATH 与 RPATH 和 -Wl,--disable-new-dtags
我已经在另一个类似的问题中回答过这个问题:
虽然该用户正在使用 CMake 构建他们的应用程序,但潜在的问题也可能发生在这里。