diff --git a/CMakeLists.txt b/CMakeLists.txt index a7771f7d02..25b1322c3e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1700,7 +1700,7 @@ if(WITH_VA OR HAVE_VA) endif() if(WITH_LAPACK OR HAVE_LAPACK) - status(" Lapack:" HAVE_LAPACK THEN "YES (${LAPACK_LIBRARIES} ${LAPACK_VERSION})" ELSE NO) + status(" Lapack:" HAVE_LAPACK THEN "YES (${LAPACK_IMPL} ${LAPACK_LIBRARIES})" ELSE NO) endif() if(HAVE_OPENVINO diff --git a/cmake/OpenCVFindLAPACK.cmake b/cmake/OpenCVFindLAPACK.cmake index a572eb7e94..99132aab0a 100644 --- a/cmake/OpenCVFindLAPACK.cmake +++ b/cmake/OpenCVFindLAPACK.cmake @@ -43,17 +43,38 @@ macro(_find_header_file_in_dirs VAR NAME) endif() endmacro() -macro(ocv_lapack_make_hdr _cblas_hdr _lapacke_hdr) - # adding proxy opencv_lapack.h header - set(CBLAS_H_PROXY_PATH ${CMAKE_BINARY_DIR}/opencv_lapack.h) +macro(ocv_lapack_check) + cmake_parse_arguments(LAPACK "SKIP_BUILD;SKIP_FIND" "IMPL;CBLAS_H;LAPACKE_H" "INCLUDE_DIR;LIBRARIES" ${ARGN}) - set(_lapack_add_extern_c NOT (APPLE OR OPENCV_SKIP_LAPACK_EXTERN_C) OR OPENCV_FORCE_LAPACK_EXTERN_C) + ocv_debug_message("LAPACK_IMPL=${LAPACK_IMPL}") + ocv_debug_message("LAPACK_CBLAS_H=${LAPACK_CBLAS_H}") + ocv_debug_message("LAPACK_LAPACKE_H=${LAPACK_LAPACKE_H}") + ocv_debug_message("LAPACK_INCLUDE_DIR=${LAPACK_INCLUDE_DIR}") + ocv_debug_message("LAPACK_LIBRARIES=${LAPACK_LIBRARIES}") - set(_lapack_content "// This file is auto-generated\n") - if(${_lapack_add_extern_c}) - list(APPEND _lapack_content "extern \"C\" {") + string(REGEX REPLACE "[^a-zA-Z0-9_]" "_" _lapack_impl "${LAPACK_IMPL}") + message(STATUS "LAPACK(${LAPACK_IMPL}): LAPACK_LIBRARIES: ${LAPACK_LIBRARIES}") + if(NOT LAPACK_SKIP_FIND) + _find_header_file_in_dirs(OPENCV_CBLAS_H_PATH_${_lapack_impl} "${LAPACK_CBLAS_H}" "${LAPACK_INCLUDE_DIR}") + _find_header_file_in_dirs(OPENCV_LAPACKE_H_PATH_${_lapack_impl} "${LAPACK_LAPACKE_H}" "${LAPACK_INCLUDE_DIR}") + else() + set(OPENCV_CBLAS_H_PATH_${_lapack_impl} "${LAPACK_INCLUDE_DIR}/${LAPACK_CBLAS_H}") + set(OPENCV_LAPACKE_H_PATH_${_lapack_impl} "${LAPACK_INCLUDE_DIR}/${LAPACK_LAPACKE_H}") endif() - if(NOT OPENCV_SKIP_LAPACK_MSVC_FIX) + if(NOT OPENCV_CBLAS_H_PATH_${_lapack_impl} OR NOT OPENCV_LAPACKE_H_PATH_${_lapack_impl}) + message(WARNING "LAPACK(${LAPACK_IMPL}): CBLAS/LAPACK headers are not found in '${LAPACK_INCLUDE_DIR}'") + unset(LAPACK_LIBRARIES) + else() + # adding proxy opencv_lapack.h header + set(CBLAS_H_PROXY_PATH ${CMAKE_BINARY_DIR}/opencv_lapack.h) + + set(_lapack_add_extern_c NOT (APPLE OR OPENCV_SKIP_LAPACK_EXTERN_C) OR OPENCV_FORCE_LAPACK_EXTERN_C) + + set(_lapack_content "// This file is auto-generated\n") + if(${_lapack_add_extern_c}) + list(APPEND _lapack_content "extern \"C\" {") + endif() + if(NOT OPENCV_SKIP_LAPACK_MSVC_FIX) list(APPEND _lapack_content " #ifdef _MSC_VER #include @@ -61,12 +82,12 @@ macro(ocv_lapack_make_hdr _cblas_hdr _lapacke_hdr) #define lapack_complex_double _Dcomplex #endif ") - endif() - list(APPEND _lapack_content "#include \"${_cblas_hdr}\"") - if(NOT "${_cblas_hdr}" STREQUAL "${_lapacke_hdr}") - list(APPEND _lapack_content "#include \"${_lapacke_hdr}\"") - endif() - list(APPEND _lapack_content " + endif() + list(APPEND _lapack_content "#include \"${OPENCV_CBLAS_H_PATH_${_lapack_impl}}\"") + if(NOT "${OPENCV_CBLAS_H_PATH_${_lapack_impl}}" STREQUAL "${OPENCV_LAPACKE_H_PATH_${_lapack_impl}}") + list(APPEND _lapack_content "#include \"${OPENCV_LAPACKE_H_PATH_${_lapack_impl}}\"") + endif() + list(APPEND _lapack_content " #if defined(LAPACK_GLOBAL) || defined(LAPACK_NAME) /* * Using netlib's reference LAPACK implementation version >= 3.4.0 (first with C interface). @@ -83,44 +104,43 @@ macro(ocv_lapack_make_hdr _cblas_hdr _lapacke_hdr) #define OCV_LAPACK_FUNC(f) f##_ #endif ") - if(${_lapack_add_extern_c}) - list(APPEND _lapack_content "}") - endif() - string(REPLACE ";" "\n" _lapack_content "${_lapack_content}") - ocv_update_file("${CBLAS_H_PROXY_PATH}" "${_lapack_content}") -endmacro() - -macro(ocv_lapack_run_check) - if(CMAKE_GENERATOR MATCHES "Visual Studio" # MSBuild - AND LAPACK_IMPL STREQUAL "MKL" - AND ";${LAPACK_LIBRARIES};" MATCHES ";tbb;" AND TARGET tbb - AND DEFINED TBB_INTERFACE_VERSION AND NOT (TBB_INTERFACE_VERSION LESS 12000) # oneTBB/oneAPI workaround - ) - # workaround DEFAULTLIB:tbb12.lib issue - get_target_property(_tbb_lib tbb IMPORTED_LOCATION) - if(NOT _tbb_lib) - get_target_property(_tbb_lib tbb IMPORTED_LOCATION_RELEASE) + if(${_lapack_add_extern_c}) + list(APPEND _lapack_content "}") endif() - if(_tbb_lib AND NOT OPENCV_SKIP_WORKAROUND_MKL_LINK_DIRECTORIES_TBB) - # MSBuild drops content of 'LIB' environment variable, - # so pass TBB library directory through `link_directories()` - get_filename_component(_tbb_lib_dir "${_tbb_lib}" DIRECTORY) - message(STATUS "MKL: adding '${_tbb_lib_dir}' to link directories (workaround DEFAULTLIB issue)") - link_directories("${_tbb_lib_dir}") - elseif(NOT OPENCV_SKIP_WORKAROUND_MKL_DEFAULTLIB) - # We may have tbb.lib for 'tbb' target, but not 'tbb12.lib' - ocv_update(OPENCV_MKL_IGNORE_DEFAULTLIB_TBB "tbb12.lib") - set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /NODEFAULTLIB:${OPENCV_MKL_IGNORE_DEFAULTLIB_TBB}") - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /NODEFAULTLIB:${OPENCV_MKL_IGNORE_DEFAULTLIB_TBB}") + + string(REPLACE ";" "\n" _lapack_content "${_lapack_content}") + ocv_update_file("${CBLAS_H_PROXY_PATH}" "${_lapack_content}") + + if(CMAKE_GENERATOR MATCHES "Visual Studio" # MSBuild + AND LAPACK_IMPL STREQUAL "MKL" + AND ";${LAPACK_LIBRARIES};" MATCHES ";tbb;" AND TARGET tbb + AND DEFINED TBB_INTERFACE_VERSION AND NOT (TBB_INTERFACE_VERSION LESS 12000) # oneTBB/oneAPI workaround + ) + # workaround DEFAULTLIB:tbb12.lib issue + get_target_property(_tbb_lib tbb IMPORTED_LOCATION) + if(NOT _tbb_lib) + get_target_property(_tbb_lib tbb IMPORTED_LOCATION_RELEASE) + endif() + if(_tbb_lib AND NOT OPENCV_SKIP_WORKAROUND_MKL_LINK_DIRECTORIES_TBB) + # MSBuild drops content of 'LIB' environment variable, + # so pass TBB library directory through `link_directories()` + get_filename_component(_tbb_lib_dir "${_tbb_lib}" DIRECTORY) + message(STATUS "MKL: adding '${_tbb_lib_dir}' to link directories (workaround DEFAULTLIB issue)") + link_directories("${_tbb_lib_dir}") + elseif(NOT OPENCV_SKIP_WORKAROUND_MKL_DEFAULTLIB) + # We may have tbb.lib for 'tbb' target, but not 'tbb12.lib' + ocv_update(OPENCV_MKL_IGNORE_DEFAULTLIB_TBB "tbb12.lib") + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /NODEFAULTLIB:${OPENCV_MKL_IGNORE_DEFAULTLIB_TBB}") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /NODEFAULTLIB:${OPENCV_MKL_IGNORE_DEFAULTLIB_TBB}") + endif() endif() - endif() - # TODO add cache for try_compile() inputs/results + # TODO add cache for try_compile() inputs/results - get_property(__link_directories DIRECTORY PROPERTY LINK_DIRECTORIES) - if(LAPACK_LINK_LIBRARIES) - list(APPEND __link_directories ${LAPACK_LINK_LIBRARIES}) - endif() + get_property(__link_directories DIRECTORY PROPERTY LINK_DIRECTORIES) + if(LAPACK_LINK_LIBRARIES) + list(APPEND __link_directories ${LAPACK_LINK_LIBRARIES}) + endif() set(LAPACK_TRY_COMPILE_DEF "") if(LAPACK_IMPL STREQUAL "LAPACK/Apple" AND OPENCV_OSX_USE_ACCELERATE_NEW_LAPACK) @@ -130,83 +150,67 @@ macro(ocv_lapack_run_check) add_compile_definitions(ACCELERATE_LAPACK_ILP64) endif() - try_compile(__VALID_LAPACK - "${OpenCV_BINARY_DIR}" - "${OpenCV_SOURCE_DIR}/cmake/checks/lapack_check.cpp" - CMAKE_FLAGS "-DINCLUDE_DIRECTORIES:STRING=${LAPACK_INCLUDE_DIR}\;${CMAKE_BINARY_DIR}" - "-DLINK_DIRECTORIES:STRING=${__link_directories}" - COMPILE_DEFINITIONS ${LAPACK_TRY_COMPILE_DEF} - LINK_LIBRARIES ${LAPACK_LIBRARIES} - OUTPUT_VARIABLE TRY_OUT - ) - if(NOT __VALID_LAPACK) - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log - "\nLAPACK(${LAPACK_IMPL}) check FAILED:\n" - " LAPACK_INCLUDE_DIR: '${LAPACK_INCLUDE_DIR}'\n" - " LAPACK_LIBRARIES: '${LAPACK_LIBRARIES}'\n" - " LAPACK_LINK_LIBRARIES: '${__link_directories}'\n" - " Output:\n${TRY_OUT}\n\n") - message(STATUS "LAPACK(${LAPACK_IMPL}): Can't build LAPACK check code. This LAPACK version is not supported.") - unset(LAPACK_LIBRARIES) - else() - message(STATUS "${LAPACK_IMPL}: Support is enabled.") - ocv_include_directories(${LAPACK_INCLUDE_DIR}) - set(HAVE_LAPACK 1) - endif() -endmacro() - -macro(ocv_lapack_check) - string(REGEX REPLACE "[^a-zA-Z0-9_]" "_" _lapack_impl "${LAPACK_IMPL}") - message(STATUS "${LAPACK_IMPL}: LAPACK_LIBRARIES=${LAPACK_LIBRARIES}") - _find_header_file_in_dirs(OPENCV_CBLAS_H_PATH_${_lapack_impl} "${LAPACK_CBLAS_H}" "${LAPACK_INCLUDE_DIR}") - _find_header_file_in_dirs(OPENCV_LAPACKE_H_PATH_${_lapack_impl} "${LAPACK_LAPACKE_H}" "${LAPACK_INCLUDE_DIR}") - message(STATUS "${LAPACK_IMPL}: Looking for CBLAS/LAPACK headers in '${LAPACK_INCLUDE_DIR}': '${OPENCV_CBLAS_H_PATH_${_lapack_impl}}', '${OPENCV_LAPACKE_H_PATH_${_lapack_impl}}'") - if(OPENCV_CBLAS_H_PATH_${_lapack_impl} AND OPENCV_LAPACKE_H_PATH_${_lapack_impl}) - ocv_lapack_make_hdr(${OPENCV_CBLAS_H_PATH_${_lapack_impl}} ${OPENCV_LAPACKE_H_PATH_${_lapack_impl}}) - ocv_lapack_run_check() - else() - unset(LAPACK_LIBRARIES) + if(NOT LAPACK_SKIP_BUILD) + try_compile(__VALID_LAPACK + "${OpenCV_BINARY_DIR}" + "${OpenCV_SOURCE_DIR}/cmake/checks/lapack_check.cpp" + CMAKE_FLAGS "-DINCLUDE_DIRECTORIES:STRING=${LAPACK_INCLUDE_DIR}\;${CMAKE_BINARY_DIR}" + "-DLINK_DIRECTORIES:STRING=${__link_directories}" + COMPILE_DEFINITIONS ${LAPACK_TRY_COMPILE_DEF} + LINK_LIBRARIES ${LAPACK_LIBRARIES} + OUTPUT_VARIABLE TRY_OUT + ) + if(NOT __VALID_LAPACK) + file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log + "\nLAPACK(${LAPACK_IMPL}) check FAILED:\n" + " LAPACK_INCLUDE_DIR: '${LAPACK_INCLUDE_DIR}'\n" + " LAPACK_LIBRARIES: '${LAPACK_LIBRARIES}'\n" + " LAPACK_LINK_LIBRARIES: '${__link_directories}'\n" + " Output:\n${TRY_OUT}\n\n") + message(STATUS "LAPACK(${LAPACK_IMPL}): Can't build LAPACK check code. This LAPACK version is not supported.") + unset(LAPACK_LIBRARIES) + else() + message(STATUS "LAPACK(${LAPACK_IMPL}): Support is enabled.") + ocv_include_directories(${LAPACK_INCLUDE_DIR}) + set(HAVE_LAPACK 1) + endif() + else() + message(STATUS "Skipped LAPACK build check") + endif() endif() endmacro() if(WITH_LAPACK) - unset(LAPACK_LIBRARIES) - unset(LAPACK_LIBRARIES CACHE) - ocv_update(LAPACK_IMPL "Unknown") if(NOT BUILD_CLAPACK AND NOT OPENCV_LAPACK_FIND_PACKAGE_ONLY) if(NOT LAPACK_LIBRARIES AND NOT OPENCV_LAPACK_DISABLE_MKL) include(cmake/OpenCVFindMKL.cmake) if(HAVE_MKL) - set(LAPACK_INCLUDE_DIR ${MKL_INCLUDE_DIRS}) - set(LAPACK_LIBRARIES ${MKL_LIBRARIES}) - set(LAPACK_CBLAS_H "mkl_cblas.h") - set(LAPACK_LAPACKE_H "mkl_lapack.h") - set(LAPACK_IMPL "MKL") - set(LAPACK_VERSION "${MKL_VERSION_STR}") - ocv_lapack_check() + ocv_lapack_check(IMPL "MKL" + CBLAS_H "mkl_cblas.h" + LAPACKE_H "mkl_lapack.h" + INCLUDE_DIR "${MKL_INCLUDE_DIRS}" + LIBRARIES "${MKL_LIBRARIES}") endif() endif() if(NOT LAPACK_LIBRARIES) include(cmake/OpenCVFindOpenBLAS.cmake) if(OpenBLAS_FOUND) - set(LAPACK_INCLUDE_DIR ${OpenBLAS_INCLUDE_DIR}) - set(LAPACK_LIBRARIES ${OpenBLAS_LIB}) - set(LAPACK_CBLAS_H "cblas.h") - set(LAPACK_LAPACKE_H "lapacke.h") - set(LAPACK_IMPL "OpenBLAS") - ocv_lapack_check() + ocv_lapack_check(IMPL "OpenBLAS" + CBLAS_H "cblas.h" + LAPACKE_H "lapacke.h" + INCLUDE_DIR "${OpenBLAS_INCLUDE_DIRS}" + LIBRARIES "${OpenBLAS_LIBRARIES}") endif() endif() if(NOT LAPACK_LIBRARIES AND UNIX) include(cmake/OpenCVFindAtlas.cmake) if(ATLAS_FOUND) - set(LAPACK_INCLUDE_DIR ${Atlas_INCLUDE_DIR}) - set(LAPACK_LIBRARIES ${Atlas_LIBRARIES}) - set(LAPACK_CBLAS_H "cblas.h") - set(LAPACK_LAPACKE_H "lapacke.h") - set(LAPACK_IMPL "Atlas") - ocv_lapack_check() + ocv_lapack_check(IMPL "Atlas" + CBLAS_H "cblas.h" + LAPACKE_H "lapacke.h" + INCLUDE_DIR "${Atlas_INCLUDE_DIR}" + LIBRARIES "${Atlas_LIBRARIES}") endif() endif() endif() @@ -224,57 +228,59 @@ if(WITH_LAPACK) find_path(MKL_LAPACKE_INCLUDE_DIR "mkl_lapack.h") endif() if(MKL_LAPACKE_INCLUDE_DIR AND NOT OPENCV_LAPACK_DISABLE_MKL) - set(LAPACK_INCLUDE_DIR ${MKL_LAPACKE_INCLUDE_DIR}) - set(LAPACK_CBLAS_H "mkl_cblas.h") - set(LAPACK_LAPACKE_H "mkl_lapack.h") - set(LAPACK_IMPL "LAPACK/MKL") - ocv_lapack_check() + ocv_lapack_check(IMPL "LAPACK/MKL" + CBLAS_H "mkl_cblas.h" + LAPACKE_H "mkl_lapack.h" + INCLUDE_DIR "${MKL_LAPACKE_INCLUDE_DIR}" + LIBRARIES "${LAPACK_LIBRARIES}") endif() if(NOT HAVE_LAPACK) - if(LAPACKE_INCLUDE_DIR) - set(LAPACK_INCLUDE_DIR ${LAPACKE_INCLUDE_DIR}) - set(LAPACK_CBLAS_H "cblas.h") - set(LAPACK_LAPACKE_H "lapacke.h") - set(LAPACK_IMPL "LAPACK/Generic") - ocv_lapack_check() + if(NOT DEFINED CBLAS_INCLUDE_DIR) + find_path(CBLAS_INCLUDE_DIR "cblas.h") + endif() + if(CBLAS_INCLUDE_DIR AND LAPACKE_INCLUDE_DIR) + ocv_lapack_check(IMPL "LAPACK/Generic" + CBLAS_H "cblas.h" + LAPACKE_H "lapacke.h" + INCLUDE_DIR "${CBLAS_INCLUDE_DIR}" "${LAPACKE_INCLUDE_DIR}" + LIBRARIES "${LAPACK_LIBRARIES}") + elseif(APPLE) + ocv_lapack_check(IMPL "LAPACK/Apple" + CBLAS_H "Accelerate/Accelerate.h" + LAPACKE_H "Accelerate/Accelerate.h") endif() endif() endif() - endif() - - if(NOT HAVE_LAPACK) - if(LAPACK_LIBRARIES AND LAPACK_CBLAS_H AND LAPACK_LAPACKE_H) - ocv_lapack_check() - else() + if(NOT HAVE_LAPACK) unset(LAPACK_LIBRARIES) unset(LAPACK_LIBRARIES CACHE) endif() endif() - if(NOT BUILD_CLAPACK AND APPLE AND NOT LAPACK_LIBRARIES) - set(LAPACK_INCLUDE_DIR "") - set(LAPACK_LIBRARIES "-framework Accelerate") - set(LAPACK_CBLAS_H "Accelerate/Accelerate.h") - set(LAPACK_LAPACKE_H "Accelerate/Accelerate.h") - set(LAPACK_IMPL "LAPACK/Apple") - ocv_lapack_check() + if(NOT BUILD_CLAPACK AND NOT LAPACK_LIBRARIES AND APPLE AND NOT OPENCV_LAPACK_FIND_PACKAGE_ONLY) + ocv_lapack_check(IMPL "Apple" + CBLAS_H "Accelerate/Accelerate.h" + LAPACKE_H "Accelerate/Accelerate.h" + LIBRARIES "-framework Accelerate") endif() - if(BUILD_CLAPACK) - ocv_assert(NOT HAVE_LAPACK) + if(NOT BUILD_CLAPACK AND NOT HAVE_LAPACK AND LAPACK_LIBRARIES AND LAPACK_CBLAS_H AND LAPACK_LAPACKE_H) + ocv_lapack_check(IMPL "Unknown" + CBLAS_H ${LAPACK_CBLAS_H} + LAPACKE_H ${LAPACK_LAPACKE_H} + LIBRARIES "${LAPACK_LIBRARIES}") endif() - if(NOT HAVE_LAPACK) # OR BUILD_CLAPACK=ON + + if(BUILD_CLAPACK OR NOT HAVE_LAPACK) + message(STATUS "Lapack not found - fallback to built-in") add_subdirectory(3rdparty/clapack) - - set(LAPACK_CBLAS_H "cblas.h") - set(LAPACK_LAPACKE_H "lapack.h") - set(LAPACK_IMPL "LAPACK/clapack") - set(LAPACK_INCLUDE_DIR "${CLAPACK_INCLUDE_DIR}") - set(LAPACK_LIBRARIES ${CLAPACK_LIBRARIES}) - set(LAPACK_VERSION "${CLAPACK_VERSION}") - ocv_lapack_make_hdr("${LAPACK_INCLUDE_DIR}/${LAPACK_CBLAS_H}" "${LAPACK_INCLUDE_DIR}/${LAPACK_LAPACKE_H}") - # unable to properly check against source code without binaries: ocv_lapack_check() - ocv_include_directories(${LAPACK_INCLUDE_DIR}) + ocv_lapack_check(IMPL "Built-In" + CBLAS_H "cblas.h" + LAPACKE_H "lapack.h" + INCLUDE_DIR "${CLAPACK_INCLUDE_DIR}" + LIBRARIES "${CLAPACK_LIBRARIES}" + SKIP_BUILD + SKIP_FIND) set(HAVE_LAPACK 1) endif()