How to compile C++ code with OpenMP on Mac OSX in a portable manner?
There are many sources that suggest solutions for compiling C++ with OpenMP on OSX, e.g.:
Most of them suggest to install a more recent LLVM/Clang (or GCC) instead of the default Clang. On OSX 10.12.6 (Sierra), using LLVM (via brew install llvm
) works for me.
However, the resulting binary does not seem to be portable. If possible, I want to provide a binary so that my users don't have to compile on their own.
Running otool -L my_binary
yields
/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)
The first two lines do not look like I could just hand that binary to some user and expect it to work. The user would have to install LLVM first.
So, I found that install_name_tool
is able to change that. See https://blogs.oracle.com/dipol/dynamic-libraries,-rpath,-and-mac-os
Thus, I ran
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
Unfortunately, I don't have another Mac to test this on. So, I don't even know whether this works.
Is that the right way to do this? Somehow it feels wrong to have to modify those two libraries this way... What is the "usual" solution for this issue?
Additional minor issue: CMake does not find OpenMP (using find_package
), so I have to hard-code the needed flag (-fopenmp=libomp
). This flag is actually tried by CMake, but not recognized as working. Any idea why, or how to fix this?
Yes, it is necessary to change the dylib location in the executable if you want to bundle them with the application. Note that you do not "modify those two libraries", but only their lookup path inside your executable.
Concerning the second point (CMake not finding OpenMP): this should be solved with newer versions of cmake (>=3.12). On my system (OSX 10.13), the following entries in CMakeLists.txt do the trick:
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()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With