1

I am currently trying to compile a project on Mac using cmake, but running into trouble. I have already looked at this article [1], but am still running into some trouble. My CMakeLists.txt looks as follows.

project(tpch_framework)

# enable c++11
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

set(CMAKE_BUILD_TYPE "Release")

set(CMAKE_C_COMPILER "/usr/local/Cellar/llvm/10.0.0_3/bin/clang")
set(CMAKE_CXX_COMPILER "/usr/local/Cellar/llvm/10.0.0_3/bin/clang++")
set(OPENMP_LIBRARIES "/usr/local/Cellar/llvm/10.0.0_3/lib")
set(OPENMP_INCLUDES "/usr/local/Cellar/llvm/10.0.0_3/include")

OPTION (USE_OpenMP "Use OpenMP to enamble <omp.h>" ON)

# Find OpenMP
if(APPLE AND USE_OpenMP)
    if(CMAKE_C_COMPILER_ID MATCHES "Clang")
        set(OpenMP_C_FLAGS "-Xpreprocessor -fopenmp")
        set(OpenMP_C_LIB_NAMES "omp")
        set(OpenMP_omp_LIBRARY omp)
    endif()
    if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
        set(OpenMP_CXX_FLAGS "-Xpreprocessor -fopenmp")
        set(OpenMP_CXX_LIB_NAMES "omp")
        set(OpenMP_omp_LIBRARY omp)
    endif()
endif()

if(USE_OpenMP)
  find_package(OpenMP REQUIRED)
endif(USE_OpenMP)

if (OPENMP_FOUND)
    include_directories("${OPENMP_INCLUDES}")
    link_directories("${OPENMP_LIBRARIES}")
    set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS} -libomp")
    set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS} -libomp")
    set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}")
endif(OPENMP_FOUND)

# Configure required Boost libraries
set(BOOST_ROOT "" CACHE PATH "Boost build root (useful on Windows)")
option(Boost_USE_STATIC_LIBS
       "Search for static boost libs" OFF)
option(Boost_USE_MULTITHREADED
       "Search for multithreaded boost libs" ON)
option(Boost_USE_STATIC_RUNTIME
       "Search for boost libs linked against static C++ runtime" OFF)
find_package(Boost 1.47.0 REQUIRED filesystem system)

# ensure that dependant libraries not explicitly specified here
# are found by the linker:
link_directories(${Boost_LIBRARY_DIRS})
include_directories(${Boost_INCLUDE_DIRS})
set(LIBS ${LIBS} ${Boost_LIBRARIES})
 
#Bring the headers into the project
include_directories(include)
  
FILE(GLOB_RECURSE INC_ALL "include/*.hpp")

#However, the file(GLOB...) allows for wildcard additions:
file(GLOB SOURCES "src/*.cpp")
 
add_library(tpch_framework ${SOURCES})
add_executable(framework main.cpp ${INC_ALL})
target_link_libraries(framework tpch_framework)
#target_link_libraries(framework stdc++fs)
target_link_libraries(framework ${LIBS})

When I execute this, I get the following output.

-- The C compiler identification is AppleClang 11.0.0.11000033
-- The CXX compiler identification is AppleClang 11.0.0.11000033
-- Check for working C compiler: /Library/Developer/CommandLineTools/usr/bin/cc
-- Check for working C compiler: /Library/Developer/CommandLineTools/usr/bin/cc - works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /Library/Developer/CommandLineTools/usr/bin/c++
-- Check for working CXX compiler: /Library/Developer/CommandLineTools/usr/bin/c++ - works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Found OpenMP_C: -Xpreprocessor -fopenmp  
-- Found OpenMP_CXX: -Xpreprocessor -fopenmp  
-- Found OpenMP: TRUE   
-- Found Boost: /usr/local/lib/cmake/Boost-1.72.0/BoostConfig.cmake (found suitable version "1.72.0", minimum required is "1.47.0") found components: filesystem system 
-- Configuring done
-- Generating done
-- Build files have been written to: /Users/...

However, when I then use make, I get the following error.

/Users/myname/Desktop/Uni/MHD/tpch_framework_challenge_mhd_2020/src/task4.cpp:48:5: error: use of undeclared identifier 'omp_set_num_threads'
    omp_set_num_threads(4);

Which I am guessing comes, as I get this warning: clang-10: warning: -libomp: 'linker' input unused [-Wunused-command-line-argument].

Does anybody have any ideas? I have been stuck with this for way too long and would appreciate any tips.

Kind regards, Moritz

  • What version of CMake are you using? From your Lists file it looks like you're using 2.x, which is almost a decade old at this point! – Alex Reinking Jun 26 '20 at 22:18
  • 1
    `cmake version 3.17.0` I just don't have much experience using cmake and was going off of what I was given and made some adjustments from what I found on SO. – Moritz Ruge Jun 27 '20 at 08:54

1 Answers1

0

If you can use a recent version of CMake, this build should work.

# NOTE: Every top-level CMakeLists.txt must start with these two lines
cmake_minimum_required(VERSION 3.16)
project(tpch_framework)

## Enable C++14
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

## Find dependencies

# OpenMP
find_package(OpenMP REQUIRED)

# Boost
set(BOOST_ROOT "" CACHE PATH "Boost build root (useful on Windows)")
option(Boost_USE_STATIC_LIBS
       "Search for static boost libs" OFF)
option(Boost_USE_MULTITHREADED
       "Search for multithreaded boost libs" ON)
option(Boost_USE_STATIC_RUNTIME
       "Search for boost libs linked against static C++ runtime" OFF)
find_package(Boost 1.47.0 REQUIRED COMPONENTS filesystem system)

## Add main project targets

# NOTE: This is completely wrong and will break incremental builds after
#       doing a "git pull" or similar. You should never glob for source
#       files, but instead list them explicitly.
file(GLOB SOURCES "src/*.cpp")
 
add_library(tpch_framework ${SOURCES})
target_include_directories(tpch_framework PUBLIC BUILD_INTERFACE:include)
target_link_libraries(tpch_framework
                      PUBLIC
                      OpenMP::OpenMP_CXX
                      Boost::boost 
                      Boost::filesystem
                      Boost::system)

add_executable(framework main.cpp)
target_link_libraries(framework PRIVATE tpch_framework)

There is so much bad CMake advice here on SO and in tutorials, it's a real shame.

Alex Reinking
  • 16,724
  • 5
  • 52
  • 86
  • Hey Alex. Thanks for your help, but sadly it didn't work, I'm getting the following output: ``` CMake Error at CMakeLists.txt:39 (add_executable): Target "framework" links to target "OpenMP::OpenMP" but the target was not found. Perhaps a find_package() call is missing for an IMPORTED target, or an ALIAS target is missing? CMake Error at CMakeLists.txt:30 (add_library): Target "tpch_framework" links to target "OpenMP::OpenMP" but the target was not found. Perhaps a find_package() call is missing for an IMPORTED target, or an ALIAS target is missing? ``` – Moritz Ruge Jun 27 '20 at 08:50
  • I believe, that the key is the warning mentioned at the end of the question `clang-10: warning: -libomp: 'linker' input unused [-Wunused-command-line-argument]`, as small test program needs this flag to compile. Any thoughts? – Moritz Ruge Jun 27 '20 at 08:52
  • Oops. Should be OpenMP::OpenMP_CXX – Alex Reinking Jun 27 '20 at 08:54
  • Thanks, however now I'm getting the same error as before `error: use of undeclared identifier 'omp_set_num_threads' omp_set_num_threads(4);` How could I explicitly add flags `-Xpreprocessor -lomp`? – Moritz Ruge Jun 27 '20 at 09:02
  • That flag makes no sense. That would pass a linker flag, `-lomp` to the preprocessor, which would do nothing and would probably generate a warning or error. Maybe even the warning you refer to above... – Alex Reinking Jun 27 '20 at 09:05
  • Can you post the actual compiler command line that CMake is running? – Alex Reinking Jun 27 '20 at 09:06
  • The thing is, when I compile my test file without that second flag I get the following error `g++ test.cpp -Xpreprocessor -fopenmp Undefined symbols for architecture x86_64: "___kmpc_fork_call", referenced from: _main in test-948209.o "_omp_get_thread_num", referenced from: _.omp_outlined. in test-948209.o ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation)` – Moritz Ruge Jun 27 '20 at 09:20
  • I always run CC=/usr/local/Cellar/gcc/9.3.0_1/bin/gcc-9 CXX=/usr/local/Cellar/gcc/9.3.0_1/bin/g++-9 cmake -DCMAKE_BUILD_TYPE=Release CMakeLists.txt make Beforehand I delete the CMakeCache.txt and do a make clean. – Moritz Ruge Jun 27 '20 at 09:22
  • So you should definitely be doing out-of-tree builds. The output in your question shows you're not using gcc, which doesn't need the `-Xpreprocessor` flag (which AppleClang does). If you can delete all the CMake-generated files and try again maybe I can help you further. We can also take this to chat, or you can find me on the [CppLang Slack](https://cpplang.now.sh/) – Alex Reinking Jun 27 '20 at 09:29
  • I just tried the CMake build above on my mac with both AppleClang 10 and the same version of GCC and both worked. So there's probably something wrong with your environment. – Alex Reinking Jun 27 '20 at 09:30
  • @MoritzRuge, GCC uses a different OpenMP runtime, called `libgomp`. OpenMP code produced by GCC shouldn't be referencing `__kmpc_fork_call`, which is a function in the LLVM OpenMP runtime. – Hristo Iliev Jun 27 '20 at 09:31
  • @HristoIliev it looks like compilers are getting mixed. – Alex Reinking Jun 27 '20 at 09:32
  • 1
    Deleting all files created by CMake did the trick. The code now compiles and I see a speedup in my code. Thanks so much for the help, it's really appreciated. – Moritz Ruge Jun 27 '20 at 10:37
  • Glad it worked out! If my answer was indeed helpful, please consider upvoting and/or accepting it. – Alex Reinking Jun 27 '20 at 10:38