Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compile C++ with OpenMP on Mac OSX with dynamic linking

Summary

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.:

  • OpenMP support on OSX 10.11
  • apple clang -fopenmp not working
  • openmp runs single threaded on my mac

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.

Here is what I tried

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.

Questions

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?

like image 955
luc Avatar asked Nov 07 '22 18:11

luc


1 Answers

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()
like image 174
cdalitz Avatar answered Nov 14 '22 20:11

cdalitz