通过动态链接在Mac OSX上用OpenMP编译C ++

luc*_*luc 5 c++ macos openmp dylib

摘要

如何以可移植的方式在Mac OSX上使用OpenMP编译C ++代码?

有许多资料来源建议在OSX上使用OpenMP编译C ++的解决方案,例如:

他们中的大多数建议安装更新的LLVM / Clang(或GCC),而不是默认的Clang。在OSX 10.12.6(Sierra)上,使用LLVM(通过brew install llvm)对我有效。

但是,生成的二进制文件似乎不可移植。如果可能的话,我想提供一个二进制文件,这样我的用户就不必自己编译。

这是我尝试过的

运行otool -L my_binary收益

/usr/local/opt/llvm/lib/libomp.dylib (compatibility version 5.0.0, current version 5.0.0)
/usr/local/opt/llvm/lib/libc++.1.dylib (compatibility version 1.0.0, current version 1.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1238.0.0)
/usr/lib/libc++abi.dylib (compatibility version 1.0.0, current version 307.2.0)
Run Code Online (Sandbox Code Playgroud)

前两行看起来并不像我可以将二进制文件交给某些用户,并希望它能工作。用户必须先安装LLVM。

因此,我发现install_name_tool可以改变这一点。参见https://blogs.oracle.com/dipol/dynamic-libraries,-rpath,-and-mac-os

因此,我跑了

cp /usr/local/opt/llvm/lib/libomp.dylib .
cp /usr/local/opt/llvm/lib/libc++.1.dylib .

install_name_tool -change /usr/local/opt/llvm/lib/libomp.dylib @executable_path/libomp.dylib my_binary
install_name_tool -change /usr/local/opt/llvm/lib/libc++.1.dylib @executable_path/libc++.1.dylib my_binary

install_name_tool -id "@loader_path/libomp.dylib" libomp.dylib
install_name_tool -id "@loader_path/libc++.1.dylib" libc++.1.dylib
Run Code Online (Sandbox Code Playgroud)

不幸的是,我没有另一台Mac可以对此进行测试。所以,我什至不知道这是否有效。

问题

这是正确的方法吗?以某种方式不得不修改这两个库感觉有点不对劲……这个问题的“通常”解决方案是什么?

另一个较小的问题:CMake找不到OpenMP(使用find_package),因此我必须对所需的标志(-fopenmp=libomp)进行硬编码。该标志实际上是由CMake尝试的,但未被识别为有效。知道为什么,还是要解决此问题?

cda*_*itz 1

是的,如果您想将它们与应用程序捆绑在一起,则需要更改可执行文件中的 dylib 位置。请注意,您不会“修改这两个库”,而只是修改它们在可执行文件中的查找路径。

关于第二点(CMake 找不到 OpenMP):这应该使用较新版本的 cmake (>=3.12) 来解决。在我的系统(OSX 10.13)上,CMakeLists.txt 中的以下条目可以解决问题:

find_package(OpenMP)
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")

if (APPLE)
  target_link_libraries(my_target OpenMP::OpenMP_CXX)
else ()
  target_link_libraries(my_target)
endif()
Run Code Online (Sandbox Code Playgroud)