Reputation: 9090
I'm using CMake to build two shared libraries (.so
files). They get built into separate directories, but on the install step they get copies into the same directory. One of them links with the other. And both get loaded dynamically from another process.
The first problem is that apparently CMake does not set an rpath on the .so
files on OS X (not tested on other platforms). In CMakeLists.txt
I have
set(CMAKE_INSTALL_PREFIX ../dist)
set(MACOSX_RPATH YES)
set(INSTALL_NAME_DIR YES)
And the CMakeLists.txt
files for the two libraries get included using
add_subdirectory(./a "${CMAKE_BINARY_DIR}/a")
add_subdirectory(./b "${CMAKE_BINARY_DIR}/b")
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 (of a
) so that when the linker loads a.so
, it can find b.so
which is in the same directory (dist/
). The executable from which a
gets loaded is in a different place.
I've tried @executable_path/
, @executable_path/../
, @origin/../
, but none seem to work.
Upvotes: 1
Views: 2276
Reputation:
The first problem is that apparently CMake does not set an rpath
By default cmake does set rpath for target in build directory (see 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)
I.e. library will load correctly if you run it from directory _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.
It depends on where you want to install your library and your executable. For instance if
destination directories are the same you can set just @executable_path
:
set(CMAKE_INSTALL_RPATH "@executable_path")
install(TARGETS foo a DESTINATION bin)
See example 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)
You can test that library will load correctly from _install
:
> ./_install/bin/foo
a: 42
Upvotes: 1