0

I tried to test OpenMP on MacOS with the Apple Clang compiler that comes with Xcode.

Code:

#include <iostream>
#include <cmath>
#include </usr/local/opt/libomp/include/omp.h>

int main() {
    std::cout << "Hello, World!" << std::endl;
    #pragma omp parallel
    {
        printf("Hello World! \n");
    }
    return 0;
}

and this is my CMakeLists.txt:

cmake_minimum_required(VERSION 3.19)
project(untitled)

set(CMAKE_CXX_STANDARD 14)
include (FindOpenMP)
if (OPENMP_FOUND)
    set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
    set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
    set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}")
    message (VERBOSE "OpenML library found")
else()
    message (FATAL_ERROR "OpenML library not found (required for multithreading)")
endif ()
add_executable(untitled main.cpp)

This is the compiler's error:

Scanning dependencies of target untitled
[ 50%] Building CXX object CMakeFiles/untitled.dir/main.cpp.o
[100%] Linking CXX executable untitled
Undefined symbols for architecture x86_64:
  "___kmpc_fork_call", referenced from:
      _main in main.cpp.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[3]: *** [untitled] Error 1
make[2]: *** [CMakeFiles/untitled.dir/all] Error 2
make[1]: *** [CMakeFiles/untitled.dir/rule] Error 2
make: *** [untitled] Error 2

The OpenMP is installed using hombrew libomp I also tried adding environment variable LDFLAGS=-L/usr/local/opt/libomp/lib/ and it does not affect the result


UPDATE: COMPILATION WITH VERBOSE=1:

...
[100%] Linking CXX executable untitled
/Applications/CLion.app/Contents/bin/cmake/mac/bin/cmake -E cmake_link_script CMakeFiles/untitled.dir/link.txt --verbose=1
/Library/Developer/CommandLineTools/usr/bin/c++  -Xclang -fopenmp -g -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX11.3.sdk -Wl,-search_paths_first -Wl,-headerpad_max_install_names -L/usr/local/opt/libomp/lib/  CMakeFiles/untitled.dir/main.cpp.o -o untitled 
Undefined symbols for architecture x86_64:
  "___kmpc_fork_call", referenced from:
      _main in main.cpp.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[3]: *** [untitled] Error 1
make[2]: *** [CMakeFiles/untitled.dir/all] Error 2
make[1]: *** [CMakeFiles/untitled.dir/rule] Error 2
make: *** [untitled] Error 2
Saeid
  • 691
  • 7
  • 26
  • 2
    Can you add the output of a verbose make with `make VERBOSE=1`? This looks like that at the link line, -fopenmp is not passed correctly. – Michael Klemm Oct 27 '21 at 06:02
  • 1
    Despite what is written in the [highly upvoted answer](https://stackoverflow.com/a/12404666/3440745), the variable `OpenMP_EXE_LINKER_FLAGS` is never created, that is its dereference gives an empty string. Since you require CMake 3.19, it is better (and simpler) to use IMPORTED library, as described in [other answer](https://stackoverflow.com/a/51448364/3440745). – Tsyvarev Oct 27 '21 at 07:09

1 Answers1

1

By using set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}") and using set in other places, you are replacing the flags that CMAKE puts. It is better to append in this case rather than replace. You can use add_compile_options(-Wall) here.

As mentioned by @Tsyvarev, it is perhaps better to use imported library. Here are a few other ways you can use target_link_libraries.

For your particular case, it is best to replace

find_package(OpenMP REQUIRED)

where you currently have include (FindOpenMP). Further, remove the if condition as well. Finally, add the following to the end of your CMakeLists.txt file.

target_link_libraries(
  untitled
  PRIVATE
  OpenMP::OpenMP_CXX
)

Here is a good explanation of the difference between PRIVATE and PUBLIC.

Your final CMakeLists.txt file should look like:

cmake_minimum_required(VERSION 3.19)
project(untitled)

set(CMAKE_CXX_STANDARD 14)
find_package(OpenMP REQUIRED)

add_executable(
  untitled 
  main.cpp
)

target_link_libraries(
  untitled
  PRIVATE
  OpenMP::OpenMP_CXX
)

Thanks to Tsyvarev, for helping me with CMake a few months ago. Further, thanks to the answers that Tsyvarev points toward, which my answer is based on (along with my own testing).

adisidev
  • 162
  • 1
  • 15