FindOpenMP.cmake 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. #.rst:
  2. # FindOpenMP
  3. # ----------
  4. #
  5. # Finds OpenMP support
  6. #
  7. # This module can be used to detect OpenMP support in a compiler. If
  8. # the compiler supports OpenMP, the flags required to compile with
  9. # OpenMP support are returned in variables for the different languages.
  10. # The variables may be empty if the compiler does not need a special
  11. # flag to support OpenMP.
  12. #
  13. # The following variables are set:
  14. #
  15. # ::
  16. #
  17. # OpenMP_C_FLAGS - flags to add to the C compiler for OpenMP support
  18. # OpenMP_CXX_FLAGS - flags to add to the CXX compiler for OpenMP support
  19. # OpenMP_Fortran_FLAGS - flags to add to the Fortran compiler for OpenMP support
  20. # OPENMP_FOUND - true if openmp is detected
  21. #
  22. #
  23. #
  24. # Supported compilers can be found at
  25. # http://openmp.org/wp/openmp-compilers/
  26. #=============================================================================
  27. # Copyright 2009 Kitware, Inc.
  28. # Copyright 2008-2009 André Rigland Brodtkorb <Andre.Brodtkorb@ifi.uio.no>
  29. # Copyright 2012 Rolf Eike Beer <eike@sf-mail.de>
  30. # Copyright 2014 Nicolas Bock <nicolasbock@gmail.com>
  31. #
  32. # Distributed under the OSI-approved BSD License (the "License");
  33. # see accompanying file Copyright.txt for details.
  34. #
  35. # This software is distributed WITHOUT ANY WARRANTY; without even the
  36. # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  37. # See the License for more information.
  38. #=============================================================================
  39. # (To distribute this file outside of CMake, substitute the full
  40. # License text for the above reference.)
  41. set(_OPENMP_REQUIRED_VARS)
  42. set(CMAKE_REQUIRED_QUIET_SAVE ${CMAKE_REQUIRED_QUIET})
  43. set(CMAKE_REQUIRED_QUIET ${OpenMP_FIND_QUIETLY})
  44. function(_OPENMP_FLAG_CANDIDATES LANG)
  45. set(OpenMP_FLAG_CANDIDATES
  46. #Empty, if compiler automatically accepts openmp
  47. " "
  48. #GNU
  49. "-fopenmp"
  50. #Clang
  51. "-fopenmp=libomp"
  52. #Microsoft Visual Studio
  53. "/openmp"
  54. #Intel windows
  55. "-Qopenmp"
  56. #PathScale, Intel
  57. "-openmp"
  58. #Sun
  59. "-xopenmp"
  60. #HP
  61. "+Oopenmp"
  62. #IBM XL C/c++
  63. "-qsmp"
  64. #Portland Group, MIPSpro
  65. "-mp"
  66. )
  67. set(OMP_FLAG_GNU "-fopenmp")
  68. set(OMP_FLAG_Clang "-fopenmp=libomp")
  69. set(OMP_FLAG_HP "+Oopenmp")
  70. if(WIN32)
  71. set(OMP_FLAG_Intel "-Qopenmp")
  72. elseif(CMAKE_${LANG}_COMPILER_ID STREQUAL "Intel" AND
  73. "${CMAKE_${LANG}_COMPILER_VERSION}" VERSION_LESS "15.0.0.20140528")
  74. set(OMP_FLAG_Intel "-openmp")
  75. else()
  76. set(OMP_FLAG_Intel "-qopenmp")
  77. endif()
  78. set(OMP_FLAG_MIPSpro "-mp")
  79. set(OMP_FLAG_MSVC "/openmp")
  80. set(OMP_FLAG_PathScale "-openmp")
  81. set(OMP_FLAG_PGI "-mp")
  82. set(OMP_FLAG_SunPro "-xopenmp")
  83. set(OMP_FLAG_XL "-qsmp")
  84. set(OMP_FLAG_Cray " ")
  85. # Move the flag that matches the compiler to the head of the list,
  86. # this is faster and doesn't clutter the output that much. If that
  87. # flag doesn't work we will still try all.
  88. if(OMP_FLAG_${CMAKE_${LANG}_COMPILER_ID})
  89. list(REMOVE_ITEM OpenMP_FLAG_CANDIDATES "${OMP_FLAG_${CMAKE_${LANG}_COMPILER_ID}}")
  90. list(INSERT OpenMP_FLAG_CANDIDATES 0 "${OMP_FLAG_${CMAKE_${LANG}_COMPILER_ID}}")
  91. endif()
  92. set(OpenMP_${LANG}_FLAG_CANDIDATES "${OpenMP_FLAG_CANDIDATES}" PARENT_SCOPE)
  93. endfunction()
  94. # sample openmp source code to test
  95. set(OpenMP_C_TEST_SOURCE
  96. "
  97. #include <omp.h>
  98. int main() {
  99. #ifdef _OPENMP
  100. return 0;
  101. #else
  102. breaks_on_purpose
  103. #endif
  104. }
  105. ")
  106. # same in Fortran
  107. set(OpenMP_Fortran_TEST_SOURCE
  108. "
  109. program test
  110. use omp_lib
  111. integer :: n
  112. n = omp_get_num_threads()
  113. end program test
  114. "
  115. )
  116. # check c compiler
  117. if(CMAKE_C_COMPILER_LOADED)
  118. # if these are set then do not try to find them again,
  119. # by avoiding any try_compiles for the flags
  120. if(OpenMP_C_FLAGS)
  121. unset(OpenMP_C_FLAG_CANDIDATES)
  122. else()
  123. _OPENMP_FLAG_CANDIDATES("C")
  124. include(${CMAKE_CURRENT_LIST_DIR}/CheckCSourceCompiles.cmake)
  125. endif()
  126. foreach(FLAG IN LISTS OpenMP_C_FLAG_CANDIDATES)
  127. set(SAFE_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}")
  128. set(CMAKE_REQUIRED_FLAGS "${FLAG}")
  129. unset(OpenMP_FLAG_DETECTED CACHE)
  130. if(NOT CMAKE_REQUIRED_QUIET)
  131. message(STATUS "Try OpenMP C flag = [${FLAG}]")
  132. endif()
  133. check_c_source_compiles("${OpenMP_C_TEST_SOURCE}" OpenMP_FLAG_DETECTED)
  134. set(CMAKE_REQUIRED_FLAGS "${SAFE_CMAKE_REQUIRED_FLAGS}")
  135. if(OpenMP_FLAG_DETECTED)
  136. set(OpenMP_C_FLAGS_INTERNAL "${FLAG}")
  137. break()
  138. endif()
  139. endforeach()
  140. set(OpenMP_C_FLAGS "${OpenMP_C_FLAGS_INTERNAL}"
  141. CACHE STRING "C compiler flags for OpenMP parallization")
  142. list(APPEND _OPENMP_REQUIRED_VARS OpenMP_C_FLAGS)
  143. unset(OpenMP_C_FLAG_CANDIDATES)
  144. endif()
  145. # check cxx compiler
  146. if(CMAKE_CXX_COMPILER_LOADED)
  147. # if these are set then do not try to find them again,
  148. # by avoiding any try_compiles for the flags
  149. if(OpenMP_CXX_FLAGS)
  150. unset(OpenMP_CXX_FLAG_CANDIDATES)
  151. else()
  152. _OPENMP_FLAG_CANDIDATES("CXX")
  153. include(${CMAKE_CURRENT_LIST_DIR}/CheckCXXSourceCompiles.cmake)
  154. # use the same source for CXX as C for now
  155. set(OpenMP_CXX_TEST_SOURCE ${OpenMP_C_TEST_SOURCE})
  156. endif()
  157. foreach(FLAG IN LISTS OpenMP_CXX_FLAG_CANDIDATES)
  158. set(SAFE_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}")
  159. set(CMAKE_REQUIRED_FLAGS "${FLAG}")
  160. unset(OpenMP_FLAG_DETECTED CACHE)
  161. if(NOT CMAKE_REQUIRED_QUIET)
  162. message(STATUS "Try OpenMP CXX flag = [${FLAG}]")
  163. endif()
  164. check_cxx_source_compiles("${OpenMP_CXX_TEST_SOURCE}" OpenMP_FLAG_DETECTED)
  165. set(CMAKE_REQUIRED_FLAGS "${SAFE_CMAKE_REQUIRED_FLAGS}")
  166. if(OpenMP_FLAG_DETECTED)
  167. set(OpenMP_CXX_FLAGS_INTERNAL "${FLAG}")
  168. break()
  169. endif()
  170. endforeach()
  171. set(OpenMP_CXX_FLAGS "${OpenMP_CXX_FLAGS_INTERNAL}"
  172. CACHE STRING "C++ compiler flags for OpenMP parallization")
  173. list(APPEND _OPENMP_REQUIRED_VARS OpenMP_CXX_FLAGS)
  174. unset(OpenMP_CXX_FLAG_CANDIDATES)
  175. unset(OpenMP_CXX_TEST_SOURCE)
  176. endif()
  177. # check Fortran compiler
  178. if(CMAKE_Fortran_COMPILER_LOADED)
  179. # if these are set then do not try to find them again,
  180. # by avoiding any try_compiles for the flags
  181. if(OpenMP_Fortran_FLAGS)
  182. unset(OpenMP_Fortran_FLAG_CANDIDATES)
  183. else()
  184. _OPENMP_FLAG_CANDIDATES("Fortran")
  185. include(${CMAKE_CURRENT_LIST_DIR}/CheckFortranSourceCompiles.cmake)
  186. endif()
  187. foreach(FLAG IN LISTS OpenMP_Fortran_FLAG_CANDIDATES)
  188. set(SAFE_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}")
  189. set(CMAKE_REQUIRED_FLAGS "${FLAG}")
  190. unset(OpenMP_FLAG_DETECTED CACHE)
  191. if(NOT CMAKE_REQUIRED_QUIET)
  192. message(STATUS "Try OpenMP Fortran flag = [${FLAG}]")
  193. endif()
  194. check_fortran_source_compiles("${OpenMP_Fortran_TEST_SOURCE}" OpenMP_FLAG_DETECTED)
  195. set(CMAKE_REQUIRED_FLAGS "${SAFE_CMAKE_REQUIRED_FLAGS}")
  196. if(OpenMP_FLAG_DETECTED)
  197. set(OpenMP_Fortran_FLAGS_INTERNAL "${FLAG}")
  198. break()
  199. endif()
  200. endforeach()
  201. set(OpenMP_Fortran_FLAGS "${OpenMP_Fortran_FLAGS_INTERNAL}"
  202. CACHE STRING "Fortran compiler flags for OpenMP parallization")
  203. list(APPEND _OPENMP_REQUIRED_VARS OpenMP_Fortran_FLAGS)
  204. unset(OpenMP_Fortran_FLAG_CANDIDATES)
  205. unset(OpenMP_Fortran_TEST_SOURCE)
  206. endif()
  207. set(CMAKE_REQUIRED_QUIET ${CMAKE_REQUIRED_QUIET_SAVE})
  208. if(_OPENMP_REQUIRED_VARS)
  209. include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
  210. find_package_handle_standard_args(OpenMP
  211. REQUIRED_VARS ${_OPENMP_REQUIRED_VARS})
  212. mark_as_advanced(${_OPENMP_REQUIRED_VARS})
  213. unset(_OPENMP_REQUIRED_VARS)
  214. else()
  215. message(SEND_ERROR "FindOpenMP requires C or CXX language to be enabled")
  216. endif()