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
99 cmake_policy(SET CMP0159 NEW) # file(STRINGS) with REGEX updates CMAKE_MATCH_<n>
101 function(_OPENMP_FLAG_CANDIDATES LANG)
102 if(NOT OpenMP_${LANG}_FLAG)
103 unset(OpenMP_FLAG_CANDIDATES)
105 set(OMP_FLAG_GNU "-fopenmp")
106 set(OMP_FLAG_LCC "-fopenmp")
107 set(OMP_FLAG_Clang "-fopenmp=libomp" "-fopenmp=libiomp5" "-fopenmp" "-Xclang -fopenmp")
108 set(OMP_FLAG_AppleClang "-Xclang -fopenmp")
109 set(OMP_FLAG_HP "+Oopenmp")
111 set(OMP_FLAG_Intel "-Qopenmp")
112 elseif(CMAKE_${LANG}_COMPILER_ID STREQUAL "Intel" AND
113 "${CMAKE_${LANG}_COMPILER_VERSION}" VERSION_LESS "15.0.0.20140528")
114 set(OMP_FLAG_Intel "-openmp")
116 set(OMP_FLAG_Intel "-qopenmp")
118 if(CMAKE_${LANG}_COMPILER_ID STREQUAL "IntelLLVM" AND
119 "x${CMAKE_${LANG}_COMPILER_FRONTEND_VARIANT}" STREQUAL "xMSVC")
120 set(OMP_FLAG_IntelLLVM "-Qiopenmp")
122 set(OMP_FLAG_IntelLLVM "-fiopenmp")
124 set(OMP_FLAG_MSVC "-openmp")
125 set(OMP_FLAG_PathScale "-openmp")
126 set(OMP_FLAG_NAG "-openmp")
127 set(OMP_FLAG_Absoft "-openmp")
128 set(OMP_FLAG_NVHPC "-mp")
129 set(OMP_FLAG_PGI "-mp")
130 set(OMP_FLAG_Flang "-fopenmp")
131 set(OMP_FLAG_SunPro "-xopenmp")
132 set(OMP_FLAG_XL "-qsmp=omp")
133 # Cray compiler activate OpenMP with -h omp, which is enabled by default.
134 set(OMP_FLAG_Cray " " "-h omp")
135 set(OMP_FLAG_Fujitsu "-Kopenmp" "-KOMP")
136 set(OMP_FLAG_FujitsuClang "-fopenmp" "-Kopenmp")
138 # If we know the correct flags, use those
139 if(DEFINED OMP_FLAG_${CMAKE_${LANG}_COMPILER_ID})
140 set(OpenMP_FLAG_CANDIDATES "${OMP_FLAG_${CMAKE_${LANG}_COMPILER_ID}}")
141 # Fall back to reasonable default tries otherwise
143 set(OpenMP_FLAG_CANDIDATES "-openmp" "-fopenmp" "-mp" " ")
145 set(OpenMP_${LANG}_FLAG_CANDIDATES "${OpenMP_FLAG_CANDIDATES}" PARENT_SCOPE)
147 set(OpenMP_${LANG}_FLAG_CANDIDATES "${OpenMP_${LANG}_FLAG}" PARENT_SCOPE)
151 # sample openmp source code to test
152 set(OpenMP_C_CXX_TEST_SOURCE
157 omp_get_max_threads();
159 #elif defined(__HIP_DEVICE_COMPILE__)
167 # in Fortran, an implementation may provide an omp_lib.h header
168 # or omp_lib module, or both (OpenMP standard, section 3.1)
169 # Furthmore !$ is the Fortran equivalent of #ifdef _OPENMP (OpenMP standard, 2.2.2)
170 # Without the conditional compilation, some compilers (e.g. PGI) might compile OpenMP code
171 # while not actually enabling OpenMP, building code sequentially
172 set(OpenMP_Fortran_TEST_SOURCE
175 @OpenMP_Fortran_INCLUDE_LINE@
177 n = omp_get_num_threads()
182 macro(_OPENMP_PREPARE_SOURCE LANG CONTENT_ID NAME_PREFIX FULLNAME_VAR CONTENT_VAR)
183 if("${LANG}" STREQUAL "C")
184 set(${FULLNAME_VAR} "${NAME_PREFIX}.c")
185 set(${CONTENT_VAR} "${OpenMP_C_CXX_${CONTENT_ID}}")
186 elseif("${LANG}" STREQUAL "CXX")
187 set(${FULLNAME_VAR} "${NAME_PREFIX}.cpp")
188 set(${CONTENT_VAR} "${OpenMP_C_CXX_${CONTENT_ID}}")
189 elseif("${LANG}" STREQUAL "Fortran")
190 set(${FULLNAME_VAR} "${NAME_PREFIX}.F90")
191 string(CONFIGURE "${OpenMP_Fortran_${CONTENT_ID}}" ${CONTENT_VAR} @ONLY)
195 include(${CMAKE_CURRENT_LIST_DIR}/CMakeParseImplicitLinkInfo.cmake)
197 function(_OPENMP_GET_FLAGS LANG FLAG_MODE OPENMP_FLAG_VAR OPENMP_LIB_NAMES_VAR)
198 _OPENMP_FLAG_CANDIDATES("${LANG}")
199 _OPENMP_PREPARE_SOURCE("${LANG}" TEST_SOURCE OpenMPTryFlag
200 _OPENMP_TEST_SRC_NAME _OPENMP_TEST_SRC_CONTENT)
202 unset(OpenMP_VERBOSE_COMPILE_OPTIONS)
203 separate_arguments(OpenMP_VERBOSE_OPTIONS NATIVE_COMMAND "${CMAKE_${LANG}_VERBOSE_FLAG}")
204 foreach(_VERBOSE_OPTION IN LISTS OpenMP_VERBOSE_OPTIONS)
205 if(NOT _VERBOSE_OPTION MATCHES "^-Wl,")
206 list(APPEND OpenMP_VERBOSE_COMPILE_OPTIONS ${_VERBOSE_OPTION})
210 foreach(OPENMP_FLAG IN LISTS OpenMP_${LANG}_FLAG_CANDIDATES)
211 set(OPENMP_FLAGS_TEST "${OPENMP_FLAG}")
212 if(OpenMP_VERBOSE_COMPILE_OPTIONS)
213 string(APPEND OPENMP_FLAGS_TEST " ${OpenMP_VERBOSE_COMPILE_OPTIONS}")
215 string(REGEX REPLACE "[-/=+]" "" OPENMP_PLAIN_FLAG "${OPENMP_FLAG}")
216 unset(_includeDirFlags)
217 if(OpenMP_${LANG}_INCLUDE_DIR)
218 set(_includeDirFlags "-DINCLUDE_DIRECTORIES:STRING=${OpenMP_${LANG}_INCLUDE_DIR}")
220 try_compile( OpenMP_COMPILE_RESULT_${FLAG_MODE}_${OPENMP_PLAIN_FLAG}
221 SOURCE_FROM_VAR "${_OPENMP_TEST_SRC_NAME}" _OPENMP_TEST_SRC_CONTENT
222 LOG_DESCRIPTION "Detecting ${LANG} OpenMP compiler info"
223 CMAKE_FLAGS "-DCOMPILE_DEFINITIONS:STRING=${OPENMP_FLAGS_TEST}" ${_includeDirFlags}
224 LINK_LIBRARIES ${CMAKE_${LANG}_VERBOSE_FLAG}
225 OUTPUT_VARIABLE OpenMP_TRY_COMPILE_OUTPUT
228 if(OpenMP_COMPILE_RESULT_${FLAG_MODE}_${OPENMP_PLAIN_FLAG} AND
229 NOT "${CMAKE_${LANG}_COMPILER_ID};${CMAKE_${LANG}_SIMULATE_ID}" STREQUAL "Clang;MSVC")
230 set("${OPENMP_FLAG_VAR}" "${OPENMP_FLAG}" PARENT_SCOPE)
232 if(CMAKE_${LANG}_VERBOSE_FLAG)
233 unset(OpenMP_${LANG}_IMPLICIT_LIBRARIES)
234 unset(OpenMP_${LANG}_IMPLICIT_LINK_DIRS)
235 unset(OpenMP_${LANG}_IMPLICIT_FWK_DIRS)
236 unset(OpenMP_${LANG}_LOG_VAR)
238 cmake_parse_implicit_link_info("${OpenMP_TRY_COMPILE_OUTPUT}"
239 OpenMP_${LANG}_IMPLICIT_LIBRARIES
240 OpenMP_${LANG}_IMPLICIT_LINK_DIRS
241 OpenMP_${LANG}_IMPLICIT_FWK_DIRS
242 OpenMP_${LANG}_LOG_VAR
243 "${CMAKE_${LANG}_IMPLICIT_OBJECT_REGEX}"
247 # For LCC we should additionally alanyze -print-search-dirs output
248 # to check for additional implicit_dirs.
249 # Note: This won't work if CMP0129 policy is set to OLD!
250 if("${CMAKE_${LANG}_COMPILER_ID}" STREQUAL "LCC")
252 COMMAND ${CMAKE_${LANG}_COMPILER} -print-search-dirs
253 OUTPUT_VARIABLE output_lines
254 COMMAND_ERROR_IS_FATAL ANY
256 if("${output_lines}" MATCHES ".*\nlibraries:[ \t]+(.*:)\n.*")
257 string(REPLACE ":" ";" implicit_dirs_addon "${CMAKE_MATCH_1}")
258 list(PREPEND OpenMP_${LANG}_IMPLICIT_LINK_DIRS ${implicit_dirs_addon})
259 string(APPEND OpenMP_${LANG}_LOG_VAR
260 " Extended OpenMP library search paths: [${implicit_dirs}]\n")
264 message(CONFIGURE_LOG
265 "Parsed ${LANG} OpenMP implicit link information from above output:\n${OpenMP_${LANG}_LOG_VAR}\n\n")
267 unset(_OPENMP_LIB_NAMES)
268 foreach(_OPENMP_IMPLICIT_LIB IN LISTS OpenMP_${LANG}_IMPLICIT_LIBRARIES)
269 get_filename_component(_OPENMP_IMPLICIT_LIB_DIR "${_OPENMP_IMPLICIT_LIB}" DIRECTORY)
270 get_filename_component(_OPENMP_IMPLICIT_LIB_NAME "${_OPENMP_IMPLICIT_LIB}" NAME)
271 get_filename_component(_OPENMP_IMPLICIT_LIB_PLAIN "${_OPENMP_IMPLICIT_LIB}" NAME_WE)
272 string(REGEX REPLACE "([][+.*?()^$])" "\\\\\\1" _OPENMP_IMPLICIT_LIB_PLAIN_ESC "${_OPENMP_IMPLICIT_LIB_PLAIN}")
273 string(REGEX REPLACE "([][+.*?()^$])" "\\\\\\1" _OPENMP_IMPLICIT_LIB_PATH_ESC "${_OPENMP_IMPLICIT_LIB}")
274 if(NOT ( "${_OPENMP_IMPLICIT_LIB}" IN_LIST CMAKE_${LANG}_IMPLICIT_LINK_LIBRARIES
275 OR "${CMAKE_${LANG}_STANDARD_LIBRARIES}" MATCHES "(^| )(-Wl,)?(-l)?(${_OPENMP_IMPLICIT_LIB_PLAIN_ESC}|${_OPENMP_IMPLICIT_LIB_PATH_ESC})( |$)"
276 OR "${CMAKE_${LANG}_LINK_EXECUTABLE}" MATCHES "(^| )(-Wl,)?(-l)?(${_OPENMP_IMPLICIT_LIB_PLAIN_ESC}|${_OPENMP_IMPLICIT_LIB_PATH_ESC})( |$)" ) )
277 if(_OPENMP_IMPLICIT_LIB_DIR)
278 set(OpenMP_${_OPENMP_IMPLICIT_LIB_PLAIN}_LIBRARY "${_OPENMP_IMPLICIT_LIB}" CACHE FILEPATH
279 "Path to the ${_OPENMP_IMPLICIT_LIB_PLAIN} library for OpenMP")
281 find_library(OpenMP_${_OPENMP_IMPLICIT_LIB_PLAIN}_LIBRARY
282 NAMES "${_OPENMP_IMPLICIT_LIB_NAME}"
283 DOC "Path to the ${_OPENMP_IMPLICIT_LIB_PLAIN} library for OpenMP"
284 HINTS ${OpenMP_${LANG}_IMPLICIT_LINK_DIRS}
285 CMAKE_FIND_ROOT_PATH_BOTH
288 NO_CMAKE_ENVIRONMENT_PATH
291 mark_as_advanced(OpenMP_${_OPENMP_IMPLICIT_LIB_PLAIN}_LIBRARY)
292 list(APPEND _OPENMP_LIB_NAMES ${_OPENMP_IMPLICIT_LIB_PLAIN})
295 set("${OPENMP_LIB_NAMES_VAR}" "${_OPENMP_LIB_NAMES}" PARENT_SCOPE)
297 # We do not know how to extract implicit OpenMP libraries for this compiler.
298 # Assume that it handles them automatically, e.g. the Intel Compiler on
299 # Windows should put the dependency in its object files.
300 set("${OPENMP_LIB_NAMES_VAR}" "" PARENT_SCOPE)
303 elseif((CMAKE_${LANG}_COMPILER_ID STREQUAL "AppleClang"
304 AND CMAKE_${LANG}_COMPILER_VERSION VERSION_GREATER_EQUAL "7.0") OR
305 (CMAKE_${LANG}_COMPILER_ID STREQUAL "Clang" AND APPLE))
307 # Check for separate OpenMP library on AppleClang 7+
308 find_library(OpenMP_libomp_LIBRARY
310 HINTS ${CMAKE_${LANG}_IMPLICIT_LINK_DIRECTORIES}
312 mark_as_advanced(OpenMP_libomp_LIBRARY)
314 if(OpenMP_libomp_LIBRARY)
315 # Try without specifying include directory first. We only want to
316 # explicitly add a search path if the header can't be found on the
317 # default header search path already.
318 try_compile( OpenMP_COMPILE_RESULT_${FLAG_MODE}_${OPENMP_PLAIN_FLAG}
319 SOURCE_FROM_VAR "${_OPENMP_TEST_SRC_NAME}" _OPENMP_TEST_SRC_CONTENT
320 LOG_DESCRIPTION "Trying ${LANG} OpenMP compiler with '${OpenMP_libomp_LIBRARY}'"
321 CMAKE_FLAGS "-DCOMPILE_DEFINITIONS:STRING=${OPENMP_FLAGS_TEST}"
322 LINK_LIBRARIES ${CMAKE_${LANG}_VERBOSE_FLAG} ${OpenMP_libomp_LIBRARY}
324 if(NOT OpenMP_COMPILE_RESULT_${FLAG_MODE}_${OPENMP_PLAIN_FLAG})
325 find_path(OpenMP_${LANG}_INCLUDE_DIR omp.h)
326 mark_as_advanced(OpenMP_${LANG}_INCLUDE_DIR)
327 set(OpenMP_${LANG}_INCLUDE_DIR "${OpenMP_${LANG}_INCLUDE_DIR}" PARENT_SCOPE)
328 if(OpenMP_${LANG}_INCLUDE_DIR)
329 try_compile( OpenMP_COMPILE_RESULT_${FLAG_MODE}_${OPENMP_PLAIN_FLAG}
330 SOURCE_FROM_VAR "${_OPENMP_TEST_SRC_NAME}" _OPENMP_TEST_SRC_CONTENT
331 LOG_DESCRIPTION "Trying ${LANG} OpenMP compiler with '${OpenMP_libomp_LIBRARY}' and '${OpenMP_${LANG}_INCLUDE_DIR}'"
332 CMAKE_FLAGS "-DCOMPILE_DEFINITIONS:STRING=${OPENMP_FLAGS_TEST}"
333 "-DINCLUDE_DIRECTORIES:STRING=${OpenMP_${LANG}_INCLUDE_DIR}"
334 LINK_LIBRARIES ${CMAKE_${LANG}_VERBOSE_FLAG} ${OpenMP_libomp_LIBRARY}
338 if(OpenMP_COMPILE_RESULT_${FLAG_MODE}_${OPENMP_PLAIN_FLAG})
339 set("${OPENMP_FLAG_VAR}" "${OPENMP_FLAG}" PARENT_SCOPE)
340 set("${OPENMP_LIB_NAMES_VAR}" "libomp" PARENT_SCOPE)
344 elseif(CMAKE_${LANG}_COMPILER_ID STREQUAL "Clang" AND WIN32)
345 # Check for separate OpenMP library for Clang on Windows
346 find_library(OpenMP_libomp_LIBRARY
347 NAMES libomp libgomp libiomp5
348 HINTS ${CMAKE_${LANG}_IMPLICIT_LINK_DIRECTORIES}
350 mark_as_advanced(OpenMP_libomp_LIBRARY)
351 if(OpenMP_libomp_LIBRARY)
352 try_compile( OpenMP_COMPILE_RESULT_${FLAG_MODE}_${OPENMP_PLAIN_FLAG}
353 SOURCE_FROM_VAR "${_OPENMP_TEST_SRC_NAME}" _OPENMP_TEST_SRC_CONTENT
354 LOG_DESCRIPTION "Trying ${LANG} OpenMP compiler with '${OpenMP_libomp_LIBRARY}'"
355 CMAKE_FLAGS "-DCOMPILE_DEFINITIONS:STRING=${OPENMP_FLAGS_TEST}"
356 LINK_LIBRARIES ${CMAKE_${LANG}_VERBOSE_FLAG} ${OpenMP_libomp_LIBRARY}
358 if(OpenMP_COMPILE_RESULT_${FLAG_MODE}_${OPENMP_PLAIN_FLAG})
359 set("${OPENMP_FLAG_VAR}" "${OPENMP_FLAG}" PARENT_SCOPE)
360 set("${OPENMP_LIB_NAMES_VAR}" "libomp" PARENT_SCOPE)
365 set("${OPENMP_LIB_NAMES_VAR}" "NOTFOUND" PARENT_SCOPE)
366 set("${OPENMP_FLAG_VAR}" "NOTFOUND" PARENT_SCOPE)
369 unset(OpenMP_VERBOSE_COMPILE_OPTIONS)
372 set(OpenMP_C_CXX_CHECK_VERSION_SOURCE
376 const char ompver_str[] = { 'I', 'N', 'F', 'O', ':', 'O', 'p', 'e', 'n', 'M',
377 'P', '-', 'd', 'a', 't', 'e', '[',
378 ('0' + ((_OPENMP/100000)%10)),
379 ('0' + ((_OPENMP/10000)%10)),
380 ('0' + ((_OPENMP/1000)%10)),
381 ('0' + ((_OPENMP/100)%10)),
382 ('0' + ((_OPENMP/10)%10)),
383 ('0' + ((_OPENMP/1)%10)),
392 set(OpenMP_Fortran_CHECK_VERSION_SOURCE
395 @OpenMP_Fortran_INCLUDE_LINE@
396 integer, parameter :: zero = ichar('0')
397 integer, parameter :: ompv = openmp_version
398 character, dimension(24), parameter :: ompver_str =&
399 (/ 'I', 'N', 'F', 'O', ':', 'O', 'p', 'e', 'n', 'M', 'P', '-',&
400 'd', 'a', 't', 'e', '[',&
401 char(zero + mod(ompv/100000, 10)),&
402 char(zero + mod(ompv/10000, 10)),&
403 char(zero + mod(ompv/1000, 10)),&
404 char(zero + mod(ompv/100, 10)),&
405 char(zero + mod(ompv/10, 10)),&
406 char(zero + mod(ompv/1, 10)), ']' /)
411 function(_OPENMP_GET_SPEC_DATE LANG SPEC_DATE)
412 _OPENMP_PREPARE_SOURCE("${LANG}" CHECK_VERSION_SOURCE OpenMPCheckVersion
413 _OPENMP_TEST_SRC_NAME _OPENMP_TEST_SRC_CONTENT)
415 unset(_includeDirFlags)
416 if(OpenMP_${LANG}_INCLUDE_DIR)
417 set(_includeDirFlags "-DINCLUDE_DIRECTORIES:STRING=${OpenMP_${LANG}_INCLUDE_DIR}")
420 set(BIN_FILE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/FindOpenMP/ompver_${LANG}.bin")
421 string(REGEX REPLACE "[-/=+]" "" OPENMP_PLAIN_FLAG "${OPENMP_FLAG}")
422 try_compile(OpenMP_SPECTEST_${LANG}_${OPENMP_PLAIN_FLAG}
423 SOURCE_FROM_VAR "${_OPENMP_TEST_SRC_NAME}" _OPENMP_TEST_SRC_CONTENT
424 LOG_DESCRIPTION "Detecting ${LANG} OpenMP version"
425 CMAKE_FLAGS "-DCOMPILE_DEFINITIONS:STRING=${OpenMP_${LANG}_FLAGS}" ${_includeDirFlags}
426 COPY_FILE "${BIN_FILE}"
429 if(${OpenMP_SPECTEST_${LANG}_${OPENMP_PLAIN_FLAG}})
430 file(STRINGS ${BIN_FILE} specstr LIMIT_COUNT 1 REGEX "INFO:OpenMP-date")
431 set(regex_spec_date ".*INFO:OpenMP-date\\[0*([^]]*)\\].*")
432 if("${specstr}" MATCHES "${regex_spec_date}")
433 set(${SPEC_DATE} "${CMAKE_MATCH_1}" PARENT_SCOPE)
438 macro(_OPENMP_SET_VERSION_BY_SPEC_DATE LANG)
439 set(OpenMP_SPEC_DATE_MAP
443 "201611=5.0" # OpenMP 5.0 preview 1
444 # Combined versions, 2.5 onwards
453 # Fortran version 2.0
455 # Fortran version 1.1
457 # C/C++ version 1.0 (there's no 1.1 for C/C++)
459 # Fortran version 1.0
463 list(APPEND OpenMP_SPEC_DATE_MAP "2019=2.0")
466 if(OpenMP_${LANG}_SPEC_DATE)
467 string(REGEX MATCHALL "${OpenMP_${LANG}_SPEC_DATE}=([0-9]+)\\.([0-9]+)" _version_match "${OpenMP_SPEC_DATE_MAP}")
469 set(_version_match "")
471 if(NOT _version_match STREQUAL "")
472 set(OpenMP_${LANG}_VERSION_MAJOR ${CMAKE_MATCH_1})
473 set(OpenMP_${LANG}_VERSION_MINOR ${CMAKE_MATCH_2})
474 set(OpenMP_${LANG}_VERSION "${OpenMP_${LANG}_VERSION_MAJOR}.${OpenMP_${LANG}_VERSION_MINOR}")
476 unset(OpenMP_${LANG}_VERSION_MAJOR)
477 unset(OpenMP_${LANG}_VERSION_MINOR)
478 unset(OpenMP_${LANG}_VERSION)
480 unset(_version_match)
481 unset(OpenMP_SPEC_DATE_MAP)
484 foreach(LANG IN ITEMS C CXX)
485 if(CMAKE_${LANG}_COMPILER_LOADED)
486 if(NOT DEFINED OpenMP_${LANG}_FLAGS OR "${OpenMP_${LANG}_FLAGS}" STREQUAL "NOTFOUND"
487 OR NOT DEFINED OpenMP_${LANG}_LIB_NAMES OR "${OpenMP_${LANG}_LIB_NAMES}" STREQUAL "NOTFOUND")
488 _OPENMP_GET_FLAGS("${LANG}" "${LANG}" OpenMP_${LANG}_FLAGS_WORK OpenMP_${LANG}_LIB_NAMES_WORK)
489 if(NOT DEFINED OpenMP_${LANG}_FLAGS OR "${OpenMP_${LANG}_FLAGS}" STREQUAL "NOTFOUND")
490 set(OpenMP_${LANG}_FLAGS "${OpenMP_${LANG}_FLAGS_WORK}"
491 CACHE STRING "${LANG} compiler flags for OpenMP parallelization" FORCE)
493 if(NOT DEFINED OpenMP_${LANG}_LIB_NAMES OR "${OpenMP_${LANG}_LIB_NAMES}" STREQUAL "NOTFOUND")
494 set(OpenMP_${LANG}_LIB_NAMES "${OpenMP_${LANG}_LIB_NAMES_WORK}"
495 CACHE STRING "${LANG} compiler libraries for OpenMP parallelization" FORCE)
497 mark_as_advanced(OpenMP_${LANG}_FLAGS OpenMP_${LANG}_LIB_NAMES)
502 if(CMAKE_Fortran_COMPILER_LOADED)
503 if(NOT DEFINED OpenMP_Fortran_FLAGS OR "${OpenMP_Fortran_FLAGS}" STREQUAL "NOTFOUND"
504 OR NOT DEFINED OpenMP_Fortran_LIB_NAMES OR "${OpenMP_Fortran_LIB_NAMES}" STREQUAL "NOTFOUND"
505 OR NOT DEFINED OpenMP_Fortran_HAVE_OMPLIB_MODULE)
506 set(OpenMP_Fortran_INCLUDE_LINE "use omp_lib\n implicit none")
507 _OPENMP_GET_FLAGS("Fortran" "FortranHeader" OpenMP_Fortran_FLAGS_WORK OpenMP_Fortran_LIB_NAMES_WORK)
508 if(OpenMP_Fortran_FLAGS_WORK)
509 set(OpenMP_Fortran_HAVE_OMPLIB_MODULE TRUE CACHE BOOL INTERNAL "")
512 if(NOT DEFINED OpenMP_Fortran_FLAGS OR "${OpenMP_Fortran_FLAGS}" STREQUAL "NOTFOUND")
513 set(OpenMP_Fortran_FLAGS "${OpenMP_Fortran_FLAGS_WORK}"
514 CACHE STRING "Fortran compiler flags for OpenMP parallelization" FORCE)
516 if(NOT DEFINED OpenMP_Fortran_LIB_NAMES OR "${OpenMP_Fortran_LIB_NAMES}" STREQUAL "NOTFOUND")
517 set(OpenMP_Fortran_LIB_NAMES "${OpenMP_Fortran_LIB_NAMES_WORK}"
518 CACHE STRING "Fortran compiler libraries for OpenMP parallelization" FORCE)
520 mark_as_advanced(OpenMP_Fortran_FLAGS OpenMP_Fortran_LIB_NAMES)
523 if(NOT DEFINED OpenMP_Fortran_FLAGS OR "${OpenMP_Fortran_FLAGS}" STREQUAL "NOTFOUND"
524 OR NOT DEFINED OpenMP_Fortran_LIB_NAMES OR "${OpenMP_Fortran_LIB_NAMES}" STREQUAL "NOTFOUND"
525 OR NOT DEFINED OpenMP_Fortran_HAVE_OMPLIB_HEADER)
526 set(OpenMP_Fortran_INCLUDE_LINE "implicit none\n include 'omp_lib.h'")
527 _OPENMP_GET_FLAGS("Fortran" "FortranModule" OpenMP_Fortran_FLAGS_WORK OpenMP_Fortran_LIB_NAMES_WORK)
528 if(OpenMP_Fortran_FLAGS_WORK)
529 set(OpenMP_Fortran_HAVE_OMPLIB_HEADER TRUE CACHE BOOL INTERNAL "")
532 if(NOT DEFINED OpenMP_Fortran_FLAGS OR "${OpenMP_Fortran_FLAGS}" STREQUAL "NOTFOUND")
533 set(OpenMP_Fortran_FLAGS "${OpenMP_Fortran_FLAGS_WORK}"
534 CACHE STRING "Fortran compiler flags for OpenMP parallelization" FORCE)
536 if(NOT DEFINED OpenMP_Fortran_LIB_NAMES OR "${OpenMP_Fortran_LIB_NAMES}" STREQUAL "NOTFOUND")
537 set(OpenMP_Fortran_LIB_NAMES "${OpenMP_Fortran_LIB_NAMES_WORK}"
538 CACHE STRING "Fortran compiler libraries for OpenMP parallelization" FORCE)
542 if(OpenMP_Fortran_HAVE_OMPLIB_MODULE)
543 set(OpenMP_Fortran_INCLUDE_LINE "use omp_lib\n implicit none")
545 set(OpenMP_Fortran_INCLUDE_LINE "implicit none\n include 'omp_lib.h'")
549 if(NOT OpenMP_FIND_COMPONENTS)
550 set(OpenMP_FINDLIST C CXX Fortran)
552 set(OpenMP_FINDLIST ${OpenMP_FIND_COMPONENTS})
555 unset(_OpenMP_MIN_VERSION)
557 include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
559 foreach(LANG IN LISTS OpenMP_FINDLIST)
560 if(CMAKE_${LANG}_COMPILER_LOADED)
561 if (NOT OpenMP_${LANG}_SPEC_DATE AND OpenMP_${LANG}_FLAGS)
562 _OPENMP_GET_SPEC_DATE("${LANG}" OpenMP_${LANG}_SPEC_DATE_INTERNAL)
563 set(OpenMP_${LANG}_SPEC_DATE "${OpenMP_${LANG}_SPEC_DATE_INTERNAL}" CACHE
564 INTERNAL "${LANG} compiler's OpenMP specification date")
566 _OPENMP_SET_VERSION_BY_SPEC_DATE("${LANG}")
568 set(OpenMP_${LANG}_FIND_QUIETLY ${OpenMP_FIND_QUIETLY})
569 set(OpenMP_${LANG}_FIND_REQUIRED ${OpenMP_FIND_REQUIRED})
570 set(OpenMP_${LANG}_FIND_VERSION ${OpenMP_FIND_VERSION})
571 set(OpenMP_${LANG}_FIND_VERSION_EXACT ${OpenMP_FIND_VERSION_EXACT})
573 set(_OPENMP_${LANG}_REQUIRED_VARS OpenMP_${LANG}_FLAGS)
574 if("${OpenMP_${LANG}_LIB_NAMES}" STREQUAL "NOTFOUND")
575 set(_OPENMP_${LANG}_REQUIRED_LIB_VARS OpenMP_${LANG}_LIB_NAMES)
577 foreach(_OPENMP_IMPLICIT_LIB IN LISTS OpenMP_${LANG}_LIB_NAMES)
578 list(APPEND _OPENMP_${LANG}_REQUIRED_LIB_VARS OpenMP_${_OPENMP_IMPLICIT_LIB}_LIBRARY)
582 find_package_handle_standard_args(OpenMP_${LANG}
584 REQUIRED_VARS OpenMP_${LANG}_FLAGS ${_OPENMP_${LANG}_REQUIRED_LIB_VARS}
585 VERSION_VAR OpenMP_${LANG}_VERSION
588 if(OpenMP_${LANG}_FOUND)
589 if(DEFINED OpenMP_${LANG}_VERSION)
590 if(NOT _OpenMP_MIN_VERSION OR _OpenMP_MIN_VERSION VERSION_GREATER OpenMP_${LANG}_VERSION)
591 set(_OpenMP_MIN_VERSION OpenMP_${LANG}_VERSION)
594 set(OpenMP_${LANG}_LIBRARIES "")
595 foreach(_OPENMP_IMPLICIT_LIB IN LISTS OpenMP_${LANG}_LIB_NAMES)
596 list(APPEND OpenMP_${LANG}_LIBRARIES "${OpenMP_${_OPENMP_IMPLICIT_LIB}_LIBRARY}")
598 if(OpenMP_${LANG}_INCLUDE_DIR)
599 set(OpenMP_${LANG}_INCLUDE_DIRS ${OpenMP_${LANG}_INCLUDE_DIR})
601 set(OpenMP_${LANG}_INCLUDE_DIRS "")
604 if(NOT TARGET OpenMP::OpenMP_${LANG})
605 add_library(OpenMP::OpenMP_${LANG} INTERFACE IMPORTED)
607 if(OpenMP_${LANG}_FLAGS)
608 set_property(TARGET OpenMP::OpenMP_${LANG} PROPERTY
609 INTERFACE_COMPILE_OPTIONS "$<$<COMPILE_LANGUAGE:${LANG}>:SHELL:${OpenMP_${LANG}_FLAGS}>")
610 if(CMAKE_${LANG}_COMPILER_ID STREQUAL "Fujitsu"
611 OR ${CMAKE_${LANG}_COMPILER_ID} STREQUAL "IntelLLVM")
612 set_property(TARGET OpenMP::OpenMP_${LANG} PROPERTY
613 INTERFACE_LINK_OPTIONS "SHELL:${OpenMP_${LANG}_FLAGS}")
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)