Issue
I am using CMake and GNU's parallel algorithms and the following code snippet in my CMakeLists.txt
:
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}")
endif().
Does that make the following command redundant?
target_link_libraries(MyTarget OpenMP::OpenMP_CXX)?
I have tried to find the answer here but to no avail. Upon printing the output of the above variables using the message
command, I see that the last two are empty.
-- OpenMP_CXX_FLAGS are: -fopenmp
-- OpenMP_C_FLAGS are: -Xclang -fopenmp
-- CMAKE_EXE_LINKER_FLAGS are:
-- OpenMP_EXE_LINKER_FLAGS are:
I tried looking up the variable definition here but did not find out anything more. A small test programme using:
__gnu_parallel::for_each
ran in parallel regardless whether I included:
target_link_libraries(MyTarget OpenMP::OpenMP_CXX)
which leads me to conclude that it is not necessary. Is that true?
My gcc
is g++-9 (Homebrew GCC 9.3.0_1) 9.3.0.
Solution
While the code:
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
will update your C++ compile flags with the proper -fopenmp
option, this is an old antiquated approach.
By linking against the provided imported target OpenMP::OpenMP_CXX
, you achieve the same effect because this target provides the -fopenmp
compile option in its INTERFACE_COMPILE_OPTIONS
property. Likewise, this imported target propagates any dependent OpenMP libraries you may need (depending on the language), which would otherwise require an additional manual step of linking to ${OpenMP_CXX_LIBRARIES}
. So, linking directly to the imported target OpenMP::OpenMP_CXX
should be the preferred approach; it saves you the extra manual steps and adheres to modern CMake axioms:
target_link_libraries(MyTarget PRIVATE OpenMP::OpenMP_CXX)
Note, the official documentation for the CMake OpenMP Find Module, and the variables/targets it provides, is here.
Answered By - Kevin