1 # Distributed under the OSI-approved BSD 3-Clause License. See accompanying
2 # file Copyright.txt or https://cmake.org/licensing for details.
4 #[=======================================================================[.rst:
8 Finds Open Multi-Processing (OpenMP) support.
10 This module can be used to detect OpenMP support in a compiler. If
11 the compiler supports OpenMP, the flags required to compile with
12 OpenMP support are returned in variables for the different languages.
13 The variables may be empty if the compiler does not need a special
14 flag to support OpenMP.
22 .. versionadded:: 3.10
23 The module exposes the components ``C``, ``CXX``, and ``Fortran``.
24 Each of these controls the various languages to search OpenMP support for.
26 Depending on the enabled components the following variables will be set:
29 Variable indicating that OpenMP flags for all requested languages have been found.
30 If no components are specified, this is true if OpenMP settings for all enabled languages
33 Minimal version of the OpenMP standard detected among the requested languages,
34 or all enabled languages if no components were specified.
36 This module will set the following variables per language in your
37 project, where ``<lang>`` is one of C, CXX, or Fortran:
39 ``OpenMP_<lang>_FOUND``
40 Variable indicating if OpenMP support for ``<lang>`` was detected.
41 ``OpenMP_<lang>_FLAGS``
42 OpenMP compiler flags for ``<lang>``, separated by spaces.
43 ``OpenMP_<lang>_INCLUDE_DIRS``
44 Directories that must be added to the header search path for ``<lang>``
47 For linking with OpenMP code written in ``<lang>``, the following
48 variables are provided:
50 ``OpenMP_<lang>_LIB_NAMES``
51 :ref:`;-list <CMake Language Lists>` of libraries for OpenMP programs for ``<lang>``.
52 ``OpenMP_<libname>_LIBRARY``
53 Location of the individual libraries needed for OpenMP support in ``<lang>``.
54 ``OpenMP_<lang>_LIBRARIES``
55 A list of libraries needed to link with OpenMP code written in ``<lang>``.
57 Additionally, the module provides :prop_tgt:`IMPORTED` targets:
59 ``OpenMP::OpenMP_<lang>``
60 Target for using OpenMP from ``<lang>``.
62 Specifically for Fortran, the module sets the following variables:
64 ``OpenMP_Fortran_HAVE_OMPLIB_HEADER``
65 Boolean indicating if OpenMP is accessible through ``omp_lib.h``.
66 ``OpenMP_Fortran_HAVE_OMPLIB_MODULE``
67 Boolean indicating if OpenMP is accessible through the ``omp_lib`` Fortran module.
69 The module will also try to provide the OpenMP version variables:
71 ``OpenMP_<lang>_SPEC_DATE``
74 Date of the OpenMP specification implemented by the ``<lang>`` compiler.
75 ``OpenMP_<lang>_VERSION_MAJOR``
76 Major version of OpenMP implemented by the ``<lang>`` compiler.
77 ``OpenMP_<lang>_VERSION_MINOR``
78 Minor version of OpenMP implemented by the ``<lang>`` compiler.
79 ``OpenMP_<lang>_VERSION``
80 OpenMP version implemented by the ``<lang>`` compiler.
82 The specification date is formatted as given in the OpenMP standard:
83 ``yyyymm`` where ``yyyy`` and ``mm`` represents the year and month of
84 the OpenMP specification implemented by the ``<lang>`` compiler.
86 For some compilers, it may be necessary to add a header search path to find
87 the relevant OpenMP headers. This location may be language-specific. Where
88 this is needed, the module may attempt to find the location, but it can be
89 provided directly by setting the ``OpenMP_<lang>_INCLUDE_DIR`` cache variable.
90 Note that this variable is an _input_ control to the module. Project code
91 should use the ``OpenMP_<lang>_INCLUDE_DIRS`` _output_ variable if it needs
92 to know what include directories are needed.
93 #]=======================================================================]
96 cmake_policy(SET CMP0012 NEW) # if() recognizes numbers and booleans
97 cmake_policy(SET CMP0054 NEW) # if() quoted variables not dereferenced
98 cmake_policy(SET CMP0057 NEW) # if IN_LIST
100 function(_OPENMP_FLAG_CANDIDATES LANG)
101 if(NOT OpenMP_${LANG}_FLAG)
102 unset(OpenMP_FLAG_CANDIDATES)
104 set(OMP_FLAG_GNU "-fopenmp")
105 set(OMP_FLAG_LCC "-fopenmp")
106 set(OMP_FLAG_Clang "-fopenmp=libomp" "-fopenmp=libiomp5" "-fopenmp" "-Xclang -fopenmp")
107 set(OMP_FLAG_AppleClang "-Xclang -fopenmp")
108 set(OMP_FLAG_HP "+Oopenmp")
110 set(OMP_FLAG_Intel "-Qopenmp")
111 elseif(CMAKE_${LANG}_COMPILER_ID STREQUAL "Intel" AND
112 "${CMAKE_${LANG}_COMPILER_VERSION}" VERSION_LESS "15.0.0.20140528")
113 set(OMP_FLAG_Intel "-openmp")
115 set(OMP_FLAG_Intel "-qopenmp")
117 if(CMAKE_${LANG}_COMPILER_ID STREQUAL "IntelLLVM" AND
118 "x${CMAKE_${LANG}_COMPILER_FRONTEND_VARIANT}" STREQUAL "xMSVC")
119 set(OMP_FLAG_IntelLLVM "-Qiopenmp")
121 set(OMP_FLAG_IntelLLVM "-fiopenmp")
123 set(OMP_FLAG_MSVC "-openmp")
124 set(OMP_FLAG_PathScale "-openmp")
125 set(OMP_FLAG_NAG "-openmp")
126 set(OMP_FLAG_Absoft "-openmp")
127 set(OMP_FLAG_NVHPC "-mp")
128 set(OMP_FLAG_PGI "-mp")
129 set(OMP_FLAG_Flang "-fopenmp")
130 set(OMP_FLAG_SunPro "-xopenmp")
131 set(OMP_FLAG_XL "-qsmp=omp")
132 # Cray compiler activate OpenMP with -h omp, which is enabled by default.
133 set(OMP_FLAG_Cray " " "-h omp")
134 set(OMP_FLAG_Fujitsu "-Kopenmp" "-KOMP")
135 set(OMP_FLAG_FujitsuClang "-fopenmp" "-Kopenmp")
137 # If we know the correct flags, use those
138 if(DEFINED OMP_FLAG_${CMAKE_${LANG}_COMPILER_ID})
139 set(OpenMP_FLAG_CANDIDATES "${OMP_FLAG_${CMAKE_${LANG}_COMPILER_ID}}")
140 # Fall back to reasonable default tries otherwise
142 set(OpenMP_FLAG_CANDIDATES "-openmp" "-fopenmp" "-mp" " ")
144 set(OpenMP_${LANG}_FLAG_CANDIDATES "${OpenMP_FLAG_CANDIDATES}" PARENT_SCOPE)
146 set(OpenMP_${LANG}_FLAG_CANDIDATES "${OpenMP_${LANG}_FLAG}" PARENT_SCOPE)
150 # sample openmp source code to test
151 set(OpenMP_C_CXX_TEST_SOURCE
156 omp_get_max_threads();
158 #elif defined(__HIP_DEVICE_COMPILE__)
166 # in Fortran, an implementation may provide an omp_lib.h header
167 # or omp_lib module, or both (OpenMP standard, section 3.1)
168 # Furthmore !$ is the Fortran equivalent of #ifdef _OPENMP (OpenMP standard, 2.2.2)
169 # Without the conditional compilation, some compilers (e.g. PGI) might compile OpenMP code
170 # while not actually enabling OpenMP, building code sequentially
171 set(OpenMP_Fortran_TEST_SOURCE
174 @OpenMP_Fortran_INCLUDE_LINE@
176 n = omp_get_num_threads()
181 macro(_OPENMP_PREPARE_SOURCE LANG CONTENT_ID NAME_PREFIX FULLNAME_VAR CONTENT_VAR)
182 if("${LANG}" STREQUAL "C")
183 set(${FULLNAME_VAR} "${NAME_PREFIX}.c")
184 set(${CONTENT_VAR} "${OpenMP_C_CXX_${CONTENT_ID}}")
185 elseif("${LANG}" STREQUAL "CXX")
186 set(${FULLNAME_VAR} "${NAME_PREFIX}.cpp")
187 set(${CONTENT_VAR} "${OpenMP_C_CXX_${CONTENT_ID}}")
188 elseif("${LANG}" STREQUAL "Fortran")
189 set(${FULLNAME_VAR} "${NAME_PREFIX}.F90")
190 string(CONFIGURE "${OpenMP_Fortran_${CONTENT_ID}}" ${CONTENT_VAR} @ONLY)
194 include(${CMAKE_CURRENT_LIST_DIR}/CMakeParseImplicitLinkInfo.cmake)
196 function(_OPENMP_GET_FLAGS LANG FLAG_MODE OPENMP_FLAG_VAR OPENMP_LIB_NAMES_VAR)
197 _OPENMP_FLAG_CANDIDATES("${LANG}")
198 _OPENMP_PREPARE_SOURCE("${LANG}" TEST_SOURCE OpenMPTryFlag
199 _OPENMP_TEST_SRC_NAME _OPENMP_TEST_SRC_CONTENT)
201 unset(OpenMP_VERBOSE_COMPILE_OPTIONS)
202 separate_arguments(OpenMP_VERBOSE_OPTIONS NATIVE_COMMAND "${CMAKE_${LANG}_VERBOSE_FLAG}")
203 foreach(_VERBOSE_OPTION IN LISTS OpenMP_VERBOSE_OPTIONS)
204 if(NOT _VERBOSE_OPTION MATCHES "^-Wl,")
205 list(APPEND OpenMP_VERBOSE_COMPILE_OPTIONS ${_VERBOSE_OPTION})
209 foreach(OPENMP_FLAG IN LISTS OpenMP_${LANG}_FLAG_CANDIDATES)
210 set(OPENMP_FLAGS_TEST "${OPENMP_FLAG}")
211 if(OpenMP_VERBOSE_COMPILE_OPTIONS)
212 string(APPEND OPENMP_FLAGS_TEST " ${OpenMP_VERBOSE_COMPILE_OPTIONS}")
214 string(REGEX REPLACE "[-/=+]" "" OPENMP_PLAIN_FLAG "${OPENMP_FLAG}")
215 try_compile( OpenMP_COMPILE_RESULT_${FLAG_MODE}_${OPENMP_PLAIN_FLAG}
216 SOURCE_FROM_VAR "${_OPENMP_TEST_SRC_NAME}" _OPENMP_TEST_SRC_CONTENT
217 CMAKE_FLAGS "-DCOMPILE_DEFINITIONS:STRING=${OPENMP_FLAGS_TEST}"
218 LINK_LIBRARIES ${CMAKE_${LANG}_VERBOSE_FLAG}
219 OUTPUT_VARIABLE OpenMP_TRY_COMPILE_OUTPUT
222 if(OpenMP_COMPILE_RESULT_${FLAG_MODE}_${OPENMP_PLAIN_FLAG})
223 set("${OPENMP_FLAG_VAR}" "${OPENMP_FLAG}" PARENT_SCOPE)
225 if(CMAKE_${LANG}_VERBOSE_FLAG)
226 unset(OpenMP_${LANG}_IMPLICIT_LIBRARIES)
227 unset(OpenMP_${LANG}_IMPLICIT_LINK_DIRS)
228 unset(OpenMP_${LANG}_IMPLICIT_FWK_DIRS)
229 unset(OpenMP_${LANG}_LOG_VAR)
231 file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
232 "Detecting ${LANG} OpenMP compiler ABI info compiled with the following output:\n${OpenMP_TRY_COMPILE_OUTPUT}\n\n")
234 cmake_parse_implicit_link_info("${OpenMP_TRY_COMPILE_OUTPUT}"
235 OpenMP_${LANG}_IMPLICIT_LIBRARIES
236 OpenMP_${LANG}_IMPLICIT_LINK_DIRS
237 OpenMP_${LANG}_IMPLICIT_FWK_DIRS
238 OpenMP_${LANG}_LOG_VAR
239 "${CMAKE_${LANG}_IMPLICIT_OBJECT_REGEX}"
243 file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
244 "Parsed ${LANG} OpenMP implicit link information from above output:\n${OpenMP_${LANG}_LOG_VAR}\n\n")
246 # For LCC we should additionally alanyze -print-search-dirs output
247 # to check for additional implicit_dirs.
248 # Note: This won't work if CMP0129 policy is set to OLD!
249 if("${CMAKE_${LANG}_COMPILER_ID}" STREQUAL "LCC")
251 COMMAND ${CMAKE_${LANG}_COMPILER} -print-search-dirs
252 OUTPUT_VARIABLE output_lines
253 COMMAND_ERROR_IS_FATAL ANY
255 if("${output_lines}" MATCHES ".*\nlibraries:[ \t]+(.*:)\n.*")
256 string(REPLACE ":" ";" implicit_dirs_addon "${CMAKE_MATCH_1}")
257 list(PREPEND OpenMP_${LANG}_IMPLICIT_LINK_DIRS ${implicit_dirs_addon})
258 file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
259 " Extended OpenMP library search paths: [${implicit_dirs}]\n")
263 unset(_OPENMP_LIB_NAMES)
264 foreach(_OPENMP_IMPLICIT_LIB IN LISTS OpenMP_${LANG}_IMPLICIT_LIBRARIES)
265 get_filename_component(_OPENMP_IMPLICIT_LIB_DIR "${_OPENMP_IMPLICIT_LIB}" DIRECTORY)
266 get_filename_component(_OPENMP_IMPLICIT_LIB_NAME "${_OPENMP_IMPLICIT_LIB}" NAME)
267 get_filename_component(_OPENMP_IMPLICIT_LIB_PLAIN "${_OPENMP_IMPLICIT_LIB}" NAME_WE)
268 string(REGEX REPLACE "([][+.*?()^$])" "\\\\\\1" _OPENMP_IMPLICIT_LIB_PLAIN_ESC "${_OPENMP_IMPLICIT_LIB_PLAIN}")
269 string(REGEX REPLACE "([][+.*?()^$])" "\\\\\\1" _OPENMP_IMPLICIT_LIB_PATH_ESC "${_OPENMP_IMPLICIT_LIB}")
270 if(NOT ( "${_OPENMP_IMPLICIT_LIB}" IN_LIST CMAKE_${LANG}_IMPLICIT_LINK_LIBRARIES
271 OR "${CMAKE_${LANG}_STANDARD_LIBRARIES}" MATCHES "(^| )(-Wl,)?(-l)?(${_OPENMP_IMPLICIT_LIB_PLAIN_ESC}|${_OPENMP_IMPLICIT_LIB_PATH_ESC})( |$)"
272 OR "${CMAKE_${LANG}_LINK_EXECUTABLE}" MATCHES "(^| )(-Wl,)?(-l)?(${_OPENMP_IMPLICIT_LIB_PLAIN_ESC}|${_OPENMP_IMPLICIT_LIB_PATH_ESC})( |$)" ) )
273 if(_OPENMP_IMPLICIT_LIB_DIR)
274 set(OpenMP_${_OPENMP_IMPLICIT_LIB_PLAIN}_LIBRARY "${_OPENMP_IMPLICIT_LIB}" CACHE FILEPATH
275 "Path to the ${_OPENMP_IMPLICIT_LIB_PLAIN} library for OpenMP")
277 find_library(OpenMP_${_OPENMP_IMPLICIT_LIB_PLAIN}_LIBRARY
278 NAMES "${_OPENMP_IMPLICIT_LIB_NAME}"
279 DOC "Path to the ${_OPENMP_IMPLICIT_LIB_PLAIN} library for OpenMP"
280 HINTS ${OpenMP_${LANG}_IMPLICIT_LINK_DIRS}
281 CMAKE_FIND_ROOT_PATH_BOTH
284 NO_CMAKE_ENVIRONMENT_PATH
287 mark_as_advanced(OpenMP_${_OPENMP_IMPLICIT_LIB_PLAIN}_LIBRARY)
288 list(APPEND _OPENMP_LIB_NAMES ${_OPENMP_IMPLICIT_LIB_PLAIN})
291 set("${OPENMP_LIB_NAMES_VAR}" "${_OPENMP_LIB_NAMES}" PARENT_SCOPE)
293 # We do not know how to extract implicit OpenMP libraries for this compiler.
294 # Assume that it handles them automatically, e.g. the Intel Compiler on
295 # Windows should put the dependency in its object files.
296 set("${OPENMP_LIB_NAMES_VAR}" "" PARENT_SCOPE)
299 elseif(CMAKE_${LANG}_COMPILER_ID STREQUAL "AppleClang"
300 AND CMAKE_${LANG}_COMPILER_VERSION VERSION_GREATER_EQUAL "7.0")
302 # Check for separate OpenMP library on AppleClang 7+
303 find_library(OpenMP_libomp_LIBRARY
305 HINTS ${CMAKE_${LANG}_IMPLICIT_LINK_DIRECTORIES}
307 mark_as_advanced(OpenMP_libomp_LIBRARY)
309 if(OpenMP_libomp_LIBRARY)
310 # Try without specifying include directory first. We only want to
311 # explicitly add a search path if the header can't be found on the
312 # default header search path already.
313 try_compile( OpenMP_COMPILE_RESULT_${FLAG_MODE}_${OPENMP_PLAIN_FLAG}
314 SOURCE_FROM_VAR "${_OPENMP_TEST_SRC_NAME}" _OPENMP_TEST_SRC_CONTENT
315 CMAKE_FLAGS "-DCOMPILE_DEFINITIONS:STRING=${OPENMP_FLAGS_TEST}"
316 LINK_LIBRARIES ${CMAKE_${LANG}_VERBOSE_FLAG} ${OpenMP_libomp_LIBRARY}
317 OUTPUT_VARIABLE OpenMP_TRY_COMPILE_OUTPUT
319 if(NOT OpenMP_COMPILE_RESULT_${FLAG_MODE}_${OPENMP_PLAIN_FLAG})
320 find_path(OpenMP_${LANG}_INCLUDE_DIR omp.h)
321 mark_as_advanced(OpenMP_${LANG}_INCLUDE_DIR)
322 set(OpenMP_${LANG}_INCLUDE_DIR "${OpenMP_${LANG}_INCLUDE_DIR}" PARENT_SCOPE)
323 if(OpenMP_${LANG}_INCLUDE_DIR)
324 try_compile( OpenMP_COMPILE_RESULT_${FLAG_MODE}_${OPENMP_PLAIN_FLAG}
325 SOURCE_FROM_VAR "${_OPENMP_TEST_SRC_NAME}" _OPENMP_TEST_SRC_CONTENT
326 CMAKE_FLAGS "-DCOMPILE_DEFINITIONS:STRING=${OPENMP_FLAGS_TEST}"
327 "-DINCLUDE_DIRECTORIES:STRING=${OpenMP_${LANG}_INCLUDE_DIR}"
328 LINK_LIBRARIES ${CMAKE_${LANG}_VERBOSE_FLAG} ${OpenMP_libomp_LIBRARY}
329 OUTPUT_VARIABLE OpenMP_TRY_COMPILE_OUTPUT
333 if(OpenMP_COMPILE_RESULT_${FLAG_MODE}_${OPENMP_PLAIN_FLAG})
334 set("${OPENMP_FLAG_VAR}" "${OPENMP_FLAG}" PARENT_SCOPE)
335 set("${OPENMP_LIB_NAMES_VAR}" "libomp" PARENT_SCOPE)
339 elseif(CMAKE_${LANG}_COMPILER_ID STREQUAL "Clang" AND WIN32)
340 # Check for separate OpenMP library for Clang on Windows
341 find_library(OpenMP_libomp_LIBRARY
342 NAMES libomp libgomp libiomp5
343 HINTS ${CMAKE_${LANG}_IMPLICIT_LINK_DIRECTORIES}
345 mark_as_advanced(OpenMP_libomp_LIBRARY)
346 if(OpenMP_libomp_LIBRARY)
347 try_compile( OpenMP_COMPILE_RESULT_${FLAG_MODE}_${OPENMP_PLAIN_FLAG}
348 SOURCE_FROM_VAR "${_OPENMP_TEST_SRC_NAME}" _OPENMP_TEST_SRC_CONTENT
349 CMAKE_FLAGS "-DCOMPILE_DEFINITIONS:STRING=${OPENMP_FLAGS_TEST}"
350 LINK_LIBRARIES ${CMAKE_${LANG}_VERBOSE_FLAG} ${OpenMP_libomp_LIBRARY}
351 OUTPUT_VARIABLE OpenMP_TRY_COMPILE_OUTPUT
353 if(OpenMP_COMPILE_RESULT_${FLAG_MODE}_${OPENMP_PLAIN_FLAG})
354 set("${OPENMP_FLAG_VAR}" "${OPENMP_FLAG}" PARENT_SCOPE)
355 set("${OPENMP_LIB_NAMES_VAR}" "libomp" PARENT_SCOPE)
360 file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
361 "Detecting ${LANG} OpenMP failed with the following output:\n${OpenMP_TRY_COMPILE_OUTPUT}\n\n")
363 set("${OPENMP_LIB_NAMES_VAR}" "NOTFOUND" PARENT_SCOPE)
364 set("${OPENMP_FLAG_VAR}" "NOTFOUND" PARENT_SCOPE)
367 unset(OpenMP_VERBOSE_COMPILE_OPTIONS)
370 set(OpenMP_C_CXX_CHECK_VERSION_SOURCE
374 const char ompver_str[] = { 'I', 'N', 'F', 'O', ':', 'O', 'p', 'e', 'n', 'M',
375 'P', '-', 'd', 'a', 't', 'e', '[',
376 ('0' + ((_OPENMP/100000)%10)),
377 ('0' + ((_OPENMP/10000)%10)),
378 ('0' + ((_OPENMP/1000)%10)),
379 ('0' + ((_OPENMP/100)%10)),
380 ('0' + ((_OPENMP/10)%10)),
381 ('0' + ((_OPENMP/1)%10)),
390 set(OpenMP_Fortran_CHECK_VERSION_SOURCE
393 @OpenMP_Fortran_INCLUDE_LINE@
394 integer, parameter :: zero = ichar('0')
395 integer, parameter :: ompv = openmp_version
396 character, dimension(24), parameter :: ompver_str =&
397 (/ 'I', 'N', 'F', 'O', ':', 'O', 'p', 'e', 'n', 'M', 'P', '-',&
398 'd', 'a', 't', 'e', '[',&
399 char(zero + mod(ompv/100000, 10)),&
400 char(zero + mod(ompv/10000, 10)),&
401 char(zero + mod(ompv/1000, 10)),&
402 char(zero + mod(ompv/100, 10)),&
403 char(zero + mod(ompv/10, 10)),&
404 char(zero + mod(ompv/1, 10)), ']' /)
409 function(_OPENMP_GET_SPEC_DATE LANG SPEC_DATE)
410 _OPENMP_PREPARE_SOURCE("${LANG}" CHECK_VERSION_SOURCE OpenMPCheckVersion
411 _OPENMP_TEST_SRC_NAME _OPENMP_TEST_SRC_CONTENT)
413 unset(_includeDirFlags)
414 if(OpenMP_${LANG}_INCLUDE_DIR)
415 set(_includeDirFlags "-DINCLUDE_DIRECTORIES:STRING=${OpenMP_${LANG}_INCLUDE_DIR}")
418 set(BIN_FILE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/FindOpenMP/ompver_${LANG}.bin")
419 string(REGEX REPLACE "[-/=+]" "" OPENMP_PLAIN_FLAG "${OPENMP_FLAG}")
420 try_compile(OpenMP_SPECTEST_${LANG}_${OPENMP_PLAIN_FLAG}
421 SOURCE_FROM_VAR "${_OPENMP_TEST_SRC_NAME}" _OPENMP_TEST_SRC_CONTENT
422 CMAKE_FLAGS "-DCOMPILE_DEFINITIONS:STRING=${OpenMP_${LANG}_FLAGS}" ${_includeDirFlags}
423 COPY_FILE "${BIN_FILE}"
424 OUTPUT_VARIABLE OpenMP_TRY_COMPILE_OUTPUT)
426 if(${OpenMP_SPECTEST_${LANG}_${OPENMP_PLAIN_FLAG}})
427 file(STRINGS ${BIN_FILE} specstr LIMIT_COUNT 1 REGEX "INFO:OpenMP-date")
428 set(regex_spec_date ".*INFO:OpenMP-date\\[0*([^]]*)\\].*")
429 if("${specstr}" MATCHES "${regex_spec_date}")
430 set(${SPEC_DATE} "${CMAKE_MATCH_1}" PARENT_SCOPE)
433 file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
434 "Detecting ${LANG} OpenMP version failed with the following output:\n${OpenMP_TRY_COMPILE_OUTPUT}\n\n")
438 macro(_OPENMP_SET_VERSION_BY_SPEC_DATE LANG)
439 set(OpenMP_SPEC_DATE_MAP
441 "201611=5.0" # OpenMP 5.0 preview 1
442 # Combined versions, 2.5 onwards
451 # Fortran version 2.0
453 # Fortran version 1.1
455 # C/C++ version 1.0 (there's no 1.1 for C/C++)
457 # Fortran version 1.0
461 list(APPEND OpenMP_SPEC_DATE_MAP "2019=2.0")
464 if(OpenMP_${LANG}_SPEC_DATE)
465 string(REGEX MATCHALL "${OpenMP_${LANG}_SPEC_DATE}=([0-9]+)\\.([0-9]+)" _version_match "${OpenMP_SPEC_DATE_MAP}")
467 set(_version_match "")
469 if(NOT _version_match STREQUAL "")
470 set(OpenMP_${LANG}_VERSION_MAJOR ${CMAKE_MATCH_1})
471 set(OpenMP_${LANG}_VERSION_MINOR ${CMAKE_MATCH_2})
472 set(OpenMP_${LANG}_VERSION "${OpenMP_${LANG}_VERSION_MAJOR}.${OpenMP_${LANG}_VERSION_MINOR}")
474 unset(OpenMP_${LANG}_VERSION_MAJOR)
475 unset(OpenMP_${LANG}_VERSION_MINOR)
476 unset(OpenMP_${LANG}_VERSION)
478 unset(_version_match)
479 unset(OpenMP_SPEC_DATE_MAP)
482 foreach(LANG IN ITEMS C CXX)
483 if(CMAKE_${LANG}_COMPILER_LOADED)
484 if(NOT DEFINED OpenMP_${LANG}_FLAGS OR "${OpenMP_${LANG}_FLAGS}" STREQUAL "NOTFOUND"
485 OR NOT DEFINED OpenMP_${LANG}_LIB_NAMES OR "${OpenMP_${LANG}_LIB_NAMES}" STREQUAL "NOTFOUND")
486 _OPENMP_GET_FLAGS("${LANG}" "${LANG}" OpenMP_${LANG}_FLAGS_WORK OpenMP_${LANG}_LIB_NAMES_WORK)
487 if(NOT DEFINED OpenMP_${LANG}_FLAGS OR "${OpenMP_${LANG}_FLAGS}" STREQUAL "NOTFOUND")
488 set(OpenMP_${LANG}_FLAGS "${OpenMP_${LANG}_FLAGS_WORK}"
489 CACHE STRING "${LANG} compiler flags for OpenMP parallelization" FORCE)
491 if(NOT DEFINED OpenMP_${LANG}_LIB_NAMES OR "${OpenMP_${LANG}_LIB_NAMES}" STREQUAL "NOTFOUND")
492 set(OpenMP_${LANG}_LIB_NAMES "${OpenMP_${LANG}_LIB_NAMES_WORK}"
493 CACHE STRING "${LANG} compiler libraries for OpenMP parallelization" FORCE)
495 mark_as_advanced(OpenMP_${LANG}_FLAGS OpenMP_${LANG}_LIB_NAMES)
500 if(CMAKE_Fortran_COMPILER_LOADED)
501 if(NOT DEFINED OpenMP_Fortran_FLAGS OR "${OpenMP_Fortran_FLAGS}" STREQUAL "NOTFOUND"
502 OR NOT DEFINED OpenMP_Fortran_LIB_NAMES OR "${OpenMP_Fortran_LIB_NAMES}" STREQUAL "NOTFOUND"
503 OR NOT DEFINED OpenMP_Fortran_HAVE_OMPLIB_MODULE)
504 set(OpenMP_Fortran_INCLUDE_LINE "use omp_lib\n implicit none")
505 _OPENMP_GET_FLAGS("Fortran" "FortranHeader" OpenMP_Fortran_FLAGS_WORK OpenMP_Fortran_LIB_NAMES_WORK)
506 if(OpenMP_Fortran_FLAGS_WORK)
507 set(OpenMP_Fortran_HAVE_OMPLIB_MODULE TRUE CACHE BOOL INTERNAL "")
510 if(NOT DEFINED OpenMP_Fortran_FLAGS OR "${OpenMP_Fortran_FLAGS}" STREQUAL "NOTFOUND")
511 set(OpenMP_Fortran_FLAGS "${OpenMP_Fortran_FLAGS_WORK}"
512 CACHE STRING "Fortran compiler flags for OpenMP parallelization" FORCE)
514 if(NOT DEFINED OpenMP_Fortran_LIB_NAMES OR "${OpenMP_Fortran_LIB_NAMES}" STREQUAL "NOTFOUND")
515 set(OpenMP_Fortran_LIB_NAMES "${OpenMP_Fortran_LIB_NAMES_WORK}"
516 CACHE STRING "Fortran compiler libraries for OpenMP parallelization" FORCE)
518 mark_as_advanced(OpenMP_Fortran_FLAGS OpenMP_Fortran_LIB_NAMES)
521 if(NOT DEFINED OpenMP_Fortran_FLAGS OR "${OpenMP_Fortran_FLAGS}" STREQUAL "NOTFOUND"
522 OR NOT DEFINED OpenMP_Fortran_LIB_NAMES OR "${OpenMP_Fortran_LIB_NAMES}" STREQUAL "NOTFOUND"
523 OR NOT DEFINED OpenMP_Fortran_HAVE_OMPLIB_HEADER)
524 set(OpenMP_Fortran_INCLUDE_LINE "implicit none\n include 'omp_lib.h'")
525 _OPENMP_GET_FLAGS("Fortran" "FortranModule" OpenMP_Fortran_FLAGS_WORK OpenMP_Fortran_LIB_NAMES_WORK)
526 if(OpenMP_Fortran_FLAGS_WORK)
527 set(OpenMP_Fortran_HAVE_OMPLIB_HEADER TRUE CACHE BOOL INTERNAL "")
530 if(NOT DEFINED OpenMP_Fortran_FLAGS OR "${OpenMP_Fortran_FLAGS}" STREQUAL "NOTFOUND")
531 set(OpenMP_Fortran_FLAGS "${OpenMP_Fortran_FLAGS_WORK}"
532 CACHE STRING "Fortran compiler flags for OpenMP parallelization" FORCE)
534 if(NOT DEFINED OpenMP_Fortran_LIB_NAMES OR "${OpenMP_Fortran_LIB_NAMES}" STREQUAL "NOTFOUND")
535 set(OpenMP_Fortran_LIB_NAMES "${OpenMP_Fortran_LIB_NAMES_WORK}"
536 CACHE STRING "Fortran compiler libraries for OpenMP parallelization" FORCE)
540 if(OpenMP_Fortran_HAVE_OMPLIB_MODULE)
541 set(OpenMP_Fortran_INCLUDE_LINE "use omp_lib\n implicit none")
543 set(OpenMP_Fortran_INCLUDE_LINE "implicit none\n include 'omp_lib.h'")
547 if(NOT OpenMP_FIND_COMPONENTS)
548 set(OpenMP_FINDLIST C CXX Fortran)
550 set(OpenMP_FINDLIST ${OpenMP_FIND_COMPONENTS})
553 unset(_OpenMP_MIN_VERSION)
555 include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
557 foreach(LANG IN LISTS OpenMP_FINDLIST)
558 if(CMAKE_${LANG}_COMPILER_LOADED)
559 if (NOT OpenMP_${LANG}_SPEC_DATE AND OpenMP_${LANG}_FLAGS)
560 _OPENMP_GET_SPEC_DATE("${LANG}" OpenMP_${LANG}_SPEC_DATE_INTERNAL)
561 set(OpenMP_${LANG}_SPEC_DATE "${OpenMP_${LANG}_SPEC_DATE_INTERNAL}" CACHE
562 INTERNAL "${LANG} compiler's OpenMP specification date")
564 _OPENMP_SET_VERSION_BY_SPEC_DATE("${LANG}")
566 set(OpenMP_${LANG}_FIND_QUIETLY ${OpenMP_FIND_QUIETLY})
567 set(OpenMP_${LANG}_FIND_REQUIRED ${OpenMP_FIND_REQUIRED})
568 set(OpenMP_${LANG}_FIND_VERSION ${OpenMP_FIND_VERSION})
569 set(OpenMP_${LANG}_FIND_VERSION_EXACT ${OpenMP_FIND_VERSION_EXACT})
571 set(_OPENMP_${LANG}_REQUIRED_VARS OpenMP_${LANG}_FLAGS)
572 if("${OpenMP_${LANG}_LIB_NAMES}" STREQUAL "NOTFOUND")
573 set(_OPENMP_${LANG}_REQUIRED_LIB_VARS OpenMP_${LANG}_LIB_NAMES)
575 foreach(_OPENMP_IMPLICIT_LIB IN LISTS OpenMP_${LANG}_LIB_NAMES)
576 list(APPEND _OPENMP_${LANG}_REQUIRED_LIB_VARS OpenMP_${_OPENMP_IMPLICIT_LIB}_LIBRARY)
580 find_package_handle_standard_args(OpenMP_${LANG}
582 REQUIRED_VARS OpenMP_${LANG}_FLAGS ${_OPENMP_${LANG}_REQUIRED_LIB_VARS}
583 VERSION_VAR OpenMP_${LANG}_VERSION
586 if(OpenMP_${LANG}_FOUND)
587 if(DEFINED OpenMP_${LANG}_VERSION)
588 if(NOT _OpenMP_MIN_VERSION OR _OpenMP_MIN_VERSION VERSION_GREATER OpenMP_${LANG}_VERSION)
589 set(_OpenMP_MIN_VERSION OpenMP_${LANG}_VERSION)
592 set(OpenMP_${LANG}_LIBRARIES "")
593 foreach(_OPENMP_IMPLICIT_LIB IN LISTS OpenMP_${LANG}_LIB_NAMES)
594 list(APPEND OpenMP_${LANG}_LIBRARIES "${OpenMP_${_OPENMP_IMPLICIT_LIB}_LIBRARY}")
596 if(OpenMP_${LANG}_INCLUDE_DIR)
597 set(OpenMP_${LANG}_INCLUDE_DIRS ${OpenMP_${LANG}_INCLUDE_DIR})
599 set(OpenMP_${LANG}_INCLUDE_DIRS "")
602 if(NOT TARGET OpenMP::OpenMP_${LANG})
603 add_library(OpenMP::OpenMP_${LANG} INTERFACE IMPORTED)
605 if(OpenMP_${LANG}_FLAGS)
606 separate_arguments(_OpenMP_${LANG}_OPTIONS NATIVE_COMMAND "${OpenMP_${LANG}_FLAGS}")
607 set_property(TARGET OpenMP::OpenMP_${LANG} PROPERTY
608 INTERFACE_COMPILE_OPTIONS "$<$<COMPILE_LANGUAGE:${LANG}>:${_OpenMP_${LANG}_OPTIONS}>")
609 if(CMAKE_${LANG}_COMPILER_ID STREQUAL "Fujitsu"
610 OR ${CMAKE_${LANG}_COMPILER_ID} STREQUAL "IntelLLVM")
611 set_property(TARGET OpenMP::OpenMP_${LANG} PROPERTY
612 INTERFACE_LINK_OPTIONS "${OpenMP_${LANG}_FLAGS}")
614 unset(_OpenMP_${LANG}_OPTIONS)
616 if(OpenMP_${LANG}_INCLUDE_DIRS)
617 set_property(TARGET OpenMP::OpenMP_${LANG} PROPERTY
618 INTERFACE_INCLUDE_DIRECTORIES "$<BUILD_INTERFACE:${OpenMP_${LANG}_INCLUDE_DIRS}>")
620 if(OpenMP_${LANG}_LIBRARIES)
621 set_property(TARGET OpenMP::OpenMP_${LANG} PROPERTY
622 INTERFACE_LINK_LIBRARIES "${OpenMP_${LANG}_LIBRARIES}")
628 unset(_OpenMP_REQ_VARS)
629 foreach(LANG IN ITEMS C CXX Fortran)
630 if((NOT OpenMP_FIND_COMPONENTS AND CMAKE_${LANG}_COMPILER_LOADED) OR LANG IN_LIST OpenMP_FIND_COMPONENTS)
631 list(APPEND _OpenMP_REQ_VARS "OpenMP_${LANG}_FOUND")
635 find_package_handle_standard_args(OpenMP
636 REQUIRED_VARS ${_OpenMP_REQ_VARS}
637 VERSION_VAR ${_OpenMP_MIN_VERSION}
640 set(OPENMP_FOUND ${OpenMP_FOUND})
642 if(CMAKE_Fortran_COMPILER_LOADED AND OpenMP_Fortran_FOUND)
643 if(NOT DEFINED OpenMP_Fortran_HAVE_OMPLIB_MODULE)
644 set(OpenMP_Fortran_HAVE_OMPLIB_MODULE FALSE CACHE BOOL INTERNAL "")
646 if(NOT DEFINED OpenMP_Fortran_HAVE_OMPLIB_HEADER)
647 set(OpenMP_Fortran_HAVE_OMPLIB_HEADER FALSE CACHE BOOL INTERNAL "")
651 if(NOT ( CMAKE_C_COMPILER_LOADED OR CMAKE_CXX_COMPILER_LOADED OR CMAKE_Fortran_COMPILER_LOADED ))
652 message(SEND_ERROR "FindOpenMP requires the C, CXX or Fortran languages to be enabled")
655 unset(OpenMP_C_CXX_TEST_SOURCE)
656 unset(OpenMP_Fortran_TEST_SOURCE)
657 unset(OpenMP_C_CXX_CHECK_VERSION_SOURCE)
658 unset(OpenMP_Fortran_CHECK_VERSION_SOURCE)
659 unset(OpenMP_Fortran_INCLUDE_LINE)