FindOpenMP.cmake 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553
  1. ##=============================================================================
  2. ##
  3. ## Copyright (c) Kitware, Inc.
  4. ## All rights reserved.
  5. ## See LICENSE.txt for details.
  6. ##
  7. ## This software is distributed WITHOUT ANY WARRANTY; without even
  8. ## the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  9. ## PURPOSE. See the above copyright notice for more information.
  10. ##
  11. ## Copyright 2018 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
  12. ## Copyright 2018 UT-Battelle, LLC.
  13. ## Copyright 2018 Los Alamos National Security.
  14. ##
  15. ## Under the terms of Contract DE-NA0003525 with NTESS,
  16. ## the U.S. Government retains certain rights in this software.
  17. ## Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
  18. ## Laboratory (LANL), the U.S. Government retains certain rights in
  19. ## this software.
  20. ##
  21. ##=============================================================================
  22. #.rst:
  23. # FindOpenMP
  24. # ----------
  25. #
  26. # Finds OpenMP support
  27. #
  28. # This module can be used to detect OpenMP support in a compiler. If
  29. # the compiler supports OpenMP, the flags required to compile with
  30. # OpenMP support are returned in variables for the different languages.
  31. # The variables may be empty if the compiler does not need a special
  32. # flag to support OpenMP.
  33. #
  34. # Variables
  35. # ^^^^^^^^^
  36. #
  37. # The module exposes the components ``C``, ``CXX``, and ``Fortran``.
  38. # Each of these controls the various languages to search OpenMP support for.
  39. #
  40. # Depending on the enabled components the following variables will be set:
  41. #
  42. # ``OpenMP_FOUND``
  43. # Variable indicating that OpenMP flags for all requested languages have been found.
  44. # If no components are specified, this is true if OpenMP settings for all enabled languages
  45. # were detected.
  46. # ``OpenMP_VERSION``
  47. # Minimal version of the OpenMP standard detected among the requested languages,
  48. # or all enabled languages if no components were specified.
  49. #
  50. # This module will set the following variables per language in your
  51. # project, where ``<lang>`` is one of C, CXX, or Fortran:
  52. #
  53. # ``OpenMP_<lang>_FOUND``
  54. # Variable indicating if OpenMP support for ``<lang>`` was detected.
  55. # ``OpenMP_<lang>_FLAGS``
  56. # OpenMP compiler flags for ``<lang>``, separated by spaces.
  57. #
  58. # For linking with OpenMP code written in ``<lang>``, the following
  59. # variables are provided:
  60. #
  61. # ``OpenMP_<lang>_LIB_NAMES``
  62. # :ref:`;-list <CMake Language Lists>` of libraries for OpenMP programs for ``<lang>``.
  63. # ``OpenMP_<libname>_LIBRARY``
  64. # Location of the individual libraries needed for OpenMP support in ``<lang>``.
  65. # ``OpenMP_<lang>_LIBRARIES``
  66. # A list of libraries needed to link with OpenMP code written in ``<lang>``.
  67. #
  68. # Additionally, the module provides :prop_tgt:`IMPORTED` targets:
  69. #
  70. # ``OpenMP::OpenMP_<lang>``
  71. # Target for using OpenMP from ``<lang>``.
  72. #
  73. # Specifically for Fortran, the module sets the following variables:
  74. #
  75. # ``OpenMP_Fortran_HAVE_OMPLIB_HEADER``
  76. # Boolean indicating if OpenMP is accessible through ``omp_lib.h``.
  77. # ``OpenMP_Fortran_HAVE_OMPLIB_MODULE``
  78. # Boolean indicating if OpenMP is accessible through the ``omp_lib`` Fortran module.
  79. #
  80. # The module will also try to provide the OpenMP version variables:
  81. #
  82. # ``OpenMP_<lang>_SPEC_DATE``
  83. # Date of the OpenMP specification implemented by the ``<lang>`` compiler.
  84. # ``OpenMP_<lang>_VERSION_MAJOR``
  85. # Major version of OpenMP implemented by the ``<lang>`` compiler.
  86. # ``OpenMP_<lang>_VERSION_MINOR``
  87. # Minor version of OpenMP implemented by the ``<lang>`` compiler.
  88. # ``OpenMP_<lang>_VERSION``
  89. # OpenMP version implemented by the ``<lang>`` compiler.
  90. #
  91. # The specification date is formatted as given in the OpenMP standard:
  92. # ``yyyymm`` where ``yyyy`` and ``mm`` represents the year and month of
  93. # the OpenMP specification implemented by the ``<lang>`` compiler.
  94. cmake_minimum_required(VERSION 3.9)
  95. cmake_policy(PUSH)
  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. function(_OPENMP_FLAG_CANDIDATES LANG)
  100. if(NOT OpenMP_${LANG}_FLAG)
  101. unset(OpenMP_FLAG_CANDIDATES)
  102. set(OMP_FLAG_GNU "-fopenmp")
  103. set(OMP_FLAG_Clang "-fopenmp=libomp" "-fopenmp=libiomp5" "-fopenmp")
  104. set(OMP_FLAG_AppleClang "-Xclang -fopenmp")
  105. set(OMP_FLAG_HP "+Oopenmp")
  106. if(WIN32)
  107. set(OMP_FLAG_Intel "-Qopenmp")
  108. elseif(CMAKE_${LANG}_COMPILER_ID STREQUAL "Intel" AND
  109. "${CMAKE_${LANG}_COMPILER_VERSION}" VERSION_LESS "15.0.0.20140528")
  110. set(OMP_FLAG_Intel "-openmp")
  111. else()
  112. set(OMP_FLAG_Intel "-qopenmp")
  113. endif()
  114. set(OMP_FLAG_MIPSpro "-mp")
  115. set(OMP_FLAG_MSVC "-openmp")
  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")
  125. # If we know the correct flags, use those
  126. if(DEFINED OMP_FLAG_${CMAKE_${LANG}_COMPILER_ID})
  127. set(OpenMP_FLAG_CANDIDATES "${OMP_FLAG_${CMAKE_${LANG}_COMPILER_ID}}")
  128. # Fall back to reasonable default tries otherwise
  129. else()
  130. set(OpenMP_FLAG_CANDIDATES "-openmp" "-fopenmp" "-mp" " ")
  131. endif()
  132. set(OpenMP_${LANG}_FLAG_CANDIDATES "${OpenMP_FLAG_CANDIDATES}" PARENT_SCOPE)
  133. else()
  134. set(OpenMP_${LANG}_FLAG_CANDIDATES "${OpenMP_${LANG}_FLAG}" PARENT_SCOPE)
  135. endif()
  136. endfunction()
  137. # sample openmp source code to test
  138. set(OpenMP_C_CXX_TEST_SOURCE
  139. "
  140. #include <omp.h>
  141. int main() {
  142. #ifdef _OPENMP
  143. int n = omp_get_max_threads();
  144. return 0;
  145. #else
  146. breaks_on_purpose
  147. #endif
  148. }
  149. ")
  150. # in Fortran, an implementation may provide an omp_lib.h header
  151. # or omp_lib module, or both (OpenMP standard, section 3.1)
  152. # Furthmore !$ is the Fortran equivalent of #ifdef _OPENMP (OpenMP standard, 2.2.2)
  153. # Without the conditional compilation, some compilers (e.g. PGI) might compile OpenMP code
  154. # while not actually enabling OpenMP, building code sequentially
  155. set(OpenMP_Fortran_TEST_SOURCE
  156. "
  157. program test
  158. @OpenMP_Fortran_INCLUDE_LINE@
  159. !$ integer :: n
  160. n = omp_get_num_threads()
  161. end program test
  162. "
  163. )
  164. function(_OPENMP_WRITE_SOURCE_FILE LANG SRC_FILE_CONTENT_VAR SRC_FILE_NAME SRC_FILE_FULLPATH)
  165. set(WORK_DIR ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/FindOpenMP)
  166. if("${LANG}" STREQUAL "C")
  167. set(SRC_FILE "${WORK_DIR}/${SRC_FILE_NAME}.c")
  168. file(WRITE "${SRC_FILE}" "${OpenMP_C_CXX_${SRC_FILE_CONTENT_VAR}}")
  169. elseif("${LANG}" STREQUAL "CXX")
  170. set(SRC_FILE "${WORK_DIR}/${SRC_FILE_NAME}.cpp")
  171. file(WRITE "${SRC_FILE}" "${OpenMP_C_CXX_${SRC_FILE_CONTENT_VAR}}")
  172. elseif("${LANG}" STREQUAL "Fortran")
  173. set(SRC_FILE "${WORK_DIR}/${SRC_FILE_NAME}.f90")
  174. file(WRITE "${SRC_FILE}_in" "${OpenMP_Fortran_${SRC_FILE_CONTENT_VAR}}")
  175. configure_file("${SRC_FILE}_in" "${SRC_FILE}" @ONLY)
  176. endif()
  177. set(${SRC_FILE_FULLPATH} "${SRC_FILE}" PARENT_SCOPE)
  178. endfunction()
  179. include(CMakeParseImplicitLinkInfo)
  180. function(_OPENMP_GET_FLAGS LANG FLAG_MODE OPENMP_FLAG_VAR OPENMP_LIB_NAMES_VAR)
  181. _OPENMP_FLAG_CANDIDATES("${LANG}")
  182. _OPENMP_WRITE_SOURCE_FILE("${LANG}" "TEST_SOURCE" OpenMPTryFlag _OPENMP_TEST_SRC)
  183. unset(OpenMP_VERBOSE_COMPILE_OPTIONS)
  184. separate_arguments(OpenMP_VERBOSE_OPTIONS NATIVE_COMMAND "${CMAKE_${LANG}_VERBOSE_FLAG}")
  185. foreach(_VERBOSE_OPTION IN LISTS OpenMP_VERBOSE_OPTIONS)
  186. if(NOT _VERBOSE_OPTION MATCHES "^-Wl,")
  187. list(APPEND OpenMP_VERBOSE_COMPILE_OPTIONS ${_VERBOSE_OPTION})
  188. endif()
  189. endforeach()
  190. foreach(OPENMP_FLAG IN LISTS OpenMP_${LANG}_FLAG_CANDIDATES)
  191. set(OPENMP_FLAGS_TEST "${OPENMP_FLAG}")
  192. if(OpenMP_VERBOSE_COMPILE_OPTIONS)
  193. string(APPEND OPENMP_FLAGS_TEST " ${OpenMP_VERBOSE_COMPILE_OPTIONS}")
  194. endif()
  195. string(REGEX REPLACE "[-/=+]" "" OPENMP_PLAIN_FLAG "${OPENMP_FLAG}")
  196. try_compile( OpenMP_COMPILE_RESULT_${FLAG_MODE}_${OPENMP_PLAIN_FLAG} ${CMAKE_BINARY_DIR} ${_OPENMP_TEST_SRC}
  197. CMAKE_FLAGS "-DCOMPILE_DEFINITIONS:STRING=${OPENMP_FLAGS_TEST}"
  198. LINK_LIBRARIES ${CMAKE_${LANG}_VERBOSE_FLAG}
  199. OUTPUT_VARIABLE OpenMP_TRY_COMPILE_OUTPUT
  200. )
  201. if(OpenMP_COMPILE_RESULT_${FLAG_MODE}_${OPENMP_PLAIN_FLAG})
  202. set("${OPENMP_FLAG_VAR}" "${OPENMP_FLAG}" PARENT_SCOPE)
  203. if(CMAKE_${LANG}_VERBOSE_FLAG)
  204. unset(OpenMP_${LANG}_IMPLICIT_LIBRARIES)
  205. unset(OpenMP_${LANG}_IMPLICIT_LINK_DIRS)
  206. unset(OpenMP_${LANG}_IMPLICIT_FWK_DIRS)
  207. unset(OpenMP_${LANG}_LOG_VAR)
  208. file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
  209. "Detecting ${LANG} OpenMP compiler ABI info compiled with the following output:\n${OpenMP_TRY_COMPILE_OUTPUT}\n\n")
  210. cmake_parse_implicit_link_info("${OpenMP_TRY_COMPILE_OUTPUT}"
  211. OpenMP_${LANG}_IMPLICIT_LIBRARIES
  212. OpenMP_${LANG}_IMPLICIT_LINK_DIRS
  213. OpenMP_${LANG}_IMPLICIT_FWK_DIRS
  214. OpenMP_${LANG}_LOG_VAR
  215. "${CMAKE_${LANG}_IMPLICIT_OBJECT_REGEX}"
  216. )
  217. file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
  218. "Parsed ${LANG} OpenMP implicit link information from above output:\n${OpenMP_${LANG}_LOG_VAR}\n\n")
  219. unset(_OPENMP_LIB_NAMES)
  220. foreach(_OPENMP_IMPLICIT_LIB IN LISTS OpenMP_${LANG}_IMPLICIT_LIBRARIES)
  221. get_filename_component(_OPENMP_IMPLICIT_LIB_DIR "${_OPENMP_IMPLICIT_LIB}" DIRECTORY)
  222. get_filename_component(_OPENMP_IMPLICIT_LIB_NAME "${_OPENMP_IMPLICIT_LIB}" NAME)
  223. get_filename_component(_OPENMP_IMPLICIT_LIB_PLAIN "${_OPENMP_IMPLICIT_LIB}" NAME_WE)
  224. string(REGEX REPLACE "([][+.*?()^$])" "\\\\\\1" _OPENMP_IMPLICIT_LIB_PLAIN_ESC "${_OPENMP_IMPLICIT_LIB_PLAIN}")
  225. string(REGEX REPLACE "([][+.*?()^$])" "\\\\\\1" _OPENMP_IMPLICIT_LIB_PATH_ESC "${_OPENMP_IMPLICIT_LIB}")
  226. if(NOT ( "${_OPENMP_IMPLICIT_LIB}" IN_LIST CMAKE_${LANG}_IMPLICIT_LINK_LIBRARIES
  227. OR "${CMAKE_${LANG}_STANDARD_LIBRARIES}" MATCHES "(^| )(-Wl,)?(-l)?(${_OPENMP_IMPLICIT_LIB_PLAIN_ESC}|${_OPENMP_IMPLICIT_LIB_PATH_ESC})( |$)"
  228. OR "${CMAKE_${LANG}_LINK_EXECUTABLE}" MATCHES "(^| )(-Wl,)?(-l)?(${_OPENMP_IMPLICIT_LIB_PLAIN_ESC}|${_OPENMP_IMPLICIT_LIB_PATH_ESC})( |$)" ) )
  229. if(_OPENMP_IMPLICIT_LIB_DIR)
  230. set(OpenMP_${_OPENMP_IMPLICIT_LIB_PLAIN}_LIBRARY "${_OPENMP_IMPLICIT_LIB}" CACHE FILEPATH
  231. "Path to the ${_OPENMP_IMPLICIT_LIB_PLAIN} library for OpenMP")
  232. else()
  233. find_library(OpenMP_${_OPENMP_IMPLICIT_LIB_PLAIN}_LIBRARY
  234. NAMES "${_OPENMP_IMPLICIT_LIB_NAME}"
  235. DOC "Path to the ${_OPENMP_IMPLICIT_LIB_PLAIN} library for OpenMP"
  236. HINTS ${OpenMP_${LANG}_IMPLICIT_LINK_DIRS}
  237. CMAKE_FIND_ROOT_PATH_BOTH
  238. NO_DEFAULT_PATH
  239. )
  240. endif()
  241. mark_as_advanced(OpenMP_${_OPENMP_IMPLICIT_LIB_PLAIN}_LIBRARY)
  242. list(APPEND _OPENMP_LIB_NAMES ${_OPENMP_IMPLICIT_LIB_PLAIN})
  243. endif()
  244. endforeach()
  245. set("${OPENMP_LIB_NAMES_VAR}" "${_OPENMP_LIB_NAMES}" PARENT_SCOPE)
  246. else()
  247. # We do not know how to extract implicit OpenMP libraries for this compiler.
  248. # Assume that it handles them automatically, e.g. the Intel Compiler on
  249. # Windows should put the dependency in its object files.
  250. set("${OPENMP_LIB_NAMES_VAR}" "" PARENT_SCOPE)
  251. endif()
  252. break()
  253. elseif(CMAKE_${LANG}_COMPILER_ID STREQUAL "AppleClang"
  254. AND CMAKE_${LANG}_COMPILER_VERSION VERSION_GREATER_EQUAL "7.0")
  255. # Check for separate OpenMP library on AppleClang 7+
  256. find_library(OpenMP_libomp_LIBRARY
  257. NAMES omp gomp iomp5
  258. HINTS ${CMAKE_${LANG}_IMPLICIT_LINK_DIRECTORIES}
  259. )
  260. mark_as_advanced(OpenMP_libomp_LIBRARY)
  261. if(OpenMP_libomp_LIBRARY)
  262. try_compile( OpenMP_COMPILE_RESULT_${FLAG_MODE}_${OPENMP_PLAIN_FLAG} ${CMAKE_BINARY_DIR} ${_OPENMP_TEST_SRC}
  263. CMAKE_FLAGS "-DCOMPILE_DEFINITIONS:STRING=${OPENMP_FLAGS_TEST}"
  264. LINK_LIBRARIES ${CMAKE_${LANG}_VERBOSE_FLAG} ${OpenMP_libomp_LIBRARY}
  265. OUTPUT_VARIABLE OpenMP_TRY_COMPILE_OUTPUT
  266. )
  267. if(OpenMP_COMPILE_RESULT_${FLAG_MODE}_${OPENMP_PLAIN_FLAG})
  268. set("${OPENMP_FLAG_VAR}" "${OPENMP_FLAG}" PARENT_SCOPE)
  269. set("${OPENMP_LIB_NAMES_VAR}" "libomp" PARENT_SCOPE)
  270. break()
  271. endif()
  272. endif()
  273. endif()
  274. set("${OPENMP_LIB_NAMES_VAR}" "NOTFOUND" PARENT_SCOPE)
  275. set("${OPENMP_FLAG_VAR}" "NOTFOUND" PARENT_SCOPE)
  276. endforeach()
  277. unset(OpenMP_VERBOSE_COMPILE_OPTIONS)
  278. endfunction()
  279. set(OpenMP_C_CXX_CHECK_VERSION_SOURCE
  280. "
  281. #include <stdio.h>
  282. #include <omp.h>
  283. const char ompver_str[] = { 'I', 'N', 'F', 'O', ':', 'O', 'p', 'e', 'n', 'M',
  284. 'P', '-', 'd', 'a', 't', 'e', '[',
  285. ('0' + ((_OPENMP/100000)%10)),
  286. ('0' + ((_OPENMP/10000)%10)),
  287. ('0' + ((_OPENMP/1000)%10)),
  288. ('0' + ((_OPENMP/100)%10)),
  289. ('0' + ((_OPENMP/10)%10)),
  290. ('0' + ((_OPENMP/1)%10)),
  291. ']', '\\0' };
  292. int main()
  293. {
  294. puts(ompver_str);
  295. return 0;
  296. }
  297. ")
  298. set(OpenMP_Fortran_CHECK_VERSION_SOURCE
  299. "
  300. program omp_ver
  301. @OpenMP_Fortran_INCLUDE_LINE@
  302. integer, parameter :: zero = ichar('0')
  303. integer, parameter :: ompv = openmp_version
  304. character, dimension(24), parameter :: ompver_str =&
  305. (/ 'I', 'N', 'F', 'O', ':', 'O', 'p', 'e', 'n', 'M', 'P', '-',&
  306. 'd', 'a', 't', 'e', '[',&
  307. char(zero + mod(ompv/100000, 10)),&
  308. char(zero + mod(ompv/10000, 10)),&
  309. char(zero + mod(ompv/1000, 10)),&
  310. char(zero + mod(ompv/100, 10)),&
  311. char(zero + mod(ompv/10, 10)),&
  312. char(zero + mod(ompv/1, 10)), ']' /)
  313. print *, ompver_str
  314. end program omp_ver
  315. ")
  316. function(_OPENMP_GET_SPEC_DATE LANG SPEC_DATE)
  317. _OPENMP_WRITE_SOURCE_FILE("${LANG}" "CHECK_VERSION_SOURCE" OpenMPCheckVersion _OPENMP_TEST_SRC)
  318. set(BIN_FILE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/FindOpenMP/ompver_${LANG}.bin")
  319. string(REGEX REPLACE "[-/=+]" "" OPENMP_PLAIN_FLAG "${OPENMP_FLAG}")
  320. try_compile(OpenMP_SPECTEST_${LANG}_${OPENMP_PLAIN_FLAG} "${CMAKE_BINARY_DIR}" "${_OPENMP_TEST_SRC}"
  321. CMAKE_FLAGS "-DCOMPILE_DEFINITIONS:STRING=${OpenMP_${LANG}_FLAGS}"
  322. COPY_FILE ${BIN_FILE})
  323. if(${OpenMP_SPECTEST_${LANG}_${OPENMP_PLAIN_FLAG}})
  324. file(STRINGS ${BIN_FILE} specstr LIMIT_COUNT 1 REGEX "INFO:OpenMP-date")
  325. set(regex_spec_date ".*INFO:OpenMP-date\\[0*([^]]*)\\].*")
  326. if("${specstr}" MATCHES "${regex_spec_date}")
  327. set(${SPEC_DATE} "${CMAKE_MATCH_1}" PARENT_SCOPE)
  328. endif()
  329. endif()
  330. endfunction()
  331. macro(_OPENMP_SET_VERSION_BY_SPEC_DATE LANG)
  332. set(OpenMP_SPEC_DATE_MAP
  333. # Preview versions
  334. "201611=5.0" # OpenMP 5.0 preview 1
  335. # Combined versions, 2.5 onwards
  336. "201511=4.5"
  337. "201307=4.0"
  338. "201107=3.1"
  339. "200805=3.0"
  340. "200505=2.5"
  341. # C/C++ version 2.0
  342. "200203=2.0"
  343. # Fortran version 2.0
  344. "200011=2.0"
  345. # Fortran version 1.1
  346. "199911=1.1"
  347. # C/C++ version 1.0 (there's no 1.1 for C/C++)
  348. "199810=1.0"
  349. # Fortran version 1.0
  350. "199710=1.0"
  351. )
  352. if(OpenMP_${LANG}_SPEC_DATE)
  353. string(REGEX MATCHALL "${OpenMP_${LANG}_SPEC_DATE}=([0-9]+)\\.([0-9]+)" _version_match "${OpenMP_SPEC_DATE_MAP}")
  354. else()
  355. set(_version_match "")
  356. endif()
  357. if(NOT _version_match STREQUAL "")
  358. set(OpenMP_${LANG}_VERSION_MAJOR ${CMAKE_MATCH_1})
  359. set(OpenMP_${LANG}_VERSION_MINOR ${CMAKE_MATCH_2})
  360. set(OpenMP_${LANG}_VERSION "${OpenMP_${LANG}_VERSION_MAJOR}.${OpenMP_${LANG}_VERSION_MINOR}")
  361. else()
  362. unset(OpenMP_${LANG}_VERSION_MAJOR)
  363. unset(OpenMP_${LANG}_VERSION_MINOR)
  364. unset(OpenMP_${LANG}_VERSION)
  365. endif()
  366. unset(_version_match)
  367. unset(OpenMP_SPEC_DATE_MAP)
  368. endmacro()
  369. foreach(LANG IN ITEMS C CXX)
  370. if(CMAKE_${LANG}_COMPILER_LOADED)
  371. if(NOT DEFINED OpenMP_${LANG}_FLAGS OR "${OpenMP_${LANG}_FLAGS}" STREQUAL "NOTFOUND"
  372. OR NOT DEFINED OpenMP_${LANG}_LIB_NAMES OR "${OpenMP_${LANG}_LIB_NAMES}" STREQUAL "NOTFOUND")
  373. _OPENMP_GET_FLAGS("${LANG}" "${LANG}" OpenMP_${LANG}_FLAGS_WORK OpenMP_${LANG}_LIB_NAMES_WORK)
  374. endif()
  375. set(OpenMP_${LANG}_FLAGS "${OpenMP_${LANG}_FLAGS_WORK}"
  376. CACHE STRING "${LANG} compiler flags for OpenMP parallelization")
  377. set(OpenMP_${LANG}_LIB_NAMES "${OpenMP_${LANG}_LIB_NAMES_WORK}"
  378. CACHE STRING "${LANG} compiler libraries for OpenMP parallelization")
  379. mark_as_advanced(OpenMP_${LANG}_FLAGS OpenMP_${LANG}_LIB_NAMES)
  380. endif()
  381. endforeach()
  382. if(CMAKE_Fortran_COMPILER_LOADED)
  383. if(NOT DEFINED OpenMP_Fortran_FLAGS OR "${OpenMP_Fortran_FLAGS}" STREQUAL "NOTFOUND"
  384. OR NOT DEFINED OpenMP_Fortran_LIB_NAMES OR "${OpenMP_Fortran_LIB_NAMES}" STREQUAL "NOTFOUND"
  385. OR NOT DEFINED OpenMP_Fortran_HAVE_OMPLIB_MODULE)
  386. set(OpenMP_Fortran_INCLUDE_LINE "use omp_lib\n implicit none")
  387. _OPENMP_GET_FLAGS("Fortran" "FortranHeader" OpenMP_Fortran_FLAGS_WORK OpenMP_Fortran_LIB_NAMES_WORK)
  388. if(OpenMP_Fortran_FLAGS_WORK)
  389. set(OpenMP_Fortran_HAVE_OMPLIB_MODULE TRUE CACHE BOOL INTERNAL "")
  390. endif()
  391. set(OpenMP_Fortran_FLAGS "${OpenMP_Fortran_FLAGS_WORK}"
  392. CACHE STRING "Fortran compiler flags for OpenMP parallelization")
  393. set(OpenMP_Fortran_LIB_NAMES "${OpenMP_Fortran_LIB_NAMES_WORK}"
  394. CACHE STRING "Fortran compiler libraries for OpenMP parallelization")
  395. mark_as_advanced(OpenMP_Fortran_FLAGS OpenMP_Fortran_LIB_NAMES)
  396. endif()
  397. if(NOT DEFINED OpenMP_Fortran_FLAGS OR "${OpenMP_Fortran_FLAGS}" STREQUAL "NOTFOUND"
  398. OR NOT DEFINED OpenMP_Fortran_LIB_NAMES OR "${OpenMP_Fortran_LIB_NAMES}" STREQUAL "NOTFOUND"
  399. OR NOT DEFINED OpenMP_Fortran_HAVE_OMPLIB_HEADER)
  400. set(OpenMP_Fortran_INCLUDE_LINE "implicit none\n include 'omp_lib.h'")
  401. _OPENMP_GET_FLAGS("Fortran" "FortranModule" OpenMP_Fortran_FLAGS_WORK OpenMP_Fortran_LIB_NAMES_WORK)
  402. if(OpenMP_Fortran_FLAGS_WORK)
  403. set(OpenMP_Fortran_HAVE_OMPLIB_HEADER TRUE CACHE BOOL INTERNAL "")
  404. endif()
  405. set(OpenMP_Fortran_FLAGS "${OpenMP_Fortran_FLAGS_WORK}"
  406. CACHE STRING "Fortran compiler flags for OpenMP parallelization")
  407. set(OpenMP_Fortran_LIB_NAMES "${OpenMP_Fortran_LIB_NAMES}"
  408. CACHE STRING "Fortran compiler libraries for OpenMP parallelization")
  409. endif()
  410. if(OpenMP_Fortran_HAVE_OMPLIB_MODULE)
  411. set(OpenMP_Fortran_INCLUDE_LINE "use omp_lib\n implicit none")
  412. else()
  413. set(OpenMP_Fortran_INCLUDE_LINE "implicit none\n include 'omp_lib.h'")
  414. endif()
  415. endif()
  416. if(NOT OpenMP_FIND_COMPONENTS)
  417. set(OpenMP_FINDLIST C CXX Fortran)
  418. else()
  419. set(OpenMP_FINDLIST ${OpenMP_FIND_COMPONENTS})
  420. endif()
  421. unset(_OpenMP_MIN_VERSION)
  422. include(FindPackageHandleStandardArgs)
  423. foreach(LANG IN LISTS OpenMP_FINDLIST)
  424. if(CMAKE_${LANG}_COMPILER_LOADED)
  425. if (NOT OpenMP_${LANG}_SPEC_DATE AND OpenMP_${LANG}_FLAGS)
  426. _OPENMP_GET_SPEC_DATE("${LANG}" OpenMP_${LANG}_SPEC_DATE_INTERNAL)
  427. set(OpenMP_${LANG}_SPEC_DATE "${OpenMP_${LANG}_SPEC_DATE_INTERNAL}" CACHE
  428. INTERNAL "${LANG} compiler's OpenMP specification date")
  429. _OPENMP_SET_VERSION_BY_SPEC_DATE("${LANG}")
  430. endif()
  431. set(OpenMP_${LANG}_FIND_QUIETLY ${OpenMP_FIND_QUIETLY})
  432. set(OpenMP_${LANG}_FIND_REQUIRED ${OpenMP_FIND_REQUIRED})
  433. set(OpenMP_${LANG}_FIND_VERSION ${OpenMP_FIND_VERSION})
  434. set(OpenMP_${LANG}_FIND_VERSION_EXACT ${OpenMP_FIND_VERSION_EXACT})
  435. set(_OPENMP_${LANG}_REQUIRED_VARS OpenMP_${LANG}_FLAGS)
  436. if("${OpenMP_${LANG}_LIB_NAMES}" STREQUAL "NOTFOUND")
  437. set(_OPENMP_${LANG}_REQUIRED_LIB_VARS OpenMP_${LANG}_LIB_NAMES)
  438. else()
  439. foreach(_OPENMP_IMPLICIT_LIB IN LISTS OpenMP_${LANG}_LIB_NAMES)
  440. list(APPEND _OPENMP_${LANG}_REQUIRED_LIB_VARS OpenMP_${_OPENMP_IMPLICIT_LIB}_LIBRARY)
  441. endforeach()
  442. endif()
  443. find_package_handle_standard_args(OpenMP_${LANG}
  444. REQUIRED_VARS OpenMP_${LANG}_FLAGS ${_OPENMP_${LANG}_REQUIRED_LIB_VARS}
  445. VERSION_VAR OpenMP_${LANG}_VERSION
  446. )
  447. if(OpenMP_${LANG}_FOUND)
  448. if(DEFINED OpenMP_${LANG}_VERSION)
  449. if(NOT _OpenMP_MIN_VERSION OR _OpenMP_MIN_VERSION VERSION_GREATER OpenMP_${LANG}_VERSION)
  450. set(_OpenMP_MIN_VERSION OpenMP_${LANG}_VERSION)
  451. endif()
  452. endif()
  453. set(OpenMP_${LANG}_LIBRARIES "")
  454. foreach(_OPENMP_IMPLICIT_LIB IN LISTS OpenMP_${LANG}_LIB_NAMES)
  455. list(APPEND OpenMP_${LANG}_LIBRARIES "${OpenMP_${_OPENMP_IMPLICIT_LIB}_LIBRARY}")
  456. endforeach()
  457. if(NOT TARGET OpenMP::OpenMP_${LANG})
  458. add_library(OpenMP::OpenMP_${LANG} INTERFACE IMPORTED)
  459. endif()
  460. if(OpenMP_${LANG}_FLAGS)
  461. separate_arguments(_OpenMP_${LANG}_OPTIONS NATIVE_COMMAND "${OpenMP_${LANG}_FLAGS}")
  462. set_property(TARGET OpenMP::OpenMP_${LANG} PROPERTY
  463. INTERFACE_COMPILE_OPTIONS "$<$<COMPILE_LANGUAGE:${LANG}>:${_OpenMP_${LANG}_OPTIONS}>")
  464. unset(_OpenMP_${LANG}_OPTIONS)
  465. endif()
  466. if(OpenMP_${LANG}_LIBRARIES)
  467. set_property(TARGET OpenMP::OpenMP_${LANG} PROPERTY
  468. INTERFACE_LINK_LIBRARIES "${OpenMP_${LANG}_LIBRARIES}")
  469. endif()
  470. endif()
  471. endif()
  472. endforeach()
  473. unset(_OpenMP_REQ_VARS)
  474. foreach(LANG IN ITEMS C CXX Fortran)
  475. if((NOT OpenMP_FIND_COMPONENTS AND CMAKE_${LANG}_COMPILER_LOADED) OR LANG IN_LIST OpenMP_FIND_COMPONENTS)
  476. list(APPEND _OpenMP_REQ_VARS "OpenMP_${LANG}_FOUND")
  477. endif()
  478. endforeach()
  479. find_package_handle_standard_args(OpenMP
  480. REQUIRED_VARS ${_OpenMP_REQ_VARS}
  481. VERSION_VAR ${_OpenMP_MIN_VERSION}
  482. HANDLE_COMPONENTS)
  483. set(OPENMP_FOUND ${OpenMP_FOUND})
  484. if(CMAKE_Fortran_COMPILER_LOADED AND OpenMP_Fortran_FOUND)
  485. if(NOT DEFINED OpenMP_Fortran_HAVE_OMPLIB_MODULE)
  486. set(OpenMP_Fortran_HAVE_OMPLIB_MODULE FALSE CACHE BOOL INTERNAL "")
  487. endif()
  488. if(NOT DEFINED OpenMP_Fortran_HAVE_OMPLIB_HEADER)
  489. set(OpenMP_Fortran_HAVE_OMPLIB_HEADER FALSE CACHE BOOL INTERNAL "")
  490. endif()
  491. endif()
  492. if(NOT ( CMAKE_C_COMPILER_LOADED OR CMAKE_CXX_COMPILER_LOADED OR CMAKE_Fortran_COMPILER_LOADED ))
  493. message(SEND_ERROR "FindOpenMP requires the C, CXX or Fortran languages to be enabled")
  494. endif()
  495. unset(OpenMP_C_CXX_TEST_SOURCE)
  496. unset(OpenMP_Fortran_TEST_SOURCE)
  497. unset(OpenMP_C_CXX_CHECK_VERSION_SOURCE)
  498. unset(OpenMP_Fortran_CHECK_VERSION_SOURCE)
  499. unset(OpenMP_Fortran_INCLUDE_LINE)
  500. cmake_policy(POP)