OpenCVFindLAPACK.cmake 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. macro(_find_header_file_in_dirs VAR NAME)
  2. unset(${VAR})
  3. unset(${VAR} CACHE)
  4. if(" ${ARGN}" STREQUAL " ")
  5. check_include_file("${NAME}" HAVE_${VAR})
  6. if(HAVE_${VAR})
  7. set(${VAR} "${NAME}") # fallback
  8. else()
  9. set(${VAR} "")
  10. endif()
  11. else()
  12. find_path(${VAR} "${NAME}" ${ARGN} NO_DEFAULT_PATH)
  13. if(${VAR})
  14. set(${VAR} "${${VAR}}/${NAME}")
  15. unset(${VAR} CACHE)
  16. else()
  17. unset(${VAR} CACHE)
  18. set(${VAR} "")
  19. endif()
  20. endif()
  21. endmacro()
  22. macro(ocv_lapack_check)
  23. string(REGEX REPLACE "[^a-zA-Z0-9_]" "_" _lapack_impl "${LAPACK_IMPL}")
  24. message(STATUS "LAPACK(${LAPACK_IMPL}): LAPACK_LIBRARIES: ${LAPACK_LIBRARIES}")
  25. _find_header_file_in_dirs(OPENCV_CBLAS_H_PATH_${_lapack_impl} "${LAPACK_CBLAS_H}" "${LAPACK_INCLUDE_DIR}")
  26. _find_header_file_in_dirs(OPENCV_LAPACKE_H_PATH_${_lapack_impl} "${LAPACK_LAPACKE_H}" "${LAPACK_INCLUDE_DIR}")
  27. if(NOT OPENCV_CBLAS_H_PATH_${_lapack_impl} OR NOT OPENCV_LAPACKE_H_PATH_${_lapack_impl})
  28. message(WARNING "LAPACK(${LAPACK_IMPL}): CBLAS/LAPACK headers are not found in '${LAPACK_INCLUDE_DIR}'")
  29. unset(LAPACK_LIBRARIES)
  30. else()
  31. # adding proxy opencv_lapack.h header
  32. set(CBLAS_H_PROXY_PATH ${CMAKE_BINARY_DIR}/opencv_lapack.h)
  33. set(_lapack_add_extern_c NOT (APPLE OR OPENCV_SKIP_LAPACK_EXTERN_C) OR OPENCV_FORCE_LAPACK_EXTERN_C)
  34. set(_lapack_content "// This file is auto-generated\n")
  35. if(${_lapack_add_extern_c})
  36. list(APPEND _lapack_content "extern \"C\" {")
  37. endif()
  38. if(NOT OPENCV_SKIP_LAPACK_MSVC_FIX)
  39. list(APPEND _lapack_content "
  40. #ifdef _MSC_VER
  41. #include <complex.h>
  42. #define lapack_complex_float _Fcomplex
  43. #define lapack_complex_double _Dcomplex
  44. #endif
  45. ")
  46. endif()
  47. list(APPEND _lapack_content "#include \"${OPENCV_CBLAS_H_PATH_${_lapack_impl}}\"")
  48. if(NOT "${OPENCV_CBLAS_H_PATH_${_lapack_impl}}" STREQUAL "${OPENCV_LAPACKE_H_PATH_${_lapack_impl}}")
  49. list(APPEND _lapack_content "#include \"${OPENCV_LAPACKE_H_PATH_${_lapack_impl}}\"")
  50. endif()
  51. list(APPEND _lapack_content "
  52. #if defined(LAPACK_GLOBAL) || defined(LAPACK_NAME)
  53. /*
  54. * Using netlib's reference LAPACK implementation version >= 3.4.0 (first with C interface).
  55. * Use LAPACK_xxxx to transparently (via predefined lapack macros) deal with pre and post 3.9.1 versions.
  56. * LAPACK 3.9.1 introduces LAPACK_FORTRAN_STRLEN_END and modifies (through preprocessing) the declarations of the following functions used in opencv
  57. * sposv_, dposv_, spotrf_, dpotrf_, sgesdd_, dgesdd_, sgels_, dgels_
  58. * which end up with an extra parameter.
  59. * So we also need to preprocess the function calls in opencv coding by prefixing them with LAPACK_.
  60. * The good news is the preprocessing works fine whatever netlib's LAPACK version.
  61. */
  62. #define OCV_LAPACK_FUNC(f) LAPACK_##f
  63. #else
  64. /* Using other LAPACK implementations so fall back to opencv's assumption until now */
  65. #define OCV_LAPACK_FUNC(f) f##_
  66. #endif
  67. ")
  68. if(${_lapack_add_extern_c})
  69. list(APPEND _lapack_content "}")
  70. endif()
  71. string(REPLACE ";" "\n" _lapack_content "${_lapack_content}")
  72. ocv_update_file("${CBLAS_H_PROXY_PATH}" "${_lapack_content}")
  73. if(CMAKE_GENERATOR MATCHES "Visual Studio" # MSBuild
  74. AND LAPACK_IMPL STREQUAL "MKL"
  75. AND ";${LAPACK_LIBRARIES};" MATCHES ";tbb;" AND TARGET tbb
  76. AND DEFINED TBB_INTERFACE_VERSION AND NOT (TBB_INTERFACE_VERSION LESS 12000) # oneTBB/oneAPI workaround
  77. )
  78. # workaround DEFAULTLIB:tbb12.lib issue
  79. get_target_property(_tbb_lib tbb IMPORTED_LOCATION)
  80. if(NOT _tbb_lib)
  81. get_target_property(_tbb_lib tbb IMPORTED_LOCATION_RELEASE)
  82. endif()
  83. if(_tbb_lib AND NOT OPENCV_SKIP_WORKAROUND_MKL_LINK_DIRECTORIES_TBB)
  84. # MSBuild drops content of 'LIB' environment variable,
  85. # so pass TBB library directory through `link_directories()`
  86. get_filename_component(_tbb_lib_dir "${_tbb_lib}" DIRECTORY)
  87. message(STATUS "MKL: adding '${_tbb_lib_dir}' to link directories (workaround DEFAULTLIB issue)")
  88. link_directories("${_tbb_lib_dir}")
  89. elseif(NOT OPENCV_SKIP_WORKAROUND_MKL_DEFAULTLIB)
  90. # We may have tbb.lib for 'tbb' target, but not 'tbb12.lib'
  91. ocv_update(OPENCV_MKL_IGNORE_DEFAULTLIB_TBB "tbb12.lib")
  92. set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /NODEFAULTLIB:${OPENCV_MKL_IGNORE_DEFAULTLIB_TBB}")
  93. set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /NODEFAULTLIB:${OPENCV_MKL_IGNORE_DEFAULTLIB_TBB}")
  94. endif()
  95. endif()
  96. # TODO add cache for try_compile() inputs/results
  97. get_property(__link_directories DIRECTORY PROPERTY LINK_DIRECTORIES)
  98. if(LAPACK_LINK_LIBRARIES)
  99. list(APPEND __link_directories ${LAPACK_LINK_LIBRARIES})
  100. endif()
  101. try_compile(__VALID_LAPACK
  102. "${OpenCV_BINARY_DIR}"
  103. "${OpenCV_SOURCE_DIR}/cmake/checks/lapack_check.cpp"
  104. CMAKE_FLAGS "-DINCLUDE_DIRECTORIES:STRING=${LAPACK_INCLUDE_DIR}\;${CMAKE_BINARY_DIR}"
  105. "-DLINK_DIRECTORIES:STRING=${__link_directories}"
  106. LINK_LIBRARIES ${LAPACK_LIBRARIES}
  107. OUTPUT_VARIABLE TRY_OUT
  108. )
  109. if(NOT __VALID_LAPACK)
  110. file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
  111. "\nLAPACK(${LAPACK_IMPL}) check FAILED:\n"
  112. " LAPACK_INCLUDE_DIR: '${LAPACK_INCLUDE_DIR}'\n"
  113. " LAPACK_LIBRARIES: '${LAPACK_LIBRARIES}'\n"
  114. " LAPACK_LINK_LIBRARIES: '${__link_directories}'\n"
  115. " Output:\n${TRY_OUT}\n\n")
  116. message(STATUS "LAPACK(${LAPACK_IMPL}): Can't build LAPACK check code. This LAPACK version is not supported.")
  117. unset(LAPACK_LIBRARIES)
  118. else()
  119. message(STATUS "LAPACK(${LAPACK_IMPL}): Support is enabled.")
  120. ocv_include_directories(${LAPACK_INCLUDE_DIR})
  121. set(HAVE_LAPACK 1)
  122. endif()
  123. endif()
  124. endmacro()
  125. if(WITH_LAPACK)
  126. ocv_update(LAPACK_IMPL "Unknown")
  127. if(NOT OPENCV_LAPACK_FIND_PACKAGE_ONLY)
  128. if(NOT LAPACK_LIBRARIES AND NOT OPENCV_LAPACK_DISABLE_MKL)
  129. include(cmake/OpenCVFindMKL.cmake)
  130. if(HAVE_MKL)
  131. set(LAPACK_INCLUDE_DIR ${MKL_INCLUDE_DIRS})
  132. set(LAPACK_LIBRARIES ${MKL_LIBRARIES})
  133. set(LAPACK_CBLAS_H "mkl_cblas.h")
  134. set(LAPACK_LAPACKE_H "mkl_lapack.h")
  135. set(LAPACK_IMPL "MKL")
  136. ocv_lapack_check()
  137. endif()
  138. endif()
  139. if(NOT LAPACK_LIBRARIES)
  140. include(cmake/OpenCVFindOpenBLAS.cmake)
  141. if(OpenBLAS_FOUND)
  142. set(LAPACK_INCLUDE_DIR ${OpenBLAS_INCLUDE_DIR})
  143. set(LAPACK_LIBRARIES ${OpenBLAS_LIB})
  144. set(LAPACK_CBLAS_H "cblas.h")
  145. set(LAPACK_LAPACKE_H "lapacke.h")
  146. set(LAPACK_IMPL "OpenBLAS")
  147. ocv_lapack_check()
  148. endif()
  149. endif()
  150. if(NOT LAPACK_LIBRARIES AND UNIX)
  151. include(cmake/OpenCVFindAtlas.cmake)
  152. if(ATLAS_FOUND)
  153. set(LAPACK_INCLUDE_DIR ${Atlas_INCLUDE_DIR})
  154. set(LAPACK_LIBRARIES ${Atlas_LIBRARIES})
  155. set(LAPACK_CBLAS_H "cblas.h")
  156. set(LAPACK_LAPACKE_H "lapacke.h")
  157. set(LAPACK_IMPL "Atlas")
  158. ocv_lapack_check()
  159. endif()
  160. endif()
  161. endif()
  162. if(NOT LAPACK_LIBRARIES)
  163. if(WIN32 AND NOT OPENCV_LAPACK_SHARED_LIBS)
  164. set(BLA_STATIC 1)
  165. endif()
  166. find_package(LAPACK)
  167. if(LAPACK_FOUND)
  168. if(NOT DEFINED LAPACKE_INCLUDE_DIR)
  169. find_path(LAPACKE_INCLUDE_DIR "lapacke.h")
  170. endif()
  171. if(NOT DEFINED MKL_LAPACKE_INCLUDE_DIR)
  172. find_path(MKL_LAPACKE_INCLUDE_DIR "mkl_lapack.h")
  173. endif()
  174. if(MKL_LAPACKE_INCLUDE_DIR AND NOT OPENCV_LAPACK_DISABLE_MKL)
  175. set(LAPACK_INCLUDE_DIR ${MKL_LAPACKE_INCLUDE_DIR})
  176. set(LAPACK_CBLAS_H "mkl_cblas.h")
  177. set(LAPACK_LAPACKE_H "mkl_lapack.h")
  178. set(LAPACK_IMPL "LAPACK/MKL")
  179. ocv_lapack_check()
  180. endif()
  181. if(NOT HAVE_LAPACK)
  182. if(LAPACKE_INCLUDE_DIR)
  183. set(LAPACK_INCLUDE_DIR ${LAPACKE_INCLUDE_DIR})
  184. set(LAPACK_CBLAS_H "cblas.h")
  185. set(LAPACK_LAPACKE_H "lapacke.h")
  186. set(LAPACK_IMPL "LAPACK/Generic")
  187. ocv_lapack_check()
  188. elseif(APPLE)
  189. set(LAPACK_CBLAS_H "Accelerate/Accelerate.h")
  190. set(LAPACK_LAPACKE_H "Accelerate/Accelerate.h")
  191. set(LAPACK_IMPL "LAPACK/Apple")
  192. ocv_lapack_check()
  193. endif()
  194. endif()
  195. endif()
  196. if(NOT HAVE_LAPACK)
  197. unset(LAPACK_LIBRARIES)
  198. unset(LAPACK_LIBRARIES CACHE)
  199. endif()
  200. endif()
  201. if(NOT LAPACK_LIBRARIES AND APPLE AND NOT OPENCV_LAPACK_FIND_PACKAGE_ONLY)
  202. set(LAPACK_INCLUDE_DIR "")
  203. set(LAPACK_LIBRARIES "-framework Accelerate")
  204. set(LAPACK_CBLAS_H "Accelerate/Accelerate.h")
  205. set(LAPACK_LAPACKE_H "Accelerate/Accelerate.h")
  206. set(LAPACK_IMPL "Apple")
  207. ocv_lapack_check()
  208. endif()
  209. if(NOT HAVE_LAPACK AND LAPACK_LIBRARIES AND LAPACK_CBLAS_H AND LAPACK_LAPACKE_H)
  210. ocv_lapack_check()
  211. endif()
  212. set(LAPACK_INCLUDE_DIR ${LAPACK_INCLUDE_DIR} CACHE PATH "Path to BLAS include dir" FORCE)
  213. set(LAPACK_CBLAS_H ${LAPACK_CBLAS_H} CACHE STRING "Alternative name of cblas.h" FORCE)
  214. set(LAPACK_LAPACKE_H ${LAPACK_LAPACKE_H} CACHE STRING "Alternative name of lapacke.h" FORCE)
  215. set(LAPACK_LIBRARIES ${LAPACK_LIBRARIES} CACHE STRING "Names of BLAS & LAPACK binaries (.so, .dll, .a, .lib)" FORCE)
  216. set(LAPACK_IMPL ${LAPACK_IMPL} CACHE STRING "Lapack implementation id" FORCE)
  217. endif()