FindOpenMP.cmake 21 KB

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