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
2
  • 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. Commented Oct 27, 2021 at 6:02
  • 1
    Despite what is written in the highly upvoted answer, 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. Commented Oct 27, 2021 at 7:09

1 Answer 1

1
+50

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

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.