链接同一目录中的共享库

Linking shared libraries in same directory

我正在使用 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 条目。

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

我试过 @executable_path/@executable_path/../@origin/../,但 none 似乎有效。

The first problem is that apparently CMake does not set an 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

But running otool -l on the resulting .so files shows no LC_RPATH entry.

Also, which path would need to be set in the RPath

I've tried @executable_path/, @executable_path/../, @origin/../, but none seem to work.

这取决于您要在何处安装库和可执行文件。例如,如果 目标目录相同,您可以设置 @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

信息