
How it works
Our simple example seems to work: the code compiled and linked, and we observe a speed-up when running on multiple cores. The fact that the speed-up is not a perfect multiple of OMP_NUM_THREADS is not our concern in this recipe, since we focus on the CMake aspect of a project which requires OpenMP. We have found linking to OpenMP to be extremely compact thanks to imported targets provided by a reasonably modern FindOpenMP module:
target_link_libraries(example
PUBLIC
OpenMP::OpenMP_CXX
)
We did not have to worry about compile flags or about include directories - these settings and dependencies are encoded in the definition of the library OpenMP::OpenMP_CXX which is of the IMPORTED type. As we mentioned in Recipe 3, Building and linking static and shared libraries, in Chapter 1, From a Simple Executable to Libraries, IMPORTED libraries are pseudo-targets that fully encode usage requirements for dependencies outside our own project. To use OpenMP one needs to set compiler flags, include directories, and link libraries. All of these are set as properties on the OpenMP::OpenMP_CXX target and transitively applied to our example target simply by using the target_link_libraries command. This makes using libraries within our CMake scripts exceedingly easy. We can print the properties of interface with the cmake_print_properties command, offered by the CMakePrintHelpers.cmake standard module:
include(CMakePrintHelpers)
cmake_print_properties(
TARGETS
OpenMP::OpenMP_CXX
PROPERTIES
INTERFACE_COMPILE_OPTIONS
INTERFACE_INCLUDE_DIRECTORIES
INTERFACE_LINK_LIBRARIES
)
Note that all properties of interest have the prefix INTERFACE_, because these properties usage requirements for any target wanting to interface and use the OpenMP target.
For CMake versions below 3.9, we would have to do a bit more work:
add_executable(example example.cpp)
target_compile_options(example
PUBLIC
${OpenMP_CXX_FLAGS}
)
set_target_properties(example
PROPERTIES
LINK_FLAGS ${OpenMP_CXX_FLAGS}
)
For CMake versions below 3.5, we might need to explicitly define compile flags for a Fortran project.
In this recipe, we have discussed C++ and Fortran, but the arguments and approach are valid also for a C project.