在运行时查找我的Linux共享库

时间:2018-03-15 23:08:19

标签: linux gcc cmake shared-libraries

我正在将用C ++编写的SDK从Windows移植到Linux。还有其他二进制文件,但最简单的是,我们的SDK是:

  • core.dll - 隐式加载的DLL(Linux上的“libcore.so”共享库)
  • tests.exe - 用于测试DLL的应用程序(使用谷歌测试)

我的所有二进制文件都必须位于应用程序可以找到的 一个 文件夹中。我在Windows上实现了这一点。我想在Linux中实现同样的目标。我悲惨地失败了

为了说明,这是基本的项目树。我们使用CMake。我建立后我已经

mysdk
  |---CMakeLists.txt (has add_subdirectory() statements for "tests" and "core")
  |---/tests  (source code + CMakeLists.txt)
  |---/core   (source code + CMakeLists.txt)
  |---/build  (all build ouput, CMake output, etc)
        |---tests  (build output)
        |---core   (build output)

目标是“扁平化”“构建”树,并将测试,核心等的所有二进制输出放入一个文件夹中。

  1. 我尝试将CMake的“安装”命令添加到我的每个CMakeLists.txt文件中(例如install(TARGETS core DESTINATION bin)。然后我在正常构建之后执行了sudo make install。这将我的所有二进制文件放在/usr/local/bin中,没有错误。但当我从那里运行tests时,它找不到libcore.so,即使它正好位于同一个文件夹中
  2. tests: error while loading shared libraries: libcore.so: Cannot open shared object file: No such file or directory
    
    1. 我读了LD_LIBRARY_PATH环境变量,因此尝试将该文件夹(/usr/local/bin)添加到其中并运行。我可以看到我已经正确地改变了LD_LIBRARY_PATH但它仍然不起作用。 “测试”仍无法找到libcore.so。我甚至尝试过更改PATH环境变量。同样的结果。

    2. 沮丧地,我尝试将输出二进制文件强制复制到临时子文件夹(/mysdk/build)并从那里运行tests。令我惊讶的是它跑了。 然后我意识到了原因:它没有加载libcore.so的本地副本,而是从构建输出文件夹中加载了一个(就像在构建时将完整路径“烘焙”到应用程序中)。随后删除libcore.so的构建输出副本使“测试”完全失败,而不是像以前那样加载本地副本。所以也许

    3. 的道路真的很棒。

      我很茫然。我已经阅读了CMake教程和参考资料。它使这个声音很容易。除了显而易见的(我做错了什么?)如果有人能回答以下任何问题,我将不胜感激:

      1. 控制我的应用查找共享库的位置的正确方法是什么?
      2. 我的项目构建结构与安装后必须出现的二进制文件之间是否存在关系?
      3. 我是否接近正确的做法?
      4. 我是否有可能无意中“烘焙”(进入我的应用程序)我的共享库的完整路径?那是一件事吗?我在我的CMakeLists文件中使用了所有CMAKE变量。

2 个答案:

答案 0 :(得分:2)

您可以运行ldd file来打印file的共享对象依赖项。它会告诉你从哪里读取它的依赖。

您可以使用希望链接器查找的路径导出环境变量LD_LIBRARY_PATH。如果未找到依赖项,请尝试将该依赖项所在的路径添加到LD_LIBRARY_PATH,然后再次运行ldd(确保导出变量)。

此外,请确保依赖项具有正确的权限。

答案 1 :(得分:1)

更新 LD_LIBRARY_PATH 是一个选项。另一种选择是使用RPATH。请查看示例。

https://github.com/mustafagonul/cmake-examples/blob/master/005-executable-with-shared-library/CMakeLists.txt

double val = (double)Math.Floor(originalValue / increment) * increment;