1
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
2
# file Copyright.txt or https://cmake.org/licensing for details.
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.
19
# The module exposes the components ``C``, ``CXX``, and ``Fortran``.
20
# Each of these controls the various languages to search OpenMP support for.
22
# Depending on the enabled components the following variables will be set:
25
# Variable indicating that OpenMP flags for all requested languages have been found.
26
# If no components are specified, this is true if OpenMP settings for all enabled languages
29
# Minimal version of the OpenMP standard detected among the requested languages,
30
# or all enabled languages if no components were specified.
32
# This module will set the following variables per language in your
33
# project, where ``<lang>`` is one of C, CXX, or Fortran:
35
# ``OpenMP_<lang>_FOUND``
36
# Variable indicating if OpenMP support for ``<lang>`` was detected.
37
# ``OpenMP_<lang>_FLAGS``
38
# OpenMP compiler flags for ``<lang>``, separated by spaces.
40
# For linking with OpenMP code written in ``<lang>``, the following
41
# variables are provided:
43
# ``OpenMP_<lang>_LIB_NAMES``
44
# :ref:`;-list <CMake Language Lists>` of libraries for OpenMP programs for ``<lang>``.
45
# ``OpenMP_<libname>_LIBRARY``
46
# Location of the individual libraries needed for OpenMP support in ``<lang>``.
47
# ``OpenMP_<lang>_LIBRARIES``
48
# A list of libraries needed to link with OpenMP code written in ``<lang>``.
50
# Additionally, the module provides :prop_tgt:`IMPORTED` targets:
52
# ``OpenMP::OpenMP_<lang>``
53
# Target for using OpenMP from ``<lang>``.
55
# Specifically for Fortran, the module sets the following variables:
57
# ``OpenMP_Fortran_HAVE_OMPLIB_HEADER``
58
# Boolean indicating if OpenMP is accessible through ``omp_lib.h``.
59
# ``OpenMP_Fortran_HAVE_OMPLIB_MODULE``
60
# Boolean indicating if OpenMP is accessible through the ``omp_lib`` Fortran module.
62
# The module will also try to provide the OpenMP version variables:
64
# ``OpenMP_<lang>_SPEC_DATE``
65
# Date of the OpenMP specification implemented by the ``<lang>`` compiler.
66
# ``OpenMP_<lang>_VERSION_MAJOR``
67
# Major version of OpenMP implemented by the ``<lang>`` compiler.
68
# ``OpenMP_<lang>_VERSION_MINOR``
69
# Minor version of OpenMP implemented by the ``<lang>`` compiler.
70
# ``OpenMP_<lang>_VERSION``
71
# OpenMP version implemented by the ``<lang>`` compiler.
73
# The specification date is formatted as given in the OpenMP standard:
74
# ``yyyymm`` where ``yyyy`` and ``mm`` represents the year and month of
75
# the OpenMP specification implemented by the ``<lang>`` compiler.
78
cmake_policy(SET CMP0012 NEW) # if() recognizes numbers and booleans
79
cmake_policy(SET CMP0054 NEW) # if() quoted variables not dereferenced
80
cmake_policy(SET CMP0057 NEW) # if IN_LIST
82
function(_OPENMP_FLAG_CANDIDATES LANG)
83
if(NOT OpenMP_${LANG}_FLAG)
84
unset(OpenMP_FLAG_CANDIDATES)
86
set(OMP_FLAG_GNU "-fopenmp")
87
set(OMP_FLAG_Clang "-fopenmp=libomp" "-fopenmp=libiomp5" "-fopenmp")
90
# Prefer Intel OpenMP header which can be provided by CMAKE_INCLUDE_PATH.
91
# Note that CMAKE_INCLUDE_PATH is searched before CMAKE_SYSTEM_INCLUDE_PATH (MSVC path in this case)
92
find_path(__header_dir "omp.h")
94
# AppleClang may need a header file, search for omp.h with hints to brew
96
find_path(__header_dir "omp.h" HINTS "/usr/local/include")
98
set(OMP_FLAG_AppleClang "-Xpreprocessor -fopenmp" "-Xpreprocessor -fopenmp -I${__header_dir}")
100
set(OMP_FLAG_HP "+Oopenmp")
102
set(OMP_FLAG_Intel "-Qopenmp")
103
elseif(CMAKE_${LANG}_COMPILER_ID STREQUAL "Intel" AND
104
"${CMAKE_${LANG}_COMPILER_VERSION}" VERSION_LESS "15.0.0.20140528")
105
set(OMP_FLAG_Intel "-openmp")
107
set(OMP_FLAG_Intel "-qopenmp")
109
set(OMP_FLAG_MIPSpro "-mp")
110
if(__header_dir MATCHES ".*Microsoft Visual Studio.*")
111
# MSVC header. No need to pass it as additional include.
112
set(OMP_FLAG_MSVC "-openmp:experimental" "-openmp")
114
set(OMP_FLAG_MSVC "-openmp:experimental -I${__header_dir}" "-openmp -I${__header_dir}")
116
set(OMP_FLAG_PathScale "-openmp")
117
set(OMP_FLAG_NAG "-openmp")
118
set(OMP_FLAG_Absoft "-openmp")
119
set(OMP_FLAG_PGI "-mp")
120
set(OMP_FLAG_Flang "-fopenmp")
121
set(OMP_FLAG_SunPro "-xopenmp")
122
set(OMP_FLAG_XL "-qsmp=omp")
123
# Cray compiler activate OpenMP with -h omp, which is enabled by default.
124
set(OMP_FLAG_Cray " " "-h omp")
126
# If we know the correct flags, use those
127
if(DEFINED OMP_FLAG_${CMAKE_${LANG}_COMPILER_ID})
128
set(OpenMP_FLAG_CANDIDATES "${OMP_FLAG_${CMAKE_${LANG}_COMPILER_ID}}")
129
# Fall back to reasonable default tries otherwise
131
set(OpenMP_FLAG_CANDIDATES "-openmp" "-fopenmp" "-mp" " ")
133
set(OpenMP_${LANG}_FLAG_CANDIDATES "${OpenMP_FLAG_CANDIDATES}" PARENT_SCOPE)
135
set(OpenMP_${LANG}_FLAG_CANDIDATES "${OpenMP_${LANG}_FLAG}" PARENT_SCOPE)
139
# sample openmp source code to test
140
set(OpenMP_C_CXX_TEST_SOURCE
145
omp_get_max_threads();
153
# in Fortran, an implementation may provide an omp_lib.h header
154
# or omp_lib module, or both (OpenMP standard, section 3.1)
155
# Furthmore !$ is the Fortran equivalent of #ifdef _OPENMP (OpenMP standard, 2.2.2)
156
# Without the conditional compilation, some compilers (e.g. PGI) might compile OpenMP code
157
# while not actually enabling OpenMP, building code sequentially
158
set(OpenMP_Fortran_TEST_SOURCE
161
@OpenMP_Fortran_INCLUDE_LINE@
163
n = omp_get_num_threads()
168
function(_OPENMP_WRITE_SOURCE_FILE LANG SRC_FILE_CONTENT_VAR SRC_FILE_NAME SRC_FILE_FULLPATH)
169
set(WORK_DIR ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/FindOpenMP)
170
if("${LANG}" STREQUAL "C")
171
set(SRC_FILE "${WORK_DIR}/${SRC_FILE_NAME}.c")
172
file(WRITE "${SRC_FILE}" "${OpenMP_C_CXX_${SRC_FILE_CONTENT_VAR}}")
173
elseif("${LANG}" STREQUAL "CXX")
174
set(SRC_FILE "${WORK_DIR}/${SRC_FILE_NAME}.cpp")
175
file(WRITE "${SRC_FILE}" "${OpenMP_C_CXX_${SRC_FILE_CONTENT_VAR}}")
176
elseif("${LANG}" STREQUAL "Fortran")
177
set(SRC_FILE "${WORK_DIR}/${SRC_FILE_NAME}.f90")
178
file(WRITE "${SRC_FILE}_in" "${OpenMP_Fortran_${SRC_FILE_CONTENT_VAR}}")
179
configure_file("${SRC_FILE}_in" "${SRC_FILE}" @ONLY)
181
set(${SRC_FILE_FULLPATH} "${SRC_FILE}" PARENT_SCOPE)
184
include(CMakeParseImplicitLinkInfo)
186
function(_OPENMP_GET_FLAGS LANG FLAG_MODE OPENMP_FLAG_VAR OPENMP_LIB_NAMES_VAR)
187
_OPENMP_FLAG_CANDIDATES("${LANG}")
188
_OPENMP_WRITE_SOURCE_FILE("${LANG}" "TEST_SOURCE" OpenMPTryFlag _OPENMP_TEST_SRC)
190
unset(OpenMP_VERBOSE_COMPILE_OPTIONS)
192
separate_arguments(OpenMP_VERBOSE_OPTIONS UNIX_COMMAND "${CMAKE_${LANG}_VERBOSE_FLAG}")
194
separate_arguments(OpenMP_VERBOSE_OPTIONS WINDOWS_COMMAND "${CMAKE_${LANG}_VERBOSE_FLAG}")
196
foreach(_VERBOSE_OPTION IN LISTS OpenMP_VERBOSE_OPTIONS)
197
if(NOT _VERBOSE_OPTION MATCHES "^-Wl,")
198
list(APPEND OpenMP_VERBOSE_COMPILE_OPTIONS ${_VERBOSE_OPTION})
202
foreach(OPENMP_FLAG IN LISTS OpenMP_${LANG}_FLAG_CANDIDATES)
203
set(OPENMP_FLAGS_TEST "${OPENMP_FLAG}")
204
if(OpenMP_VERBOSE_COMPILE_OPTIONS)
205
string(APPEND OPENMP_FLAGS_TEST " ${OpenMP_VERBOSE_COMPILE_OPTIONS}")
207
string(REGEX REPLACE "[-/=+]" "" OPENMP_PLAIN_FLAG "${OPENMP_FLAG}")
209
# NOTE [ Linking both MKL and OpenMP ]
211
# It is crucial not to link two `libomp` libraries together, even when they
212
# are both Intel or GNU. Otherwise, you will end up with this nasty error,
213
# and may get incorrect results.
215
# OMP: Error #15: Initializing libomp.dylib, but found libiomp5.dylib
216
# already initialized.
218
# OMP: Hint This means that multiple copies of the OpenMP runtime have
219
# been linked into the program. That is dangerous, since it can degrade
220
# performance or cause incorrect results. The best thing to do is to
221
# ensure that only a single OpenMP runtime is linked into the process,
222
# e.g. by avoiding static linking of the OpenMP runtime in any library. As
223
# an unsafe, unsupported, undocumented workaround you can set the
224
# environment variable KMP_DUPLICATE_LIB_OK=TRUE to allow the program to
225
# continue to execute, but that may cause crashes or silently produce
226
# incorrect results. For more information, please see
227
# http://openmp.llvm.org/
229
# So here, before we test each flag combination, we first try directly
230
# linking against any `libomp` MKL has linked to (if any and when MKL is
231
# specified). This allows us to do sensible things in tricky (yet common)
233
# - using `clang` (so no native GNU OpenMP), and
234
# - having `brew` `libomp` installed at `/usr/local/`, and
235
# - having `conda` `mkl` installed at `$HOME/conda/`, with includes a copy
237
# Rather than blindly picking one, we pick what ever `FindMKL.cmake` chooses
238
# to avoid conflicts.
240
# `FindMKL.cmake` calls `FindOpenMP.cmake` when trying to find `gomp` and
241
# thus will cause infinite recursion if this is not taken care of. Therefore,
242
# we record an internal flag to detect repeatedly inclusion.
244
if(NOT MKL_OPENMP_LIBRARY AND NOT IN_FIND_OMP AND BLAS STREQUAL "MKL")
245
set(IN_FIND_OMP ON CACHE BOOL "" FORCE)
246
find_package(MKL QUIET)
247
unset(IN_FIND_OMP CACHE)
250
if(MKL_OPENMP_LIBRARY)
251
# If we already link OpenMP via MKL, use that. Otherwise at run-time
252
# OpenMP will complain about being initialized twice (OMP: Error #15),
253
# can may cause incorrect behavior.
254
set(OpenMP_libomp_LIBRARY "${MKL_OPENMP_LIBRARY}" CACHE STRING "libomp location for OpenMP")
257
if (NOT OpenMP_libomp_LIBRARY)
258
find_library(OpenMP_libomp_LIBRARY
260
HINTS ${CMAKE_${LANG}_IMPLICIT_LINK_DIRECTORIES}
261
DOC "libomp location for OpenMP"
263
mark_as_advanced(OpenMP_libomp_LIBRARY)
266
if(OpenMP_libomp_LIBRARY MATCHES "iomp5")
267
set(OpenMP_libiomp5_LIBRARY "${MKL_OPENMP_LIBRARY}" CACHE STRING "libiomp5 location for OpenMP")
268
if("-fopenmp=libiomp5" IN_LIST OpenMP_${LANG}_FLAG_CANDIDATES)
269
get_filename_component(iomp5_dir "${OpenMP_libomp_LIBRARY}" DIRECTORY)
270
set(OPENMP_FLAGS_TEST "-fopenmp=libiomp5 -L${iomp5_dir}")
274
if(OpenMP_libomp_LIBRARY)
275
message(STATUS "Check OMP with lib ${OpenMP_libomp_LIBRARY} and flags ${OPENMP_FLAGS_TEST}")
276
try_compile( OpenMP_COMPILE_RESULT_${FLAG_MODE}_${OPENMP_PLAIN_FLAG} ${CMAKE_BINARY_DIR} ${_OPENMP_TEST_SRC}
277
CMAKE_FLAGS "-DCOMPILE_DEFINITIONS:STRING=${OPENMP_FLAGS_TEST}"
278
LINK_LIBRARIES ${CMAKE_${LANG}_VERBOSE_FLAG} ${OpenMP_libomp_LIBRARY}
279
OUTPUT_VARIABLE OpenMP_TRY_COMPILE_OUTPUT
281
if(OpenMP_COMPILE_RESULT_${FLAG_MODE}_${OPENMP_PLAIN_FLAG})
282
set("${OPENMP_FLAG_VAR}" "${OPENMP_FLAG}" PARENT_SCOPE)
283
if(OpenMP_libomp_LIBRARY MATCHES "iomp5")
284
set("${OPENMP_LIB_NAMES_VAR}" "libiomp5" PARENT_SCOPE)
286
set("${OPENMP_LIB_NAMES_VAR}" "libomp" PARENT_SCOPE)
290
message(WARNING "Detecting ${LANG} OpenMP compiler ABI info compiled with the following output:\n${OpenMP_TRY_COMPILE_OUTPUT}")
294
try_compile( OpenMP_COMPILE_RESULT_${FLAG_MODE}_${OPENMP_PLAIN_FLAG} ${CMAKE_BINARY_DIR} ${_OPENMP_TEST_SRC}
295
CMAKE_FLAGS "-DCOMPILE_DEFINITIONS:STRING=${OPENMP_FLAGS_TEST}"
296
LINK_LIBRARIES ${CMAKE_${LANG}_VERBOSE_FLAG}
297
OUTPUT_VARIABLE OpenMP_TRY_COMPILE_OUTPUT
300
if(OpenMP_COMPILE_RESULT_${FLAG_MODE}_${OPENMP_PLAIN_FLAG})
301
set("${OPENMP_FLAG_VAR}" "${OPENMP_FLAG}" PARENT_SCOPE)
303
if(CMAKE_${LANG}_VERBOSE_FLAG)
304
unset(OpenMP_${LANG}_IMPLICIT_LIBRARIES)
305
unset(OpenMP_${LANG}_IMPLICIT_LINK_DIRS)
306
unset(OpenMP_${LANG}_IMPLICIT_FWK_DIRS)
307
unset(OpenMP_${LANG}_LOG_VAR)
309
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
310
"Detecting ${LANG} OpenMP compiler ABI info compiled with the following output:\n${OpenMP_TRY_COMPILE_OUTPUT}\n\n")
312
cmake_parse_implicit_link_info("${OpenMP_TRY_COMPILE_OUTPUT}"
313
OpenMP_${LANG}_IMPLICIT_LIBRARIES
314
OpenMP_${LANG}_IMPLICIT_LINK_DIRS
315
OpenMP_${LANG}_IMPLICIT_FWK_DIRS
316
OpenMP_${LANG}_LOG_VAR
317
"${CMAKE_${LANG}_IMPLICIT_OBJECT_REGEX}"
320
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
321
"Parsed ${LANG} OpenMP implicit link information from above output:\n${OpenMP_${LANG}_LOG_VAR}\n\n")
323
unset(_OPENMP_LIB_NAMES)
324
foreach(_OPENMP_IMPLICIT_LIB IN LISTS OpenMP_${LANG}_IMPLICIT_LIBRARIES)
325
get_filename_component(_OPENMP_IMPLICIT_LIB_DIR "${_OPENMP_IMPLICIT_LIB}" DIRECTORY)
326
get_filename_component(_OPENMP_IMPLICIT_LIB_NAME "${_OPENMP_IMPLICIT_LIB}" NAME)
327
get_filename_component(_OPENMP_IMPLICIT_LIB_PLAIN "${_OPENMP_IMPLICIT_LIB}" NAME_WE)
328
string(REGEX REPLACE "([][+.*?()^$])" "\\\\\\1" _OPENMP_IMPLICIT_LIB_PLAIN_ESC "${_OPENMP_IMPLICIT_LIB_PLAIN}")
329
string(REGEX REPLACE "([][+.*?()^$])" "\\\\\\1" _OPENMP_IMPLICIT_LIB_PATH_ESC "${_OPENMP_IMPLICIT_LIB}")
330
if(NOT ( "${_OPENMP_IMPLICIT_LIB}" IN_LIST CMAKE_${LANG}_IMPLICIT_LINK_LIBRARIES
331
OR "${CMAKE_${LANG}_STANDARD_LIBRARIES}" MATCHES "(^| )(-Wl,)?(-l)?(${_OPENMP_IMPLICIT_LIB_PLAIN_ESC}|${_OPENMP_IMPLICIT_LIB_PATH_ESC})( |$)"
332
OR "${CMAKE_${LANG}_LINK_EXECUTABLE}" MATCHES "(^| )(-Wl,)?(-l)?(${_OPENMP_IMPLICIT_LIB_PLAIN_ESC}|${_OPENMP_IMPLICIT_LIB_PATH_ESC})( |$)" ) )
333
if(_OPENMP_IMPLICIT_LIB_DIR)
334
set(OpenMP_${_OPENMP_IMPLICIT_LIB_PLAIN}_LIBRARY "${_OPENMP_IMPLICIT_LIB}" CACHE FILEPATH
335
"Path to the ${_OPENMP_IMPLICIT_LIB_PLAIN} library for OpenMP")
337
find_library(OpenMP_${_OPENMP_IMPLICIT_LIB_PLAIN}_LIBRARY
338
NAMES "${_OPENMP_IMPLICIT_LIB_NAME}"
339
DOC "Path to the ${_OPENMP_IMPLICIT_LIB_PLAIN} library for OpenMP"
340
HINTS ${OpenMP_${LANG}_IMPLICIT_LINK_DIRS}
341
CMAKE_FIND_ROOT_PATH_BOTH
345
mark_as_advanced(OpenMP_${_OPENMP_IMPLICIT_LIB_PLAIN}_LIBRARY)
346
list(APPEND _OPENMP_LIB_NAMES ${_OPENMP_IMPLICIT_LIB_PLAIN})
349
set("${OPENMP_LIB_NAMES_VAR}" "${_OPENMP_LIB_NAMES}" PARENT_SCOPE)
351
# We do not know how to extract implicit OpenMP libraries for this compiler.
352
# Assume that it handles them automatically, e.g. the Intel Compiler on
353
# Windows should put the dependency in its object files.
354
set("${OPENMP_LIB_NAMES_VAR}" "" PARENT_SCOPE)
357
elseif((CMAKE_${LANG}_COMPILER_ID STREQUAL "AppleClang") AND
358
(NOT CMAKE_${LANG}_COMPILER_VERSION VERSION_LESS "7.0"))
360
# LLVM 3.7 supports OpenMP 3.1, and continues to add more features to
361
# support newer OpenMP standards in new versions.
362
# http://releases.llvm.org/3.7.0/tools/clang/docs/ReleaseNotes.html#openmp-support
364
# Apple Clang 7.0 is the first version based on LLVM 3.7 or later.
365
# https://en.wikipedia.org/wiki/Xcode#Latest_versions
367
# Check for separate OpenMP library on AppleClang 7+
368
find_library(OpenMP_libomp_LIBRARY
370
HINTS ${CMAKE_${LANG}_IMPLICIT_LINK_DIRECTORIES}
371
DOC "libomp location for OpenMP"
373
mark_as_advanced(OpenMP_libomp_LIBRARY)
375
if(OpenMP_libomp_LIBRARY)
376
try_compile( OpenMP_COMPILE_RESULT_${FLAG_MODE}_${OPENMP_PLAIN_FLAG} ${CMAKE_BINARY_DIR} ${_OPENMP_TEST_SRC}
377
CMAKE_FLAGS "-DCOMPILE_DEFINITIONS:STRING=${OPENMP_FLAGS_TEST}"
378
LINK_LIBRARIES ${CMAKE_${LANG}_VERBOSE_FLAG} ${OpenMP_libomp_LIBRARY}
379
OUTPUT_VARIABLE OpenMP_TRY_COMPILE_OUTPUT
381
if(OpenMP_COMPILE_RESULT_${FLAG_MODE}_${OPENMP_PLAIN_FLAG})
382
set("${OPENMP_FLAG_VAR}" "${OPENMP_FLAG}" PARENT_SCOPE)
383
set("${OPENMP_LIB_NAMES_VAR}" "libomp" PARENT_SCOPE)
388
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
389
"Detecting ${LANG} OpenMP failed with the following output:\n${OpenMP_TRY_COMPILE_OUTPUT}\n\n")
391
if (NOT ${OpenMP_${LANG}_FIND_QUIETLY})
392
message(STATUS "OpenMP try_compile log:\n${OpenMP_TRY_COMPILE_OUTPUT}\n\n")
394
set("${OPENMP_LIB_NAMES_VAR}" "NOTFOUND" PARENT_SCOPE)
395
set("${OPENMP_FLAG_VAR}" "NOTFOUND" PARENT_SCOPE)
398
unset(OpenMP_VERBOSE_COMPILE_OPTIONS)
401
set(OpenMP_C_CXX_CHECK_VERSION_SOURCE
405
const char ompver_str[] = { 'I', 'N', 'F', 'O', ':', 'O', 'p', 'e', 'n', 'M',
406
'P', '-', 'd', 'a', 't', 'e', '[',
407
('0' + ((_OPENMP/100000)%10)),
408
('0' + ((_OPENMP/10000)%10)),
409
('0' + ((_OPENMP/1000)%10)),
410
('0' + ((_OPENMP/100)%10)),
411
('0' + ((_OPENMP/10)%10)),
412
('0' + ((_OPENMP/1)%10)),
421
set(OpenMP_Fortran_CHECK_VERSION_SOURCE
424
@OpenMP_Fortran_INCLUDE_LINE@
425
integer, parameter :: zero = ichar('0')
426
integer, parameter :: ompv = openmp_version
427
character, dimension(24), parameter :: ompver_str =&
428
(/ 'I', 'N', 'F', 'O', ':', 'O', 'p', 'e', 'n', 'M', 'P', '-',&
429
'd', 'a', 't', 'e', '[',&
430
char(zero + mod(ompv/100000, 10)),&
431
char(zero + mod(ompv/10000, 10)),&
432
char(zero + mod(ompv/1000, 10)),&
433
char(zero + mod(ompv/100, 10)),&
434
char(zero + mod(ompv/10, 10)),&
435
char(zero + mod(ompv/1, 10)), ']' /)
440
function(_OPENMP_GET_SPEC_DATE LANG SPEC_DATE)
441
_OPENMP_WRITE_SOURCE_FILE("${LANG}" "CHECK_VERSION_SOURCE" OpenMPCheckVersion _OPENMP_TEST_SRC)
443
set(BIN_FILE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/FindOpenMP/ompver_${LANG}.bin")
444
string(REGEX REPLACE "[-/=+]" "" OPENMP_PLAIN_FLAG "${OPENMP_FLAG}")
445
try_compile(OpenMP_SPECTEST_${LANG}_${OPENMP_PLAIN_FLAG} "${CMAKE_BINARY_DIR}" "${_OPENMP_TEST_SRC}"
446
CMAKE_FLAGS "-DCOMPILE_DEFINITIONS:STRING=${OpenMP_${LANG}_FLAGS}"
447
COPY_FILE ${BIN_FILE}
448
OUTPUT_VARIABLE OpenMP_TRY_COMPILE_OUTPUT)
450
if(${OpenMP_SPECTEST_${LANG}_${OPENMP_PLAIN_FLAG}})
451
file(STRINGS ${BIN_FILE} specstr LIMIT_COUNT 1 REGEX "INFO:OpenMP-date")
452
set(regex_spec_date ".*INFO:OpenMP-date\\[0*([^]]*)\\].*")
453
if("${specstr}" MATCHES "${regex_spec_date}")
454
set(${SPEC_DATE} "${CMAKE_MATCH_1}" PARENT_SCOPE)
457
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
458
"Detecting ${LANG} OpenMP version failed with the following output:\n${OpenMP_TRY_COMPILE_OUTPUT}\n\n")
462
macro(_OPENMP_SET_VERSION_BY_SPEC_DATE LANG)
463
set(OpenMP_SPEC_DATE_MAP
465
"201611=5.0" # OpenMP 5.0 preview 1
466
# Combined versions, 2.5 onwards
474
# Fortran version 2.0
476
# Fortran version 1.1
478
# C/C++ version 1.0 (there's no 1.1 for C/C++)
480
# Fortran version 1.0
484
if(OpenMP_${LANG}_SPEC_DATE)
485
string(REGEX MATCHALL "${OpenMP_${LANG}_SPEC_DATE}=([0-9]+)\\.([0-9]+)" _version_match "${OpenMP_SPEC_DATE_MAP}")
487
set(_version_match "")
489
if(NOT _version_match STREQUAL "")
490
set(OpenMP_${LANG}_VERSION_MAJOR ${CMAKE_MATCH_1})
491
set(OpenMP_${LANG}_VERSION_MINOR ${CMAKE_MATCH_2})
492
set(OpenMP_${LANG}_VERSION "${OpenMP_${LANG}_VERSION_MAJOR}.${OpenMP_${LANG}_VERSION_MINOR}")
494
unset(OpenMP_${LANG}_VERSION_MAJOR)
495
unset(OpenMP_${LANG}_VERSION_MINOR)
496
unset(OpenMP_${LANG}_VERSION)
498
unset(_version_match)
499
unset(OpenMP_SPEC_DATE_MAP)
502
foreach(LANG IN ITEMS C CXX)
503
if(CMAKE_${LANG}_COMPILER_LOADED)
504
if(NOT DEFINED OpenMP_${LANG}_FLAGS OR "${OpenMP_${LANG}_FLAGS}" STREQUAL "NOTFOUND"
505
OR NOT DEFINED OpenMP_${LANG}_LIB_NAMES OR "${OpenMP_${LANG}_LIB_NAMES}" STREQUAL "NOTFOUND")
506
_OPENMP_GET_FLAGS("${LANG}" "${LANG}" OpenMP_${LANG}_FLAGS_WORK OpenMP_${LANG}_LIB_NAMES_WORK)
509
set(OpenMP_${LANG}_FLAGS "${OpenMP_${LANG}_FLAGS_WORK}"
510
CACHE STRING "${LANG} compiler flags for OpenMP parallelization")
511
set(OpenMP_${LANG}_LIB_NAMES "${OpenMP_${LANG}_LIB_NAMES_WORK}"
512
CACHE STRING "${LANG} compiler libraries for OpenMP parallelization")
513
mark_as_advanced(OpenMP_${LANG}_FLAGS OpenMP_${LANG}_LIB_NAMES)
517
if(CMAKE_Fortran_COMPILER_LOADED)
518
if(NOT DEFINED OpenMP_Fortran_FLAGS OR "${OpenMP_Fortran_FLAGS}" STREQUAL "NOTFOUND"
519
OR NOT DEFINED OpenMP_Fortran_LIB_NAMES OR "${OpenMP_Fortran_LIB_NAMES}" STREQUAL "NOTFOUND"
520
OR NOT DEFINED OpenMP_Fortran_HAVE_OMPLIB_MODULE)
521
set(OpenMP_Fortran_INCLUDE_LINE "use omp_lib\n implicit none")
522
_OPENMP_GET_FLAGS("Fortran" "FortranHeader" OpenMP_Fortran_FLAGS_WORK OpenMP_Fortran_LIB_NAMES_WORK)
523
if(OpenMP_Fortran_FLAGS_WORK)
524
set(OpenMP_Fortran_HAVE_OMPLIB_MODULE TRUE CACHE BOOL INTERNAL "")
527
set(OpenMP_Fortran_FLAGS "${OpenMP_Fortran_FLAGS_WORK}"
528
CACHE STRING "Fortran compiler flags for OpenMP parallelization")
529
set(OpenMP_Fortran_LIB_NAMES "${OpenMP_Fortran_LIB_NAMES_WORK}"
530
CACHE STRING "Fortran compiler libraries for OpenMP parallelization")
531
mark_as_advanced(OpenMP_Fortran_FLAGS OpenMP_Fortran_LIB_NAMES)
534
if(NOT DEFINED OpenMP_Fortran_FLAGS OR "${OpenMP_Fortran_FLAGS}" STREQUAL "NOTFOUND"
535
OR NOT DEFINED OpenMP_Fortran_LIB_NAMES OR "${OpenMP_Fortran_LIB_NAMES}" STREQUAL "NOTFOUND"
536
OR NOT DEFINED OpenMP_Fortran_HAVE_OMPLIB_HEADER)
537
set(OpenMP_Fortran_INCLUDE_LINE "implicit none\n include 'omp_lib.h'")
538
_OPENMP_GET_FLAGS("Fortran" "FortranModule" OpenMP_Fortran_FLAGS_WORK OpenMP_Fortran_LIB_NAMES_WORK)
539
if(OpenMP_Fortran_FLAGS_WORK)
540
set(OpenMP_Fortran_HAVE_OMPLIB_HEADER TRUE CACHE BOOL INTERNAL "")
543
set(OpenMP_Fortran_FLAGS "${OpenMP_Fortran_FLAGS_WORK}"
544
CACHE STRING "Fortran compiler flags for OpenMP parallelization")
546
set(OpenMP_Fortran_LIB_NAMES "${OpenMP_Fortran_LIB_NAMES}"
547
CACHE STRING "Fortran compiler libraries for OpenMP parallelization")
550
if(OpenMP_Fortran_HAVE_OMPLIB_MODULE)
551
set(OpenMP_Fortran_INCLUDE_LINE "use omp_lib\n implicit none")
553
set(OpenMP_Fortran_INCLUDE_LINE "implicit none\n include 'omp_lib.h'")
557
if(NOT OpenMP_FIND_COMPONENTS)
558
set(OpenMP_FINDLIST C CXX Fortran)
560
set(OpenMP_FINDLIST ${OpenMP_FIND_COMPONENTS})
563
unset(_OpenMP_MIN_VERSION)
565
include(FindPackageHandleStandardArgs)
567
foreach(LANG IN LISTS OpenMP_FINDLIST)
568
if(CMAKE_${LANG}_COMPILER_LOADED)
569
if (NOT OpenMP_${LANG}_SPEC_DATE AND OpenMP_${LANG}_FLAGS)
570
_OPENMP_GET_SPEC_DATE("${LANG}" OpenMP_${LANG}_SPEC_DATE_INTERNAL)
571
set(OpenMP_${LANG}_SPEC_DATE "${OpenMP_${LANG}_SPEC_DATE_INTERNAL}" CACHE
572
INTERNAL "${LANG} compiler's OpenMP specification date")
573
_OPENMP_SET_VERSION_BY_SPEC_DATE("${LANG}")
576
set(OpenMP_${LANG}_FIND_QUIETLY ${OpenMP_FIND_QUIETLY})
577
set(OpenMP_${LANG}_FIND_REQUIRED ${OpenMP_FIND_REQUIRED})
578
set(OpenMP_${LANG}_FIND_VERSION ${OpenMP_FIND_VERSION})
579
set(OpenMP_${LANG}_FIND_VERSION_EXACT ${OpenMP_FIND_VERSION_EXACT})
581
set(_OPENMP_${LANG}_REQUIRED_VARS OpenMP_${LANG}_FLAGS)
582
if("${OpenMP_${LANG}_LIB_NAMES}" STREQUAL "NOTFOUND")
583
set(_OPENMP_${LANG}_REQUIRED_LIB_VARS OpenMP_${LANG}_LIB_NAMES)
585
foreach(_OPENMP_IMPLICIT_LIB IN LISTS OpenMP_${LANG}_LIB_NAMES)
586
list(APPEND _OPENMP_${LANG}_REQUIRED_LIB_VARS OpenMP_${_OPENMP_IMPLICIT_LIB}_LIBRARY)
590
find_package_handle_standard_args(OpenMP_${LANG}
591
REQUIRED_VARS OpenMP_${LANG}_FLAGS ${_OPENMP_${LANG}_REQUIRED_LIB_VARS}
592
VERSION_VAR OpenMP_${LANG}_VERSION
595
if(OpenMP_${LANG}_FOUND)
596
if(DEFINED OpenMP_${LANG}_VERSION)
597
if(NOT _OpenMP_MIN_VERSION OR _OpenMP_MIN_VERSION VERSION_GREATER OpenMP_${LANG}_VERSION)
598
set(_OpenMP_MIN_VERSION OpenMP_${LANG}_VERSION)
601
set(OpenMP_${LANG}_LIBRARIES "")
602
foreach(_OPENMP_IMPLICIT_LIB IN LISTS OpenMP_${LANG}_LIB_NAMES)
603
list(APPEND OpenMP_${LANG}_LIBRARIES "${OpenMP_${_OPENMP_IMPLICIT_LIB}_LIBRARY}")
606
if(NOT TARGET OpenMP::OpenMP_${LANG})
607
add_library(OpenMP::OpenMP_${LANG} INTERFACE IMPORTED)
609
if(OpenMP_${LANG}_FLAGS)
611
separate_arguments(_OpenMP_${LANG}_OPTIONS UNIX_COMMAND "${OpenMP_${LANG}_FLAGS}")
613
separate_arguments(_OpenMP_${LANG}_OPTIONS WINDOWS_COMMAND "${OpenMP_${LANG}_FLAGS}")
615
set_property(TARGET OpenMP::OpenMP_${LANG} PROPERTY
616
INTERFACE_COMPILE_OPTIONS "$<$<COMPILE_LANGUAGE:${LANG}>:${_OpenMP_${LANG}_OPTIONS}>")
617
unset(_OpenMP_${LANG}_OPTIONS)
619
if(OpenMP_${LANG}_LIBRARIES)
620
set_property(TARGET OpenMP::OpenMP_${LANG} PROPERTY
621
INTERFACE_LINK_LIBRARIES "${OpenMP_${LANG}_LIBRARIES}")
627
unset(_OpenMP_REQ_VARS)
628
foreach(LANG IN ITEMS C CXX Fortran)
629
if((NOT OpenMP_FIND_COMPONENTS AND CMAKE_${LANG}_COMPILER_LOADED) OR LANG IN_LIST OpenMP_FIND_COMPONENTS)
630
list(APPEND _OpenMP_REQ_VARS "OpenMP_${LANG}_FOUND")
634
find_package_handle_standard_args(OpenMP
635
REQUIRED_VARS ${_OpenMP_REQ_VARS}
636
VERSION_VAR ${_OpenMP_MIN_VERSION}
639
set(OPENMP_FOUND ${OpenMP_FOUND})
641
if(CMAKE_Fortran_COMPILER_LOADED AND OpenMP_Fortran_FOUND)
642
if(NOT DEFINED OpenMP_Fortran_HAVE_OMPLIB_MODULE)
643
set(OpenMP_Fortran_HAVE_OMPLIB_MODULE FALSE CACHE BOOL INTERNAL "")
645
if(NOT DEFINED OpenMP_Fortran_HAVE_OMPLIB_HEADER)
646
set(OpenMP_Fortran_HAVE_OMPLIB_HEADER FALSE CACHE BOOL INTERNAL "")
650
if(NOT ( CMAKE_C_COMPILER_LOADED OR CMAKE_CXX_COMPILER_LOADED OR CMAKE_Fortran_COMPILER_LOADED ))
651
message(SEND_ERROR "FindOpenMP requires the C, CXX or Fortran languages to be enabled")
654
unset(OpenMP_C_CXX_TEST_SOURCE)
655
unset(OpenMP_Fortran_TEST_SOURCE)
656
unset(OpenMP_C_CXX_CHECK_VERSION_SOURCE)
657
unset(OpenMP_Fortran_CHECK_VERSION_SOURCE)
658
unset(OpenMP_Fortran_INCLUDE_LINE)