【发布时间】:2018-05-21 17:16:29
【问题描述】:
问题
在 MacOS 上,我在运行时遇到依赖于动态链接资源的 CMake 项目的链接问题 - 但仅在安装项目之后!当我只构建二进制文件而不安装它时,不会出现此问题。
$ ./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
最小示例
我能够在由CMakeLists.txt 和main.cpp 组成的最小设置中重现该问题。我要链接的库名为 VTK (v7.1.1),它是使用共享库构建的(有关详细信息,请参见下文)。
# 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}")
main.cpp 甚至不使用任何 VTK 对象。
// main.cpp
#include <iostream>
int main (int argc, char* argv[])
{
std::cout << "Hello world!" << std::endl;
return 0;
}
我使用以下命令构建项目。我设置的标志CMAKE_PREFIX_PATH 是为了给 CMake 一个关于在哪里可以找到 VTK 库的提示。
$ 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
在构建文件夹中执行testapp 时,一切正常:
$ ./testapp
Hello world!
$ cp testapp $INSTALLDIR/testapp
$ $INSTALLDIR/testapp
Hello world!
但是,如果我在 INSTALLDIR 中运行可执行文件,我会收到运行时错误:
$ $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
当然,如果我删除 CMakeLists.txt 中的 target_link_libraries() 指令,问题就会消失。
那么在安装 CMake 项目时究竟会发生什么?我的情况出了什么问题?我测试了不同的 CMake 版本(3.5、3.9 和 3.10)——但行为是相同的。
详情
显然,MacOS 上的 RPATH 机制没有为示例正确设置。
这是testapp二进制文件的链接结构的摘录:
$ 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)
...
因为它可能会影响 VTK 库(另一个 CMake 项目)的构建方式:对于 python 支持,必须设置项目标志 VTK_WRAP_PYTHON=ON 和 BUILD_SHARED_LIBS=ON。安装前缀设置为CMAKE_INSTALL_PREFIX="$VTK_INSTALL_DIR"。为了确保在运行时找到资源,还必须通过CMAKE_MACOSX_RPATH=ON 和CMAKE_INSTALL_RPATH="$VTK_INSTALL_DIR/lib" 启用 RPATH 支持。
总结
我在概念上会犯什么错误?使用make install 安装项目时会发生什么?这个问题可以在 CMake 中解决吗?还是仅与 VTK 以及共享库的构建方式有关?
【问题讨论】:
标签: macos cmake shared-libraries vtk dylib