如何在macOS的CPack包中集成OpenMP库并确保可执行文件能找到它?
macOS下CMake/CPack打包OpenMP程序的库路径问题
我正在学习CMake和CPack,在macOS上打包带OpenMP的C++程序时遇到问题:已经成功把可执行文件和OpenMP共享库打包到同一个安装包,但运行时可执行文件还是会去原始路径(Homebrew安装libomp的路径)查找libomp,导致找不到库无法运行。不想手动用install_name_tool或者设置DYLD_LIBRARY_PATH,希望直接通过CMake/CPack解决。之前调过RPATH相关变量但没成功,把库和可执行文件放同一目录也没用。
C++代码示例
#include <iostream> #include <omp.h> int main() { #pragma omp parallel num_threads(4) { std::cout << "Hallo Welt... von Thread = " << omp_get_thread_num() << std::endl; } return 0; }
当前使用的CMakeLists.txt
# Set the minimum required CMake version cmake_minimum_required(VERSION 3.21) # Set the project name project(OpenMPExample) # Find OpenMP package find_package(OpenMP REQUIRED) # Add the executable target add_executable(parallel-hallo parallel-hallo.cpp) # Link the OpenMP library target_link_libraries(parallel-hallo PRIVATE OpenMP::OpenMP_CXX) # Install main executable and runtime dependencies install(TARGETS parallel-hallo RUNTIME_DEPENDENCY_SET OpenMP RUNTIME DESTINATION bin) install(RUNTIME_DEPENDENCY_SET OpenMP DESTINATION lib) include(CPack)
打包后的文件结构
OpenMPExample-0.1.1-Darwin/bin: parallel-hallo* OpenMPExample-0.1.1-Darwin/lib: libomp.dylib*
运行时错误信息
/Users/user/Downloads/OpenMPExample-0.1.1-Darwin/bin/parallel-hallo ; exit; dyld[4755]: Library not loaded: /usr/local/opt/libomp/lib/libomp.dylib Referenced from: <59DF0FF4-9EF7-338A-87BC-6A25C972D9D4> /Users/user/Downloads/OpenMPExample-0.1.1-Darwin/bin/parallel-hallo Reason: tried: '/usr/local/opt/libomp/lib/libomp.dylib' (no such file), '/System/Volumes/Preboot/Cryptexes/OS/usr/local/opt/libomp/lib/libomp.dylib' (no such file), '/usr/local/opt/libomp/lib/libomp.dylib' (no such file), '/usr/local/lib/libomp.dylib' (no such file), '/usr/lib/libomp.dylib' (no such file, not in dyld cache)
预期运行结果
Hallo Welt... von Thread = 0 Hallo Welt... von Thread = 3 Hallo Welt... von Thread = 2 Hallo Welt... von Thread = 1
解决方案
要让可执行文件在打包后自动找到同包内的libomp,需要正确配置CMake的RPATH和库标识,以下是修改后的完整CMake配置:
修改后的CMakeLists.txt
cmake_minimum_required(VERSION 3.21) project(OpenMPExample) find_package(OpenMP REQUIRED) add_executable(parallel-hallo parallel-hallo.cpp) target_link_libraries(parallel-hallo PRIVATE OpenMP::OpenMP_CXX) # 配置可执行文件的安装RPATH,指向相对路径的lib目录 set_target_properties(parallel-hallo PROPERTIES INSTALL_RPATH "@executable_path/../lib" BUILD_WITH_INSTALL_RPATH ON ) install(TARGETS parallel-hallo RUNTIME DESTINATION bin) install(RUNTIME_DEPENDENCY_SET OpenMP DESTINATION lib) # 修改libomp.dylib的自身标识为相对路径,配合RPATH被正确查找 install(CODE " execute_process( COMMAND install_name_tool -id @rpath/libomp.dylib \${CMAKE_INSTALL_PREFIX}/lib/libomp.dylib ) ") include(CPack)
关键配置说明
INSTALL_RPATH "@executable_path/../lib":告诉macOS的动态链接器(dyld),可执行文件运行时从自身所在的bin目录向上跳转一层,到lib目录查找依赖库。BUILD_WITH_INSTALL_RPATH ON:让编译阶段就使用安装后的RPATH配置,避免后续还要额外调整路径。- 修改libomp的
install_name:Homebrew安装的libomp默认使用绝对路径作为自身标识,通过install_name_tool修改为@rpath/libomp.dylib,确保可执行文件能通过RPATH正确定位到它。
内容的提问来源于stack exchange,提问作者Marie H
相关产品推荐
相关产品推荐

