Problem
On MacOS, I get linking problems at runtime for a CMake project that depends on dynamically linked resources – but only after installing the project! The problem does not occur when I only build the binary without installing it.
$ ./testapp
Hello world!
$ $INSTALLDIR/testapp
dyld: Library not loaded: @rpath/libvtkDomainsChemistryOpenGL2-7.1.1.dylib
Referenced from: /Users/normanius/workspace/installdir/testapp
Reason: image not found
[1] 76964 trace trap /Users/normanius/workspace/installdir/testapp
Minimum example
I am able to reproduce the problem in a minimal setup consisting of CMakeLists.txt
and main.cpp
. The library I am linking to is called VTK (v7.1.1) which has been built with shared libs (see below for further details).
# CMakeLists.txt
cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
project(test)
# Test application.
add_executable(testapp
main.cpp)
# Find vtk (library that has to be linked to dynamically).
find_package(VTK REQUIRED)
include(${VTK_USE_FILE})
target_link_libraries(testapp ${VTK_LIBRARIES}) # <---- this causes the problem
# Install instructions.
install(TARGETS testapp DESTINATION "${CMAKE_INSTALL_PREFIX}")
The main.cpp
not even makes use of any VTK objects.
// main.cpp
#include <iostream>
int main (int argc, char* argv[])
{
std::cout << "Hello world!" << std::endl;
return 0;
}
I build the project with the following commands. The flag CMAKE_PREFIX_PATH
I set to give CMake a hint about where to find the VTK library.
$ INSTALLDIR="path/to/installation"
$ mkdir build && cd build
$ cmake .. -DCMAKE_PREFIX_PATH="$DEVPATH/lib/vtk/cmake" \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX="$INSTALLDIR"
$ make
$ make install
When executing the testapp
in the build folder, everything looks fine:
$ ./testapp
Hello world!
$ cp testapp $INSTALLDIR/testapp
$ $INSTALLDIR/testapp
Hello world!
However, if I run the executable in the INSTALLDIR
I get a run-time error:
$ $INSTALLDIR/testapp
dyld: Library not loaded: @rpath/libvtkDomainsChemistryOpenGL2-7.1.1.dylib
Referenced from: /Users/normanius/workspace/installdir/testapp
Reason: image not found
[1] 76964 trace trap /Users/normanius/workspace/installdir/testapp
Naturally, the problem goes away if I remove the target_link_libraries()
instruction in the CMakeLists.txt
.
So what exactly happens when installing a CMake project? And what goes wrong in my case? I tested different CMake versions (3.5, 3.9 and 3.10) - but the behaviour is the same.
Details
Apparently, the RPATH mechanism on MacOS is not properly set up for the example.
This is an excerpt of the linking structure of the testapp
binary:
$ otool -L testapp
testapp:
@rpath/libvtkDomainsChemistryOpenGL2-7.1.1.dylib (compatibility version 0.0.0, current version 0.0.0)
@rpath/libvtkFiltersFlowPaths-7.1.1.dylib (compatibility version 0.0.0, current version 0.0.0)
@rpath/libvtkFiltersGeneric-7.1.1.dylib (compatibility version 0.0.0, current version 0.0.0)
@rpath/libvtkFiltersHyperTree-7.1.1.dylib (compatibility version 0.0.0, current version 0.0.0)
...
Because it may play a role how the VTK library (another CMake project) was built: For python support, one has to set the project flags VTK_WRAP_PYTHON=ON
and BUILD_SHARED_LIBS=ON
. The installation prefix was set to CMAKE_INSTALL_PREFIX="$VTK_INSTALL_DIR"
. To make sure that the resources are found at runtime, one has to additionally enable RPATH support via CMAKE_MACOSX_RPATH=ON
and CMAKE_INSTALL_RPATH="$VTK_INSTALL_DIR/lib"
.
Wrap-up
What do I conceptually get wrong? What happens when installing the project with make install
? Can this problem be solved within CMake? Or is it related only to VTK and how the shared libs were built?
-DCMAKE_INSTALL_RPATH_USE_LINK_PATH="ON"
to the command cmake command, the problem is solved! – Introject