我正在使用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.so
( dist/
)。加载a
的可执行文件位于不同的位置。
我已尝试过@executable_path/
,@executable_path/../
,@origin/../
,但似乎都没有。
答案 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