链接同一目录中的共享库

时间:2015-02-11 10:09:23

标签: macos linker cmake makefile dyld

我正在使用CMake构建两个共享库(.so文件)。它们构建在单独的目录中,但在安装步骤中,它们会将副本复制到同一目录中。其中一个与另一个链接。两者都是从另一个进程动态加载的。

第一个问题是显然CMake没有在OS X上的.so文件上设置rpath(未在其他平台上测试)。在CMakeLists.txt我有

set(CMAKE_INSTALL_PREFIX ../dist)
set(MACOSX_RPATH YES)
set(INSTALL_NAME_DIR YES)

使用

包含两个库的CMakeLists.txt个文件
add_subdirectory(./a "${CMAKE_BINARY_DIR}/a")
add_subdirectory(./b "${CMAKE_BINARY_DIR}/b")

但在生成的otool -l文件上运行.so会显示没有LC_RPATH条目。

此外,需要在RPath(a)中设置哪条路径,以便在链接器加载a.so时,它可以找到位于同一目录中的b.sodist/)。加载a的可执行文件位于不同的位置。

我已尝试过@executable_path/@executable_path/../@origin/../,但似乎都没有。

1 个答案:

答案 0 :(得分:1)

  

第一个问题是显然CMake没有设置rpath

默认情况下,cmake会在构建目录中为目标设置rpath(参见project):

> cmake -H. -B_builds -DBUILD_SHARED_LIBS=ON
> cmake --build _builds
> ls _builds/foo _builds/liba.dylib 
  _builds/foo
  _builds/liba.dylib
> otool -L _builds/foo 
_builds/foo:
  @rpath/liba.dylib (compatibility version 0.0.0, current version 0.0.0)
  ...
> otool -l _builds/foo | grep LC_RPATH -A2
      cmd LC_RPATH
  cmdsize 64
     path /.../_builds (offset 12)

即。如果从目录_builds运行它,则库将正确加载:

> ./_builds/foo
a: 42
  

但是在生成的.so文件上运行otool -l显示没有LC_RPATH条目。

     

此外,需要在RPath中设置哪条路径

     

我已经尝试了@ executable_path /,@ executable_path /../, @ origin /../,但似乎都没有。

这取决于您要安装库和可执行文件的位置。例如,如果 目标目录与您只能设置@executable_path

相同
set(CMAKE_INSTALL_RPATH "@executable_path")
install(TARGETS foo a DESTINATION bin)

参见示例project

> cmake -H. -B_builds -DBUILD_SHARED_LIBS=ON -DCMAKE_INSTALL_PREFIX=_install
> cmake --build _builds --target install
> otool -L _install/bin/foo 
_install/bin/foo:
  @rpath/liba.dylib (compatibility version 0.0.0, current version 0.0.0)
  ...
> otool -l _install/bin/foo | grep LC_RPATH -A2
      cmd LC_RPATH
  cmdsize 32
     path @executable_path (offset 12)

您可以测试该库是否会从_install正确加载:

> ./_install/bin/foo
a: 42

信息