FindOpenMP.cmake 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485
  1. # Distributed under the OSI-approved BSD 3-Clause License. See accompanying
  2. # file Copyright.txt or https://cmake.org/licensing for details.
  3. #.rst:
  4. # FindOpenMP
  5. # ----------
  6. #
  7. # Finds OpenMP support
  8. #
  9. # This module can be used to detect OpenMP support in a compiler. If
  10. # the compiler supports OpenMP, the flags required to compile with
  11. # OpenMP support are returned in variables for the different languages.
  12. # The variables may be empty if the compiler does not need a special
  13. # flag to support OpenMP.
  14. #
  15. # Variables
  16. # ^^^^^^^^^
  17. #
  18. # The module exposes the components ``C``, ``CXX``, and ``Fortran``.
  19. # Each of these controls the various languages to search OpenMP support for.
  20. #
  21. # Depending on the enabled components the following variables will be set:
  22. #
  23. # ``OpenMP_FOUND``
  24. # Variable indicating that OpenMP flags for all requested languages have been found.
  25. # If no components are specified, this is true if OpenMP settings for all enabled languages
  26. # were detected.
  27. # ``OpenMP_VERSION``
  28. # Minimal version of the OpenMP standard detected among the requested languages,
  29. # or all enabled languages if no components were specified.
  30. #
  31. # This module will set the following variables per language in your
  32. # project, where ``<lang>`` is one of C, CXX, or Fortran:
  33. #
  34. # ``OpenMP_<lang>_FOUND``
  35. # Variable indicating if OpenMP support for ``<lang>`` was detected.
  36. # ``OpenMP_<lang>_FLAGS``
  37. # OpenMP compiler flags for ``<lang>``, separated by spaces.
  38. #
  39. # For linking with OpenMP code written in ``<lang>``, the following
  40. # variables are provided:
  41. #
  42. # ``OpenMP_<lang>_LIB_NAMES``
  43. # :ref:`;-list <CMake Language Lists>` of libraries for OpenMP programs for ``<lang>``.
  44. # ``OpenMP_<libname>_LIBRARY``
  45. # Location of the individual libraries needed for OpenMP support in ``<lang>``.
  46. # ``OpenMP_<lang>_LIBRARIES``
  47. # A list of libraries needed to link with OpenMP code written in ``<lang>``.
  48. #
  49. # Additionally, the module provides :prop_tgt:`IMPORTED` targets:
  50. #
  51. # ``OpenMP::OpenMP_<lang>``
  52. # Target for using OpenMP from ``<lang>``.
  53. #
  54. # Specifically for Fortran, the module sets the following variables:
  55. #
  56. # ``OpenMP_Fortran_HAVE_OMPLIB_HEADER``
  57. # Boolean indicating if OpenMP is accessible through ``omp_lib.h``.
  58. # ``OpenMP_Fortran_HAVE_OMPLIB_MODULE``
  59. # Boolean indicating if OpenMP is accessible through the ``omp_lib`` Fortran module.
  60. #
  61. # The module will also try to provide the OpenMP version variables:
  62. #
  63. # ``OpenMP_<lang>_SPEC_DATE``
  64. # Date of the OpenMP specification implemented by the ``<lang>`` compiler.
  65. # ``OpenMP_<lang>_VERSION_MAJOR``
  66. # Major version of OpenMP implemented by the ``<lang>`` compiler.
  67. # ``OpenMP_<lang>_VERSION_MINOR``
  68. # Minor version of OpenMP implemented by the ``<lang>`` compiler.
  69. # ``OpenMP_<lang>_VERSION``
  70. # OpenMP version implemented by the ``<lang>`` compiler.
  71. #
  72. # The specification date is formatted as given in the OpenMP standard:
  73. # ``yyyymm`` where ``yyyy`` and ``mm`` represents the year and month of
  74. # the OpenMP specification implemented by the ``<lang>`` compiler.
  75. cmake_policy(PUSH)
  76. cmake_policy(SET CMP0054 NEW) # if() quoted variables not dereferenced
  77. cmake_policy(SET CMP0057 NEW) # if IN_LIST
  78. function(_OPENMP_FLAG_CANDIDATES LANG)
  79. if(NOT OpenMP_${LANG}_FLAG)
  80. unset(OpenMP_FLAG_CANDIDATES)
  81. set(OMP_FLAG_GNU "-fopenmp")
  82. set(OMP_FLAG_Clang "-fopenmp=libomp" "-fopenmp=libiomp5" "-fopenmp")
  83. set(OMP_FLAG_HP "+Oopenmp")
  84. if(WIN32)
  85. set(OMP_FLAG_Intel "-Qopenmp")
  86. elseif(CMAKE_${LANG}_COMPILER_ID STREQUAL "Intel" AND
  87. "${CMAKE_${LANG}_COMPILER_VERSION}" VERSION_LESS "15.0.0.20140528")
  88. set(OMP_FLAG_Intel "-openmp")
  89. else()
  90. set(OMP_FLAG_Intel "-qopenmp")
  91. endif()
  92. set(OMP_FLAG_MIPSpro "-mp")
  93. set(OMP_FLAG_MSVC "-openmp")
  94. set(OMP_FLAG_PathScale "-openmp")
  95. set(OMP_FLAG_NAG "-openmp")
  96. set(OMP_FLAG_Absoft "-openmp")
  97. set(OMP_FLAG_PGI "-mp")
  98. set(OMP_FLAG_Flang "-fopenmp")
  99. set(OMP_FLAG_SunPro "-xopenmp")
  100. set(OMP_FLAG_XL "-qsmp=omp")
  101. # Cray compiler activate OpenMP with -h omp, which is enabled by default.
  102. set(OMP_FLAG_Cray " " "-h omp")
  103. # If we know the correct flags, use those
  104. if(DEFINED OMP_FLAG_${CMAKE_${LANG}_COMPILER_ID})
  105. set(OpenMP_FLAG_CANDIDATES "${OMP_FLAG_${CMAKE_${LANG}_COMPILER_ID}}")
  106. # Fall back to reasonable default tries otherwise
  107. else()
  108. set(OpenMP_FLAG_CANDIDATES "-openmp" "-fopenmp" "-mp" " ")
  109. endif()
  110. set(OpenMP_${LANG}_FLAG_CANDIDATES "${OpenMP_FLAG_CANDIDATES}" PARENT_SCOPE)
  111. else()
  112. set(OpenMP_${LANG}_FLAG_CANDIDATES "${OpenMP_${LANG}_FLAG}" PARENT_SCOPE)
  113. endif()
  114. endfunction()
  115. # sample openmp source code to test
  116. set(OpenMP_C_CXX_TEST_SOURCE
  117. "
  118. #include <omp.h>
  119. int main() {
  120. #ifndef _OPENMP
  121. breaks_on_purpose
  122. #endif
  123. }
  124. ")
  125. # in Fortran, an implementation may provide an omp_lib.h header
  126. # or omp_lib module, or both (OpenMP standard, section 3.1)
  127. # Furthmore !$ is the Fortran equivalent of #ifdef _OPENMP (OpenMP standard, 2.2.2)
  128. # Without the conditional compilation, some compilers (e.g. PGI) might compile OpenMP code
  129. # while not actually enabling OpenMP, building code sequentially
  130. set(OpenMP_Fortran_TEST_SOURCE
  131. "
  132. program test
  133. @OpenMP_Fortran_INCLUDE_LINE@
  134. !$ integer :: n
  135. n = omp_get_num_threads()
  136. end program test
  137. "
  138. )
  139. function(_OPENMP_WRITE_SOURCE_FILE LANG SRC_FILE_CONTENT_VAR SRC_FILE_NAME SRC_FILE_FULLPATH)
  140. set(WORK_DIR ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/FindOpenMP)
  141. if("${LANG}" STREQUAL "C")
  142. set(SRC_FILE "${WORK_DIR}/${SRC_FILE_NAME}.c")
  143. file(WRITE "${SRC_FILE}" "${OpenMP_C_CXX_${SRC_FILE_CONTENT_VAR}}")
  144. elseif("${LANG}" STREQUAL "CXX")
  145. set(SRC_FILE "${WORK_DIR}/${SRC_FILE_NAME}.cpp")
  146. file(WRITE "${SRC_FILE}" "${OpenMP_C_CXX_${SRC_FILE_CONTENT_VAR}}")
  147. elseif("${LANG}" STREQUAL "Fortran")
  148. set(SRC_FILE "${WORK_DIR}/${SRC_FILE_NAME}.f90")
  149. file(WRITE "${SRC_FILE}_in" "${OpenMP_Fortran_${SRC_FILE_CONTENT_VAR}}")
  150. configure_file("${SRC_FILE}_in" "${SRC_FILE}" @ONLY)
  151. endif()
  152. set(${SRC_FILE_FULLPATH} "${SRC_FILE}" PARENT_SCOPE)
  153. endfunction()
  154. include(${CMAKE_ROOT}/Modules/CMakeParseImplicitLinkInfo.cmake)
  155. function(_OPENMP_GET_FLAGS LANG FLAG_MODE OPENMP_FLAG_VAR OPENMP_LIB_NAMES_VAR)
  156. _OPENMP_FLAG_CANDIDATES("${LANG}")
  157. _OPENMP_WRITE_SOURCE_FILE("${LANG}" "TEST_SOURCE" OpenMPTryFlag _OPENMP_TEST_SRC)
  158. foreach(OPENMP_FLAG IN LISTS OpenMP_${LANG}_FLAG_CANDIDATES)
  159. set(OPENMP_FLAGS_TEST "${OPENMP_FLAG}")
  160. if(CMAKE_${LANG}_VERBOSE_FLAG)
  161. string(APPEND OPENMP_FLAGS_TEST " ${CMAKE_${LANG}_VERBOSE_FLAG}")
  162. endif()
  163. string(REGEX REPLACE "[-/=+]" "" OPENMP_PLAIN_FLAG "${OPENMP_FLAG}")
  164. try_compile( OpenMP_COMPILE_RESULT_${FLAG_MODE}_${OPENMP_PLAIN_FLAG} ${CMAKE_BINARY_DIR} ${_OPENMP_TEST_SRC}
  165. CMAKE_FLAGS "-DCOMPILE_DEFINITIONS:STRING=${OPENMP_FLAGS_TEST}"
  166. OUTPUT_VARIABLE OpenMP_TRY_COMPILE_OUTPUT
  167. )
  168. if(OpenMP_COMPILE_RESULT_${FLAG_MODE}_${OPENMP_PLAIN_FLAG})
  169. set("${OPENMP_FLAG_VAR}" "${OPENMP_FLAG}" PARENT_SCOPE)
  170. if(CMAKE_${LANG}_VERBOSE_FLAG)
  171. unset(OpenMP_${LANG}_IMPLICIT_LIBRARIES)
  172. unset(OpenMP_${LANG}_IMPLICIT_LINK_DIRS)
  173. unset(OpenMP_${LANG}_IMPLICIT_FWK_DIRS)
  174. unset(OpenMP_${LANG}_LOG_VAR)
  175. file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
  176. "Detecting ${LANG} OpenMP compiler ABI info compiled with the following output:\n${OpenMP_TRY_COMPILE_OUTPUT}\n\n")
  177. cmake_parse_implicit_link_info("${OpenMP_TRY_COMPILE_OUTPUT}"
  178. OpenMP_${LANG}_IMPLICIT_LIBRARIES
  179. OpenMP_${LANG}_IMPLICIT_LINK_DIRS
  180. OpenMP_${LANG}_IMPLICIT_FWK_DIRS
  181. OpenMP_${LANG}_LOG_VAR
  182. "${CMAKE_${LANG}_IMPLICIT_OBJECT_REGEX}"
  183. )
  184. file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
  185. "Parsed ${LANG} OpenMP implicit link information from above output:\n${OpenMP_${LANG}_LOG_VAR}\n\n")
  186. unset(_OPENMP_LIB_NAMES)
  187. foreach(_OPENMP_IMPLICIT_LIB IN LISTS OpenMP_${LANG}_IMPLICIT_LIBRARIES)
  188. if(NOT "${_OPENMP_IMPLICIT_LIB}" IN_LIST CMAKE_${LANG}_IMPLICIT_LINK_LIBRARIES)
  189. find_library(OpenMP_${_OPENMP_IMPLICIT_LIB}_LIBRARY
  190. NAMES "${_OPENMP_IMPLICIT_LIB}"
  191. HINTS ${OpenMP_${LANG}_IMPLICIT_LINK_DIRS}
  192. )
  193. mark_as_advanced(OpenMP_${_OPENMP_IMPLICIT_LIB}_LIBRARY)
  194. list(APPEND _OPENMP_LIB_NAMES ${_OPENMP_IMPLICIT_LIB})
  195. endif()
  196. endforeach()
  197. set("${OPENMP_LIB_NAMES_VAR}" "${_OPENMP_LIB_NAMES}" PARENT_SCOPE)
  198. else()
  199. # The Intel compiler on windows has no verbose mode, so we need to treat it explicitly
  200. if("${CMAKE_${LANG}_COMPILER_ID}" STREQUAL "Intel" AND "${CMAKE_SYSTEM_NAME}" STREQUAL "Windows")
  201. set("${OPENMP_LIB_NAMES_VAR}" "libiomp5md" PARENT_SCOPE)
  202. find_library(OpenMP_libiomp5md_LIBRARY
  203. NAMES "libiomp5md"
  204. HINTS ${CMAKE_${LANG}_IMPLICIT_LINK_DIRECTORIES}
  205. )
  206. mark_as_advanced(OpenMP_libiomp5md_LIBRARY)
  207. else()
  208. set("${OPENMP_LIB_NAMES_VAR}" "" PARENT_SCOPE)
  209. endif()
  210. endif()
  211. break()
  212. endif()
  213. set("${OPENMP_LIB_NAMES_VAR}" "NOTFOUND" PARENT_SCOPE)
  214. set("${OPENMP_FLAG_VAR}" "NOTFOUND" PARENT_SCOPE)
  215. endforeach()
  216. endfunction()
  217. set(OpenMP_C_CXX_CHECK_VERSION_SOURCE
  218. "
  219. #include <stdio.h>
  220. #include <omp.h>
  221. const char ompver_str[] = { 'I', 'N', 'F', 'O', ':', 'O', 'p', 'e', 'n', 'M',
  222. 'P', '-', 'd', 'a', 't', 'e', '[',
  223. ('0' + ((_OPENMP/100000)%10)),
  224. ('0' + ((_OPENMP/10000)%10)),
  225. ('0' + ((_OPENMP/1000)%10)),
  226. ('0' + ((_OPENMP/100)%10)),
  227. ('0' + ((_OPENMP/10)%10)),
  228. ('0' + ((_OPENMP/1)%10)),
  229. ']', '\\0' };
  230. int main()
  231. {
  232. puts(ompver_str);
  233. }
  234. ")
  235. set(OpenMP_Fortran_CHECK_VERSION_SOURCE
  236. "
  237. program omp_ver
  238. @OpenMP_Fortran_INCLUDE_LINE@
  239. integer, parameter :: zero = ichar('0')
  240. integer, parameter :: ompv = openmp_version
  241. character, dimension(24), parameter :: ompver_str =&
  242. (/ 'I', 'N', 'F', 'O', ':', 'O', 'p', 'e', 'n', 'M', 'P', '-',&
  243. 'd', 'a', 't', 'e', '[',&
  244. char(zero + mod(ompv/100000, 10)),&
  245. char(zero + mod(ompv/10000, 10)),&
  246. char(zero + mod(ompv/1000, 10)),&
  247. char(zero + mod(ompv/100, 10)),&
  248. char(zero + mod(ompv/10, 10)),&
  249. char(zero + mod(ompv/1, 10)), ']' /)
  250. print *, ompver_str
  251. end program omp_ver
  252. ")
  253. function(_OPENMP_GET_SPEC_DATE LANG SPEC_DATE)
  254. _OPENMP_WRITE_SOURCE_FILE("${LANG}" "CHECK_VERSION_SOURCE" OpenMPCheckVersion _OPENMP_TEST_SRC)
  255. set(BIN_FILE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/FindOpenMP/ompver_${LANG}.bin")
  256. string(REGEX REPLACE "[-/=+]" "" OPENMP_PLAIN_FLAG "${OPENMP_FLAG}")
  257. try_compile(OpenMP_SPECTEST_${LANG}_${OPENMP_PLAIN_FLAG} "${CMAKE_BINARY_DIR}" "${_OPENMP_TEST_SRC}"
  258. CMAKE_FLAGS "-DCOMPILE_DEFINITIONS:STRING=${OpenMP_${LANG}_FLAGS}"
  259. COPY_FILE ${BIN_FILE})
  260. if(${OpenMP_SPECTEST_${LANG}_${OPENMP_PLAIN_FLAG}})
  261. file(STRINGS ${BIN_FILE} specstr LIMIT_COUNT 1 REGEX "INFO:OpenMP-date")
  262. set(regex_spec_date ".*INFO:OpenMP-date\\[0*([^]]*)\\].*")
  263. if("${specstr}" MATCHES "${regex_spec_date}")
  264. set(${SPEC_DATE} "${CMAKE_MATCH_1}" PARENT_SCOPE)
  265. endif()
  266. endif()
  267. endfunction()
  268. macro(_OPENMP_SET_VERSION_BY_SPEC_DATE LANG)
  269. set(OpenMP_SPEC_DATE_MAP
  270. # Preview versions
  271. "201611=5.0" # OpenMP 5.0 preview 1
  272. # Combined versions, 2.5 onwards
  273. "201511=4.5"
  274. "201307=4.0"
  275. "201107=3.1"
  276. "200805=3.0"
  277. "200505=2.5"
  278. # C/C++ version 2.0
  279. "200203=2.0"
  280. # Fortran version 2.0
  281. "200011=2.0"
  282. # Fortran version 1.1
  283. "199911=1.1"
  284. # C/C++ version 1.0 (there's no 1.1 for C/C++)
  285. "199810=1.0"
  286. # Fortran version 1.0
  287. "199710=1.0"
  288. )
  289. if(OpenMP_${LANG}_SPEC_DATE)
  290. string(REGEX MATCHALL "${OpenMP_${LANG}_SPEC_DATE}=([0-9]+)\\.([0-9]+)" _version_match "${OpenMP_SPEC_DATE_MAP}")
  291. else()
  292. set(_version_match "")
  293. endif()
  294. if(NOT _version_match STREQUAL "")
  295. set(OpenMP_${LANG}_VERSION_MAJOR ${CMAKE_MATCH_1})
  296. set(OpenMP_${LANG}_VERSION_MINOR ${CMAKE_MATCH_2})
  297. set(OpenMP_${LANG}_VERSION "${OpenMP_${LANG}_VERSION_MAJOR}.${OpenMP_${LANG}_VERSION_MINOR}")
  298. else()
  299. unset(OpenMP_${LANG}_VERSION_MAJOR)
  300. unset(OpenMP_${LANG}_VERSION_MINOR)
  301. unset(OpenMP_${LANG}_VERSION)
  302. endif()
  303. unset(_version_match)
  304. unset(OpenMP_SPEC_DATE_MAP)
  305. endmacro()
  306. foreach(LANG IN ITEMS C CXX)
  307. if(CMAKE_${LANG}_COMPILER_LOADED)
  308. if(NOT DEFINED OpenMP_${LANG}_FLAGS OR "${OpenMP_${LANG}_FLAGS}" STREQUAL "NOTFOUND"
  309. OR NOT DEFINED OpenMP_${LANG}_LIB_NAMES OR "${OpenMP_${LANG}_LIB_NAMES}" STREQUAL "NOTFOUND")
  310. _OPENMP_GET_FLAGS("${LANG}" "${LANG}" OpenMP_${LANG}_FLAGS_WORK OpenMP_${LANG}_LIB_NAMES_WORK)
  311. endif()
  312. set(OpenMP_${LANG}_FLAGS "${OpenMP_${LANG}_FLAGS_WORK}"
  313. CACHE STRING "${LANG} compiler flags for OpenMP parallelization")
  314. set(OpenMP_${LANG}_LIB_NAMES "${OpenMP_${LANG}_LIB_NAMES_WORK}"
  315. CACHE STRING "${LANG} compiler libraries for OpenMP parallelization")
  316. mark_as_advanced(OpenMP_${LANG}_FLAGS OpenMP_${LANG}_LIB_NAMES)
  317. endif()
  318. endforeach()
  319. if(CMAKE_Fortran_COMPILER_LOADED)
  320. if(NOT DEFINED OpenMP_Fortran_FLAGS OR "${OpenMP_Fortran_FLAGS}" STREQUAL "NOTFOUND"
  321. OR NOT DEFINED OpenMP_Fortran_LIB_NAMES OR "${OpenMP_Fortran_LIB_NAMES}" STREQUAL "NOTFOUND"
  322. OR NOT DEFINED OpenMP_Fortran_HAVE_OMPLIB_MODULE)
  323. set(OpenMP_Fortran_INCLUDE_LINE "use omp_lib\n implicit none")
  324. _OPENMP_GET_FLAGS("Fortran" "FortranHeader" OpenMP_Fortran_FLAGS_WORK OpenMP_Fortran_LIB_NAMES_WORK)
  325. if(OpenMP_Fortran_FLAGS_WORK)
  326. set(OpenMP_Fortran_HAVE_OMPLIB_MODULE TRUE CACHE BOOL INTERNAL "")
  327. endif()
  328. set(OpenMP_Fortran_FLAGS "${OpenMP_Fortran_FLAGS_WORK}"
  329. CACHE STRING "Fortran compiler flags for OpenMP parallelization")
  330. set(OpenMP_Fortran_LIB_NAMES "${OpenMP_Fortran_LIB_NAMES_WORK}"
  331. CACHE STRING "Fortran compiler libraries for OpenMP parallelization")
  332. mark_as_advanced(OpenMP_Fortran_FLAGS OpenMP_Fortran_LIB_NAMES)
  333. endif()
  334. if(NOT DEFINED OpenMP_Fortran_FLAGS OR "${OpenMP_Fortran_FLAGS}" STREQUAL "NOTFOUND"
  335. OR NOT DEFINED OpenMP_Fortran_LIB_NAMES OR "${OpenMP_Fortran_LIB_NAMES}" STREQUAL "NOTFOUND"
  336. OR NOT DEFINED OpenMP_Fortran_HAVE_OMPLIB_HEADER)
  337. set(OpenMP_Fortran_INCLUDE_LINE "implicit none\n include 'omp_lib.h'")
  338. _OPENMP_GET_FLAGS("Fortran" "FortranModule" OpenMP_Fortran_FLAGS_WORK OpenMP_Fortran_LIB_NAMES_WORK)
  339. if(OpenMP_Fortran_FLAGS_WORK)
  340. set(OpenMP_Fortran_HAVE_OMPLIB_HEADER TRUE CACHE BOOL INTERNAL "")
  341. endif()
  342. set(OpenMP_Fortran_FLAGS "${OpenMP_Fortran_FLAGS_WORK}"
  343. CACHE STRING "Fortran compiler flags for OpenMP parallelization")
  344. set(OpenMP_Fortran_LIB_NAMES "${OpenMP_Fortran_LIB_NAMES}"
  345. CACHE STRING "Fortran compiler libraries for OpenMP parallelization")
  346. endif()
  347. if(OpenMP_Fortran_HAVE_OMPLIB_MODULE)
  348. set(OpenMP_Fortran_INCLUDE_LINE "use omp_lib\n implicit none")
  349. else()
  350. set(OpenMP_Fortran_INCLUDE_LINE "implicit none\n include 'omp_lib.h'")
  351. endif()
  352. endif()
  353. if(NOT OpenMP_FIND_COMPONENTS)
  354. set(OpenMP_FINDLIST C CXX Fortran)
  355. else()
  356. set(OpenMP_FINDLIST ${OpenMP_FIND_COMPONENTS})
  357. endif()
  358. unset(_OpenMP_MIN_VERSION)
  359. foreach(LANG IN LISTS OpenMP_FINDLIST)
  360. if(CMAKE_${LANG}_COMPILER_LOADED)
  361. if (NOT OpenMP_${LANG}_SPEC_DATE AND OpenMP_${LANG}_FLAGS)
  362. _OPENMP_GET_SPEC_DATE("${LANG}" OpenMP_${LANG}_SPEC_DATE_INTERNAL)
  363. set(OpenMP_${LANG}_SPEC_DATE "${OpenMP_${LANG}_SPEC_DATE_INTERNAL}" CACHE
  364. INTERNAL "${LANG} compiler's OpenMP specification date")
  365. _OPENMP_SET_VERSION_BY_SPEC_DATE("${LANG}")
  366. endif()
  367. include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
  368. set(OpenMP_${LANG}_FIND_QUIETLY ${OpenMP_FIND_QUIETLY})
  369. set(OpenMP_${LANG}_FIND_REQUIRED ${OpenMP_FIND_REQUIRED})
  370. set(OpenMP_${LANG}_FIND_VERSION ${OpenMP_FIND_VERSION})
  371. set(OpenMP_${LANG}_FIND_VERSION_EXACT ${OpenMP_FIND_VERSION_EXACT})
  372. set(_OPENMP_${LANG}_REQUIRED_VARS OpenMP_${LANG}_FLAGS)
  373. if("${OpenMP_${LANG}_LIB_NAMES}" STREQUAL "NOTFOUND")
  374. set(_OPENMP_${LANG}_REQUIRED_LIB_VARS OpenMP_${LANG}_LIB_NAMES)
  375. else()
  376. foreach(_OPENMP_IMPLICIT_LIB IN LISTS OpenMP_${LANG}_LIB_NAMES)
  377. list(APPEND _OPENMP_${LANG}_REQUIRED_LIB_VARS OpenMP_${_OPENMP_IMPLICIT_LIB}_LIBRARY)
  378. endforeach()
  379. endif()
  380. find_package_handle_standard_args(OpenMP_${LANG}
  381. REQUIRED_VARS OpenMP_${LANG}_FLAGS ${_OPENMP_${LANG}_REQUIRED_LIB_VARS}
  382. VERSION_VAR OpenMP_${LANG}_VERSION
  383. )
  384. if(OpenMP_${LANG}_FOUND)
  385. if(DEFINED OpenMP_${LANG}_VERSION)
  386. if(NOT _OpenMP_MIN_VERSION OR _OpenMP_MIN_VERSION VERSION_GREATER OpenMP_${LANG}_VERSION)
  387. set(_OpenMP_MIN_VERSION OpenMP_${LANG}_VERSION)
  388. endif()
  389. endif()
  390. set(OpenMP_${LANG}_LIBRARIES "")
  391. foreach(_OPENMP_IMPLICIT_LIB IN LISTS OpenMP_${LANG}_LIB_NAMES)
  392. list(APPEND OpenMP_${LANG}_LIBRARIES "${OpenMP_${_OPENMP_IMPLICIT_LIB}_LIBRARY}")
  393. endforeach()
  394. if(NOT TARGET OpenMP::OpenMP_${LANG})
  395. add_library(OpenMP::OpenMP_${LANG} INTERFACE IMPORTED)
  396. endif()
  397. if(OpenMP_${LANG}_FLAGS)
  398. separate_arguments(_OpenMP_${LANG}_OPTIONS NATIVE_COMMAND "${OpenMP_${LANG}_FLAGS}")
  399. set_property(TARGET OpenMP::OpenMP_${LANG} PROPERTY
  400. INTERFACE_COMPILE_OPTIONS "${_OpenMP_${LANG}_OPTIONS}")
  401. unset(_OpenMP_${LANG}_OPTIONS)
  402. endif()
  403. if(OpenMP_${LANG}_LIBRARIES)
  404. set_property(TARGET OpenMP::OpenMP_${LANG} PROPERTY
  405. INTERFACE_LINK_LIBRARIES "${OpenMP_${LANG}_LIBRARIES}")
  406. endif()
  407. endif()
  408. endif()
  409. endforeach()
  410. unset(_OpenMP_REQ_VARS)
  411. foreach(LANG IN ITEMS C CXX Fortran)
  412. if((NOT OpenMP_FIND_COMPONENTS AND CMAKE_${LANG}_COMPILER_LOADED) OR LANG IN_LIST OpenMP_FIND_COMPONENTS)
  413. list(APPEND _OpenMP_REQ_VARS "OpenMP_${LANG}_FOUND")
  414. endif()
  415. endforeach()
  416. find_package_handle_standard_args(OpenMP
  417. REQUIRED_VARS ${_OpenMP_REQ_VARS}
  418. VERSION_VAR ${_OpenMP_MIN_VERSION}
  419. HANDLE_COMPONENTS)
  420. set(OPENMP_FOUND ${OpenMP_FOUND})
  421. if(CMAKE_Fortran_COMPILER_LOADED AND OpenMP_Fortran_FOUND)
  422. if(NOT DEFINED OpenMP_Fortran_HAVE_OMPLIB_MODULE)
  423. set(OpenMP_Fortran_HAVE_OMPLIB_MODULE FALSE CACHE BOOL INTERNAL "")
  424. endif()
  425. if(NOT DEFINED OpenMP_Fortran_HAVE_OMPLIB_HEADER)
  426. set(OpenMP_Fortran_HAVE_OMPLIB_HEADER FALSE CACHE BOOL INTERNAL "")
  427. endif()
  428. endif()
  429. if(NOT ( CMAKE_C_COMPILER_LOADED OR CMAKE_CXX_COMPILER_LOADED OR CMAKE_Fortran_COMPILER_LOADED ))
  430. message(SEND_ERROR "FindOpenMP requires the C, CXX or Fortran languages to be enabled")
  431. endif()
  432. unset(OpenMP_C_CXX_TEST_SOURCE)
  433. unset(OpenMP_Fortran_TEST_SOURCE)
  434. unset(OpenMP_C_CXX_CHECK_VERSION_SOURCE)
  435. unset(OpenMP_Fortran_CHECK_VERSION_SOURCE)
  436. unset(OpenMP_Fortran_INCLUDE_LINE)
  437. cmake_policy(POP)