Problem
$ ./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?