FindOpenMP.cmake 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  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 <[email protected]>
  29. # Copyright 2012 Rolf Eike Beer <[email protected]>
  30. # Copyright 2014 Nicolas Bock <[email protected]>
  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. #Microsoft Visual Studio
  51. "/openmp"
  52. #Intel windows
  53. "-Qopenmp"
  54. #PathScale, Intel
  55. "-openmp"
  56. #Sun
  57. "-xopenmp"
  58. #HP
  59. "+Oopenmp"
  60. #IBM XL C/c++
  61. "-qsmp"
  62. #Portland Group, MIPSpro
  63. "-mp"
  64. )
  65. set(OMP_FLAG_GNU "-fopenmp")
  66. set(OMP_FLAG_HP "+Oopenmp")
  67. if(WIN32)
  68. set(OMP_FLAG_Intel "-Qopenmp")
  69. elseif(CMAKE_${LANG}_COMPILER_ID STREQUAL "Intel" AND
  70. "${CMAKE_${LANG}_COMPILER_VERSION}" VERSION_LESS "15.0.0.20140528")
  71. set(OMP_FLAG_Intel "-openmp")
  72. else()
  73. set(OMP_FLAG_Intel "-qopenmp")
  74. endif()
  75. set(OMP_FLAG_MIPSpro "-mp")
  76. set(OMP_FLAG_MSVC "/openmp")
  77. set(OMP_FLAG_PathScale "-openmp")
  78. set(OMP_FLAG_PGI "-mp")
  79. set(OMP_FLAG_SunPro "-xopenmp")
  80. set(OMP_FLAG_XL "-qsmp")
  81. set(OMP_FLAG_Cray " ")
  82. # Move the flag that matches the compiler to the head of the list,
  83. # this is faster and doesn't clutter the output that much. If that
  84. # flag doesn't work we will still try all.
  85. if(OMP_FLAG_${CMAKE_${LANG}_COMPILER_ID})
  86. list(REMOVE_ITEM OpenMP_FLAG_CANDIDATES "${OMP_FLAG_${CMAKE_${LANG}_COMPILER_ID}}")
  87. list(INSERT OpenMP_FLAG_CANDIDATES 0 "${OMP_FLAG_${CMAKE_${LANG}_COMPILER_ID}}")
  88. endif()
  89. set(OpenMP_${LANG}_FLAG_CANDIDATES "${OpenMP_FLAG_CANDIDATES}" PARENT_SCOPE)
  90. endfunction()
  91. # sample openmp source code to test
  92. set(OpenMP_C_TEST_SOURCE
  93. "
  94. #include <omp.h>
  95. int main() {
  96. #ifdef _OPENMP
  97. return 0;
  98. #else
  99. breaks_on_purpose
  100. #endif
  101. }
  102. ")
  103. # same in Fortran
  104. set(OpenMP_Fortran_TEST_SOURCE
  105. "
  106. program test
  107. use omp_lib
  108. integer :: n
  109. n = omp_get_num_threads()
  110. end program test
  111. "
  112. )
  113. # check c compiler
  114. if(CMAKE_C_COMPILER_LOADED)
  115. # if these are set then do not try to find them again,
  116. # by avoiding any try_compiles for the flags
  117. if(OpenMP_C_FLAGS)
  118. unset(OpenMP_C_FLAG_CANDIDATES)
  119. else()
  120. _OPENMP_FLAG_CANDIDATES("C")
  121. include(${CMAKE_CURRENT_LIST_DIR}/CheckCSourceCompiles.cmake)
  122. endif()
  123. foreach(FLAG IN LISTS OpenMP_C_FLAG_CANDIDATES)
  124. set(SAFE_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}")
  125. set(CMAKE_REQUIRED_FLAGS "${FLAG}")
  126. unset(OpenMP_FLAG_DETECTED CACHE)
  127. if(NOT CMAKE_REQUIRED_QUIET)
  128. message(STATUS "Try OpenMP C flag = [${FLAG}]")
  129. endif()
  130. check_c_source_compiles("${OpenMP_C_TEST_SOURCE}" OpenMP_FLAG_DETECTED)
  131. set(CMAKE_REQUIRED_FLAGS "${SAFE_CMAKE_REQUIRED_FLAGS}")
  132. if(OpenMP_FLAG_DETECTED)
  133. set(OpenMP_C_FLAGS_INTERNAL "${FLAG}")
  134. break()
  135. endif()
  136. endforeach()
  137. set(OpenMP_C_FLAGS "${OpenMP_C_FLAGS_INTERNAL}"
  138. CACHE STRING "C compiler flags for OpenMP parallization")
  139. list(APPEND _OPENMP_REQUIRED_VARS OpenMP_C_FLAGS)
  140. unset(OpenMP_C_FLAG_CANDIDATES)
  141. endif()
  142. # check cxx compiler
  143. if(CMAKE_CXX_COMPILER_LOADED)
  144. # if these are set then do not try to find them again,
  145. # by avoiding any try_compiles for the flags
  146. if(OpenMP_CXX_FLAGS)
  147. unset(OpenMP_CXX_FLAG_CANDIDATES)
  148. else()
  149. _OPENMP_FLAG_CANDIDATES("CXX")
  150. include(${CMAKE_CURRENT_LIST_DIR}/CheckCXXSourceCompiles.cmake)
  151. # use the same source for CXX as C for now
  152. set(OpenMP_CXX_TEST_SOURCE ${OpenMP_C_TEST_SOURCE})
  153. endif()
  154. foreach(FLAG IN LISTS OpenMP_CXX_FLAG_CANDIDATES)
  155. set(SAFE_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}")
  156. set(CMAKE_REQUIRED_FLAGS "${FLAG}")
  157. unset(OpenMP_FLAG_DETECTED CACHE)
  158. if(NOT CMAKE_REQUIRED_QUIET)
  159. message(STATUS "Try OpenMP CXX flag = [${FLAG}]")
  160. endif()
  161. check_cxx_source_compiles("${OpenMP_CXX_TEST_SOURCE}" OpenMP_FLAG_DETECTED)
  162. set(CMAKE_REQUIRED_FLAGS "${SAFE_CMAKE_REQUIRED_FLAGS}")
  163. if(OpenMP_FLAG_DETECTED)
  164. set(OpenMP_CXX_FLAGS_INTERNAL "${FLAG}")
  165. break()
  166. endif()
  167. endforeach()
  168. set(OpenMP_CXX_FLAGS "${OpenMP_CXX_FLAGS_INTERNAL}"
  169. CACHE STRING "C++ compiler flags for OpenMP parallization")
  170. list(APPEND _OPENMP_REQUIRED_VARS OpenMP_CXX_FLAGS)
  171. unset(OpenMP_CXX_FLAG_CANDIDATES)
  172. unset(OpenMP_CXX_TEST_SOURCE)
  173. endif()
  174. # check Fortran compiler
  175. if(CMAKE_Fortran_COMPILER_LOADED)
  176. # if these are set then do not try to find them again,
  177. # by avoiding any try_compiles for the flags
  178. if(OpenMP_Fortran_FLAGS)
  179. unset(OpenMP_Fortran_FLAG_CANDIDATES)
  180. else()
  181. _OPENMP_FLAG_CANDIDATES("Fortran")
  182. include(${CMAKE_CURRENT_LIST_DIR}/CheckFortranSourceCompiles.cmake)
  183. endif()
  184. foreach(FLAG IN LISTS OpenMP_Fortran_FLAG_CANDIDATES)
  185. set(SAFE_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}")
  186. set(CMAKE_REQUIRED_FLAGS "${FLAG}")
  187. unset(OpenMP_FLAG_DETECTED CACHE)
  188. if(NOT CMAKE_REQUIRED_QUIET)
  189. message(STATUS "Try OpenMP Fortran flag = [${FLAG}]")
  190. endif()
  191. check_fortran_source_compiles("${OpenMP_Fortran_TEST_SOURCE}" OpenMP_FLAG_DETECTED)
  192. set(CMAKE_REQUIRED_FLAGS "${SAFE_CMAKE_REQUIRED_FLAGS}")
  193. if(OpenMP_FLAG_DETECTED)
  194. set(OpenMP_Fortran_FLAGS_INTERNAL "${FLAG}")
  195. break()
  196. endif()
  197. endforeach()
  198. set(OpenMP_Fortran_FLAGS "${OpenMP_Fortran_FLAGS_INTERNAL}"
  199. CACHE STRING "Fortran compiler flags for OpenMP parallization")
  200. list(APPEND _OPENMP_REQUIRED_VARS OpenMP_Fortran_FLAGS)
  201. unset(OpenMP_Fortran_FLAG_CANDIDATES)
  202. unset(OpenMP_Fortran_TEST_SOURCE)
  203. endif()
  204. set(CMAKE_REQUIRED_QUIET ${CMAKE_REQUIRED_QUIET_SAVE})
  205. if(_OPENMP_REQUIRED_VARS)
  206. include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
  207. find_package_handle_standard_args(OpenMP
  208. REQUIRED_VARS ${_OPENMP_REQUIRED_VARS})
  209. mark_as_advanced(${_OPENMP_REQUIRED_VARS})
  210. unset(_OPENMP_REQUIRED_VARS)
  211. else()
  212. message(SEND_ERROR "FindOpenMP requires C or CXX language to be enabled")
  213. endif()