FindOpenMP.cmake 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480
  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 CMP0057 NEW) # if IN_LIST
  77. function(_OPENMP_FLAG_CANDIDATES LANG)
  78. if(NOT OpenMP_${LANG}_FLAG)
  79. unset(OpenMP_FLAG_CANDIDATES)
  80. set(OMP_FLAG_GNU "-fopenmp")
  81. set(OMP_FLAG_Clang "-fopenmp=libomp" "-fopenmp=libiomp5" "-fopenmp")
  82. set(OMP_FLAG_HP "+Oopenmp")
  83. if(WIN32)
  84. set(OMP_FLAG_Intel "-Qopenmp")
  85. elseif(CMAKE_${LANG}_COMPILER_ID STREQUAL "Intel" AND
  86. "${CMAKE_${LANG}_COMPILER_VERSION}" VERSION_LESS "15.0.0.20140528")
  87. set(OMP_FLAG_Intel "-openmp")
  88. else()
  89. set(OMP_FLAG_Intel "-qopenmp")
  90. endif()
  91. set(OMP_FLAG_MIPSpro "-mp")
  92. set(OMP_FLAG_MSVC "-openmp")
  93. set(OMP_FLAG_PathScale "-openmp")
  94. set(OMP_FLAG_NAG "-openmp")
  95. set(OMP_FLAG_Absoft "-openmp")
  96. set(OMP_FLAG_PGI "-mp")
  97. set(OMP_FLAG_Flang "-fopenmp")
  98. set(OMP_FLAG_SunPro "-xopenmp")
  99. set(OMP_FLAG_XL "-qsmp=omp")
  100. # Cray compiler activate OpenMP with -h omp, which is enabled by default.
  101. set(OMP_FLAG_Cray " " "-h omp")
  102. # If we know the correct flags, use those
  103. if(DEFINED OMP_FLAG_${CMAKE_${LANG}_COMPILER_ID})
  104. set(OpenMP_FLAG_CANDIDATES "${OMP_FLAG_${CMAKE_${LANG}_COMPILER_ID}}")
  105. # Fall back to reasonable default tries otherwise
  106. else()
  107. set(OpenMP_FLAG_CANDIDATES "-openmp" "-fopenmp" "-mp" " ")
  108. endif()
  109. set(OpenMP_${LANG}_FLAG_CANDIDATES "${OpenMP_FLAG_CANDIDATES}" PARENT_SCOPE)
  110. else()
  111. set(OpenMP_${LANG}_FLAG_CANDIDATES "${OpenMP_${LANG}_FLAG}" PARENT_SCOPE)
  112. endif()
  113. endfunction()
  114. # sample openmp source code to test
  115. set(OpenMP_C_CXX_TEST_SOURCE
  116. "
  117. #include <omp.h>
  118. int main() {
  119. #ifndef _OPENMP
  120. breaks_on_purpose
  121. #endif
  122. }
  123. ")
  124. # in Fortran, an implementation may provide an omp_lib.h header
  125. # or omp_lib module, or both (OpenMP standard, section 3.1)
  126. # Furthmore !$ is the Fortran equivalent of #ifdef _OPENMP (OpenMP standard, 2.2.2)
  127. # Without the conditional compilation, some compilers (e.g. PGI) might compile OpenMP code
  128. # while not actually enabling OpenMP, building code sequentially
  129. set(OpenMP_Fortran_TEST_SOURCE
  130. "
  131. program test
  132. @OpenMP_Fortran_INCLUDE_LINE@
  133. !$ integer :: n
  134. n = omp_get_num_threads()
  135. end program test
  136. "
  137. )
  138. function(_OPENMP_WRITE_SOURCE_FILE LANG SRC_FILE_CONTENT_VAR SRC_FILE_NAME SRC_FILE_FULLPATH)
  139. set(WORK_DIR ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/FindOpenMP)
  140. if("${LANG}" STREQUAL "C")
  141. set(SRC_FILE "${WORK_DIR}/${SRC_FILE_NAME}.c")
  142. file(WRITE "${SRC_FILE}" "${OpenMP_C_CXX_${SRC_FILE_CONTENT_VAR}}")
  143. elseif("${LANG}" STREQUAL "CXX")
  144. set(SRC_FILE "${WORK_DIR}/${SRC_FILE_NAME}.cpp")
  145. file(WRITE "${SRC_FILE}" "${OpenMP_C_CXX_${SRC_FILE_CONTENT_VAR}}")
  146. elseif("${LANG}" STREQUAL "Fortran")
  147. set(SRC_FILE "${WORK_DIR}/${SRC_FILE_NAME}.f90")
  148. file(WRITE "${SRC_FILE}_in" "${OpenMP_Fortran_${SRC_FILE_CONTENT_VAR}}")
  149. configure_file("${SRC_FILE}_in" "${SRC_FILE}" @ONLY)
  150. endif()
  151. set(${SRC_FILE_FULLPATH} "${SRC_FILE}" PARENT_SCOPE)
  152. endfunction()
  153. include(${CMAKE_ROOT}/Modules/CMakeParseImplicitLinkInfo.cmake)
  154. function(_OPENMP_GET_FLAGS LANG FLAG_MODE OPENMP_FLAG_VAR OPENMP_LIB_NAMES_VAR)
  155. _OPENMP_FLAG_CANDIDATES("${LANG}")
  156. _OPENMP_WRITE_SOURCE_FILE("${LANG}" "TEST_SOURCE" OpenMPTryFlag _OPENMP_TEST_SRC)
  157. foreach(OPENMP_FLAG IN LISTS OpenMP_${LANG}_FLAG_CANDIDATES)
  158. set(OPENMP_FLAGS_TEST "${OPENMP_FLAG}")
  159. if(CMAKE_${LANG}_VERBOSE_FLAG)
  160. string(APPEND OPENMP_FLAGS_TEST " ${CMAKE_${LANG}_VERBOSE_FLAG}")
  161. endif()
  162. string(REGEX REPLACE "[-/=+]" "" OPENMP_PLAIN_FLAG "${OPENMP_FLAG}")
  163. try_compile( OpenMP_COMPILE_RESULT_${FLAG_MODE}_${OPENMP_PLAIN_FLAG} ${CMAKE_BINARY_DIR} ${_OPENMP_TEST_SRC}
  164. CMAKE_FLAGS "-DCOMPILE_DEFINITIONS:STRING=${OPENMP_FLAGS_TEST}"
  165. OUTPUT_VARIABLE OpenMP_TRY_COMPILE_OUTPUT
  166. )
  167. if(OpenMP_COMPILE_RESULT_${FLAG_MODE}_${OPENMP_PLAIN_FLAG})
  168. set("${OPENMP_FLAG_VAR}" "${OPENMP_FLAG}" PARENT_SCOPE)
  169. if(CMAKE_${LANG}_VERBOSE_FLAG)
  170. unset(OpenMP_${LANG}_IMPLICIT_LIBRARIES)
  171. unset(OpenMP_${LANG}_IMPLICIT_LINK_DIRS)
  172. unset(OpenMP_${LANG}_IMPLICIT_FWK_DIRS)
  173. unset(OpenMP_${LANG}_LOG_VAR)
  174. file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
  175. "Detecting ${LANG} OpenMP compiler ABI info compiled with the following output:\n${OpenMP_TRY_COMPILE_OUTPUT}\n\n")
  176. cmake_parse_implicit_link_info("${OpenMP_TRY_COMPILE_OUTPUT}"
  177. OpenMP_${LANG}_IMPLICIT_LIBRARIES
  178. OpenMP_${LANG}_IMPLICIT_LINK_DIRS
  179. OpenMP_${LANG}_IMPLICIT_FWK_DIRS
  180. OpenMP_${LANG}_LOG_VAR
  181. "${CMAKE_${LANG}_IMPLICIT_OBJECT_REGEX}"
  182. )
  183. file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
  184. "Parsed ${LANG} OpenMP implicit link information from above output:\n${OpenMP_${LANG}_LOG_VAR}\n\n")
  185. unset(_OPENMP_LIB_NAMES)
  186. foreach(_OPENMP_IMPLICIT_LIB IN LISTS OpenMP_${LANG}_IMPLICIT_LIBRARIES)
  187. if(NOT "${_OPENMP_IMPLICIT_LIB}" IN_LIST CMAKE_${LANG}_IMPLICIT_LINK_LIBRARIES)
  188. find_library(OpenMP_${_OPENMP_IMPLICIT_LIB}_LIBRARY
  189. NAMES "${_OPENMP_IMPLICIT_LIB}"
  190. HINTS ${OpenMP_${LANG}_IMPLICIT_LINK_DIRS}
  191. )
  192. mark_as_advanced(OpenMP_${_OPENMP_IMPLICIT_LIB}_LIBRARY)
  193. list(APPEND _OPENMP_LIB_NAMES ${_OPENMP_IMPLICIT_LIB})
  194. endif()
  195. endforeach()
  196. set("${OPENMP_LIB_NAMES_VAR}" "${_OPENMP_LIB_NAMES}" PARENT_SCOPE)
  197. else()
  198. # The Intel compiler on windows has no verbose mode, so we need to treat it explicitly
  199. if("${CMAKE_${LANG}_COMPILER_ID}" STREQUAL "Intel" AND "${CMAKE_SYSTEM_NAME}" STREQUAL "Windows")
  200. set("${OPENMP_LIB_NAMES_VAR}" "libiomp5md" PARENT_SCOPE)
  201. find_library(OpenMP_libiomp5md_LIBRARY
  202. NAMES "libiomp5md"
  203. HINTS ${CMAKE_${LANG}_IMPLICIT_LINK_DIRECTORIES}
  204. )
  205. mark_as_advanced(OpenMP_libiomp5md_LIBRARY)
  206. else()
  207. set("${OPENMP_LIB_NAMES_VAR}" "" PARENT_SCOPE)
  208. endif()
  209. endif()
  210. break()
  211. endif()
  212. set("${OPENMP_LIB_NAMES_VAR}" "NOTFOUND" PARENT_SCOPE)
  213. set("${OPENMP_FLAG_VAR}" "NOTFOUND" PARENT_SCOPE)
  214. endforeach()
  215. endfunction()
  216. set(OpenMP_C_CXX_CHECK_VERSION_SOURCE
  217. "
  218. #include <stdio.h>
  219. #include <omp.h>
  220. const char ompver_str[] = { 'I', 'N', 'F', 'O', ':', 'O', 'p', 'e', 'n', 'M',
  221. 'P', '-', 'd', 'a', 't', 'e', '[',
  222. ('0' + ((_OPENMP/100000)%10)),
  223. ('0' + ((_OPENMP/10000)%10)),
  224. ('0' + ((_OPENMP/1000)%10)),
  225. ('0' + ((_OPENMP/100)%10)),
  226. ('0' + ((_OPENMP/10)%10)),
  227. ('0' + ((_OPENMP/1)%10)),
  228. ']', '\\0' };
  229. int main()
  230. {
  231. puts(ompver_str);
  232. }
  233. ")
  234. set(OpenMP_Fortran_CHECK_VERSION_SOURCE
  235. "
  236. program omp_ver
  237. @OpenMP_Fortran_INCLUDE_LINE@
  238. integer, parameter :: zero = ichar('0')
  239. integer, parameter :: ompv = openmp_version
  240. character, dimension(24), parameter :: ompver_str =&
  241. (/ 'I', 'N', 'F', 'O', ':', 'O', 'p', 'e', 'n', 'M', 'P', '-',&
  242. 'd', 'a', 't', 'e', '[',&
  243. char(zero + mod(ompv/100000, 10)),&
  244. char(zero + mod(ompv/10000, 10)),&
  245. char(zero + mod(ompv/1000, 10)),&
  246. char(zero + mod(ompv/100, 10)),&
  247. char(zero + mod(ompv/10, 10)),&
  248. char(zero + mod(ompv/1, 10)), ']' /)
  249. print *, ompver_str
  250. end program omp_ver
  251. ")
  252. function(_OPENMP_GET_SPEC_DATE LANG SPEC_DATE)
  253. _OPENMP_WRITE_SOURCE_FILE("${LANG}" "CHECK_VERSION_SOURCE" OpenMPCheckVersion _OPENMP_TEST_SRC)
  254. set(BIN_FILE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/FindOpenMP/ompver_${LANG}.bin")
  255. string(REGEX REPLACE "[-/=+]" "" OPENMP_PLAIN_FLAG "${OPENMP_FLAG}")
  256. try_compile(OpenMP_SPECTEST_${LANG}_${OPENMP_PLAIN_FLAG} "${CMAKE_BINARY_DIR}" "${_OPENMP_TEST_SRC}"
  257. CMAKE_FLAGS "-DCOMPILE_DEFINITIONS:STRING=${OpenMP_${LANG}_FLAGS}"
  258. COPY_FILE ${BIN_FILE})
  259. if(${OpenMP_SPECTEST_${LANG}_${OPENMP_PLAIN_FLAG}})
  260. file(STRINGS ${BIN_FILE} specstr LIMIT_COUNT 1 REGEX "INFO:OpenMP-date")
  261. set(regex_spec_date ".*INFO:OpenMP-date\\[0*([^]]*)\\].*")
  262. if("${specstr}" MATCHES "${regex_spec_date}")
  263. set(${SPEC_DATE} "${CMAKE_MATCH_1}" PARENT_SCOPE)
  264. endif()
  265. endif()
  266. endfunction()
  267. macro(_OPENMP_SET_VERSION_BY_SPEC_DATE LANG)
  268. set(OpenMP_SPEC_DATE_MAP
  269. # Preview versions
  270. "201611=5.0" # OpenMP 5.0 preview 1
  271. # Combined versions, 2.5 onwards
  272. "201511=4.5"
  273. "201307=4.0"
  274. "201107=3.1"
  275. "200805=3.0"
  276. "200505=2.5"
  277. # C/C++ version 2.0
  278. "200203=2.0"
  279. # Fortran version 2.0
  280. "200011=2.0"
  281. # Fortran version 1.1
  282. "199911=1.1"
  283. # C/C++ version 1.0 (there's no 1.1 for C/C++)
  284. "199810=1.0"
  285. # Fortran version 1.0
  286. "199710=1.0"
  287. )
  288. string(REGEX MATCHALL "${OpenMP_${LANG}_SPEC_DATE}=([0-9]+)\\.([0-9]+)" _version_match "${OpenMP_SPEC_DATE_MAP}")
  289. if(NOT _version_match STREQUAL "")
  290. set(OpenMP_${LANG}_VERSION_MAJOR ${CMAKE_MATCH_1})
  291. set(OpenMP_${LANG}_VERSION_MINOR ${CMAKE_MATCH_2})
  292. set(OpenMP_${LANG}_VERSION "${OpenMP_${LANG}_VERSION_MAJOR}.${OpenMP_${LANG}_VERSION_MINOR}")
  293. else()
  294. unset(OpenMP_${LANG}_VERSION_MAJOR)
  295. unset(OpenMP_${LANG}_VERSION_MINOR)
  296. unset(OpenMP_${LANG}_VERSION)
  297. endif()
  298. unset(_version_match)
  299. unset(OpenMP_SPEC_DATE_MAP)
  300. endmacro()
  301. foreach(LANG IN ITEMS C CXX)
  302. if(CMAKE_${LANG}_COMPILER_LOADED)
  303. if(NOT DEFINED OpenMP_${LANG}_FLAGS OR "${OpenMP_${LANG}_FLAGS}" STREQUAL "NOTFOUND"
  304. OR NOT DEFINED OpenMP_${LANG}_LIB_NAMES OR "${OpenMP_${LANG}_LIB_NAMES}" STREQUAL "NOTFOUND")
  305. _OPENMP_GET_FLAGS("${LANG}" "${LANG}" OpenMP_${LANG}_FLAGS_WORK OpenMP_${LANG}_LIB_NAMES_WORK)
  306. endif()
  307. set(OpenMP_${LANG}_FLAGS "${OpenMP_${LANG}_FLAGS_WORK}"
  308. CACHE STRING "${LANG} compiler flags for OpenMP parallelization")
  309. set(OpenMP_${LANG}_LIB_NAMES "${OpenMP_${LANG}_LIB_NAMES_WORK}"
  310. CACHE STRING "${LANG} compiler libraries for OpenMP parallelization")
  311. mark_as_advanced(OpenMP_${LANG}_FLAGS OpenMP_${LANG}_LIB_NAMES)
  312. endif()
  313. endforeach()
  314. if(CMAKE_Fortran_COMPILER_LOADED)
  315. if(NOT DEFINED OpenMP_Fortran_FLAGS OR "${OpenMP_Fortran_FLAGS}" STREQUAL "NOTFOUND"
  316. OR NOT DEFINED OpenMP_Fortran_LIB_NAMES OR "${OpenMP_Fortran_LIB_NAMES}" STREQUAL "NOTFOUND"
  317. OR NOT DEFINED OpenMP_Fortran_HAVE_OMPLIB_MODULE)
  318. set(OpenMP_Fortran_INCLUDE_LINE "use omp_lib\n implicit none")
  319. _OPENMP_GET_FLAGS("Fortran" "FortranHeader" OpenMP_Fortran_FLAGS_WORK OpenMP_Fortran_LIB_NAMES_WORK)
  320. if(OpenMP_Fortran_FLAGS_WORK)
  321. set(OpenMP_Fortran_HAVE_OMPLIB_MODULE TRUE CACHE BOOL INTERNAL "")
  322. endif()
  323. set(OpenMP_Fortran_FLAGS "${OpenMP_Fortran_FLAGS_WORK}"
  324. CACHE STRING "Fortran compiler flags for OpenMP parallelization")
  325. set(OpenMP_Fortran_LIB_NAMES "${OpenMP_Fortran_LIB_NAMES_WORK}"
  326. CACHE STRING "Fortran compiler libraries for OpenMP parallelization")
  327. mark_as_advanced(OpenMP_Fortran_FLAGS OpenMP_Fortran_LIB_NAMES)
  328. endif()
  329. if(NOT DEFINED OpenMP_Fortran_FLAGS OR "${OpenMP_Fortran_FLAGS}" STREQUAL "NOTFOUND"
  330. OR NOT DEFINED OpenMP_Fortran_LIB_NAMES OR "${OpenMP_Fortran_LIB_NAMES}" STREQUAL "NOTFOUND"
  331. OR NOT DEFINED OpenMP_Fortran_HAVE_OMPLIB_HEADER)
  332. set(OpenMP_Fortran_INCLUDE_LINE "implicit none\n include 'omp_lib.h'")
  333. _OPENMP_GET_FLAGS("Fortran" "FortranModule" OpenMP_Fortran_FLAGS_WORK OpenMP_Fortran_LIB_NAMES_WORK)
  334. if(OpenMP_Fortran_FLAGS_WORK)
  335. set(OpenMP_Fortran_HAVE_OMPLIB_HEADER TRUE CACHE BOOL INTERNAL "")
  336. endif()
  337. set(OpenMP_Fortran_FLAGS "${OpenMP_Fortran_FLAGS_WORK}"
  338. CACHE STRING "Fortran compiler flags for OpenMP parallelization")
  339. set(OpenMP_Fortran_LIB_NAMES "${OpenMP_Fortran_LIB_NAMES}"
  340. CACHE STRING "Fortran compiler libraries for OpenMP parallelization")
  341. endif()
  342. if(OpenMP_Fortran_HAVE_OMPLIB_MODULE)
  343. set(OpenMP_Fortran_INCLUDE_LINE "use omp_lib\n implicit none")
  344. else()
  345. set(OpenMP_Fortran_INCLUDE_LINE "implicit none\n include 'omp_lib.h'")
  346. endif()
  347. endif()
  348. if(NOT OpenMP_FIND_COMPONENTS)
  349. set(OpenMP_FINDLIST C CXX Fortran)
  350. else()
  351. set(OpenMP_FINDLIST ${OpenMP_FIND_COMPONENTS})
  352. endif()
  353. unset(_OpenMP_MIN_VERSION)
  354. foreach(LANG IN LISTS OpenMP_FINDLIST)
  355. if(CMAKE_${LANG}_COMPILER_LOADED)
  356. if (NOT OpenMP_${LANG}_SPEC_DATE)
  357. _OPENMP_GET_SPEC_DATE("${LANG}" OpenMP_${LANG}_SPEC_DATE_INTERNAL)
  358. set(OpenMP_${LANG}_SPEC_DATE "${OpenMP_${LANG}_SPEC_DATE_INTERNAL}" CACHE
  359. INTERNAL "${LANG} compiler's OpenMP specification date")
  360. _OPENMP_SET_VERSION_BY_SPEC_DATE("${LANG}")
  361. endif()
  362. include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
  363. set(OpenMP_${LANG}_FIND_QUIETLY ${OpenMP_FIND_QUIETLY})
  364. set(OpenMP_${LANG}_FIND_REQUIRED ${OpenMP_FIND_REQUIRED})
  365. set(OpenMP_${LANG}_FIND_VERSION ${OpenMP_FIND_VERSION})
  366. set(OpenMP_${LANG}_FIND_VERSION_EXACT ${OpenMP_FIND_VERSION_EXACT})
  367. set(_OPENMP_${LANG}_REQUIRED_VARS OpenMP_${LANG}_FLAGS)
  368. if("${OpenMP_${LANG}_LIB_NAMES}" STREQUAL "NOTFOUND")
  369. set(_OPENMP_${LANG}_REQUIRED_LIB_VARS OpenMP_${LANG}_LIB_NAMES)
  370. else()
  371. foreach(_OPENMP_IMPLICIT_LIB IN LISTS OpenMP_${LANG}_LIB_NAMES)
  372. list(APPEND _OPENMP_${LANG}_REQUIRED_LIB_VARS OpenMP_${_OPENMP_IMPLICIT_LIB}_LIBRARY)
  373. endforeach()
  374. endif()
  375. find_package_handle_standard_args(OpenMP_${LANG}
  376. REQUIRED_VARS OpenMP_${LANG}_FLAGS ${_OPENMP_${LANG}_REQUIRED_LIB_VARS}
  377. VERSION_VAR OpenMP_${LANG}_VERSION
  378. )
  379. if(OpenMP_${LANG}_FOUND)
  380. if(DEFINED OpenMP_${LANG}_VERSION)
  381. if(NOT _OpenMP_MIN_VERSION OR _OpenMP_MIN_VERSION VERSION_GREATER OpenMP_${LANG}_VERSION)
  382. set(_OpenMP_MIN_VERSION OpenMP_${LANG}_VERSION)
  383. endif()
  384. endif()
  385. set(OpenMP_${LANG}_LIBRARIES "")
  386. foreach(_OPENMP_IMPLICIT_LIB IN LISTS OpenMP_${LANG}_LIB_NAMES)
  387. list(APPEND OpenMP_${LANG}_LIBRARIES "${OpenMP_${_OPENMP_IMPLICIT_LIB}_LIBRARY}")
  388. endforeach()
  389. if(NOT TARGET OpenMP::OpenMP_${LANG})
  390. add_library(OpenMP::OpenMP_${LANG} INTERFACE IMPORTED)
  391. endif()
  392. if(OpenMP_${LANG}_FLAGS)
  393. separate_arguments(_OpenMP_${LANG}_OPTIONS NATIVE_COMMAND "${OpenMP_${LANG}_FLAGS}")
  394. set_property(TARGET OpenMP::OpenMP_${LANG} PROPERTY
  395. INTERFACE_COMPILE_OPTIONS "${_OpenMP_${LANG}_OPTIONS}")
  396. unset(_OpenMP_${LANG}_OPTIONS)
  397. endif()
  398. if(OpenMP_${LANG}_LIBRARIES)
  399. set_property(TARGET OpenMP::OpenMP_${LANG} PROPERTY
  400. INTERFACE_LINK_LIBRARIES "${OpenMP_${LANG}_LIBRARIES}")
  401. endif()
  402. endif()
  403. endif()
  404. endforeach()
  405. unset(_OpenMP_REQ_VARS)
  406. foreach(LANG IN ITEMS C CXX Fortran)
  407. if((NOT OpenMP_FIND_COMPONENTS AND CMAKE_${LANG}_COMPILER_LOADED) OR LANG IN_LIST OpenMP_FIND_COMPONENTS)
  408. list(APPEND _OpenMP_REQ_VARS "OpenMP_${LANG}_FOUND")
  409. endif()
  410. endforeach()
  411. find_package_handle_standard_args(OpenMP
  412. REQUIRED_VARS ${_OpenMP_REQ_VARS}
  413. VERSION_VAR ${_OpenMP_MIN_VERSION}
  414. HANDLE_COMPONENTS)
  415. set(OPENMP_FOUND ${OpenMP_FOUND})
  416. if(CMAKE_Fortran_COMPILER_LOADED AND OpenMP_Fortran_FOUND)
  417. if(NOT DEFINED OpenMP_Fortran_HAVE_OMPLIB_MODULE)
  418. set(OpenMP_Fortran_HAVE_OMPLIB_MODULE FALSE CACHE BOOL INTERNAL "")
  419. endif()
  420. if(NOT DEFINED OpenMP_Fortran_HAVE_OMPLIB_HEADER)
  421. set(OpenMP_Fortran_HAVE_OMPLIB_HEADER FALSE CACHE BOOL INTERNAL "")
  422. endif()
  423. endif()
  424. if(NOT ( CMAKE_C_COMPILER_LOADED OR CMAKE_CXX_COMPILER_LOADED OR CMAKE_Fortran_COMPILER_LOADED ))
  425. message(SEND_ERROR "FindOpenMP requires the C, CXX or Fortran languages to be enabled")
  426. endif()
  427. unset(OpenMP_C_CXX_TEST_SOURCE)
  428. unset(OpenMP_Fortran_TEST_SOURCE)
  429. unset(OpenMP_C_CXX_CHECK_VERSION_SOURCE)
  430. unset(OpenMP_Fortran_CHECK_VERSION_SOURCE)
  431. unset(OpenMP_Fortran_INCLUDE_LINE)
  432. cmake_policy(POP)