diff --git a/ports/lapack-reference/FindLAPACK.cmake b/ports/lapack-reference/FindLAPACK.cmake index f4d25477d8dad4..855ac56f0b6334 100644 --- a/ports/lapack-reference/FindLAPACK.cmake +++ b/ports/lapack-reference/FindLAPACK.cmake @@ -8,11 +8,11 @@ FindLAPACK Find Linear Algebra PACKage (LAPACK) library This module finds an installed Fortran library that implements the -LAPACK linear-algebra interface (see http://www.netlib.org/lapack/). +`LAPACK linear-algebra interface`_. -The approach follows that taken for the ``autoconf`` macro file, -``acx_lapack.m4`` (distributed at -http://ac-archive.sourceforge.net/ac-archive/acx_lapack.html). +At least one of the ``C``, ``CXX``, or ``Fortran`` languages must be enabled. + +.. _`LAPACK linear-algebra interface`: http://www.netlib.org/lapack/ Input Variables ^^^^^^^^^^^^^^^ @@ -23,36 +23,26 @@ The following variables may be set to influence this module's behavior: if ``ON`` use static linkage ``BLA_VENDOR`` - If set, checks only the specified vendor, if not set checks all the - possibilities. List of vendors valid in this module: - - * ``OpenBLAS`` - * ``FLAME`` - * ``Intel10_32`` (intel mkl v10 32 bit) - * ``Intel10_64lp`` (intel mkl v10+ 64 bit, threaded code, lp64 model) - * ``Intel10_64lp_seq`` (intel mkl v10+ 64 bit, sequential code, lp64 model) - * ``Intel10_64ilp`` (intel mkl v10+ 64 bit, threaded code, ilp64 model) - * ``Intel10_64ilp_seq`` (intel mkl v10+ 64 bit, sequential code, ilp64 model) - * ``Intel10_64_dyn`` (intel mkl v10+ 64 bit, single dynamic library) - * ``Intel`` (obsolete versions of mkl 32 and 64 bit) - * ``ACML`` - * ``Apple`` - * ``NAS`` - * ``Arm`` - * ``Arm_mp`` - * ``Arm_ilp64`` - * ``Arm_ilp64_mp`` - * ``Generic`` + Set to one of the :ref:`BLAS/LAPACK Vendors` to search for BLAS only + from the specified vendor. If not set, all vendors are considered. ``BLA_F95`` if ``ON`` tries to find the BLAS95/LAPACK95 interfaces +``BLA_PREFER_PKGCONFIG`` + .. versionadded:: 3.20 + + if set ``pkg-config`` will be used to search for a LAPACK library first + and if one is found that is preferred + Imported targets ^^^^^^^^^^^^^^^^ -This module defines the following :prop_tgt:`IMPORTED` target: +This module defines the following :prop_tgt:`IMPORTED` targets: ``LAPACK::LAPACK`` + .. versionadded:: 3.18 + The libraries to use for LAPACK, if found. Result Variables @@ -73,69 +63,95 @@ This module defines the following variables: ``LAPACK95_FOUND`` library implementing the LAPACK95 interface is found -.. note:: +Intel MKL +^^^^^^^^^ - C, CXX or Fortran must be enabled to detect a BLAS/LAPACK library. - C or CXX must be enabled to use Intel Math Kernel Library (MKL). +To use the Intel MKL implementation of LAPACK, a project must enable at least +one of the ``C`` or ``CXX`` languages. Set ``BLA_VENDOR`` to an Intel MKL +variant either on the command-line as ``-DBLA_VENDOR=Intel10_64lp`` or in +project code: - For example, to use Intel MKL libraries and/or Intel compiler: +.. code-block:: cmake - .. code-block:: cmake + set(BLA_VENDOR Intel10_64lp) + find_package(LAPACK) + +In order to build a project using Intel MKL, and end user must first +establish an Intel MKL environment. See the :module:`FindBLAS` module +section on :ref:`Intel MKL` for details. - set(BLA_VENDOR Intel10_64lp) - find_package(LAPACK) #]=======================================================================] -enable_language(C) -# Check the language being used -if(NOT (CMAKE_C_COMPILER_LOADED OR CMAKE_CXX_COMPILER_LOADED OR CMAKE_Fortran_COMPILER_LOADED)) - if(LAPACK_FIND_REQUIRED) - message(FATAL_ERROR "FindLAPACK requires Fortran, C, or C++ to be enabled.") - else() - message(STATUS "Looking for LAPACK... - NOT found (Unsupported languages)") - return() - endif() -endif() +# The approach follows that of the ``autoconf`` macro file, ``acx_lapack.m4`` +# (distributed at http://ac-archive.sourceforge.net/ac-archive/acx_lapack.html). if(CMAKE_Fortran_COMPILER_LOADED) - include(${CMAKE_ROOT}/Modules/CheckFortranFunctionExists.cmake) + include("${CMAKE_ROOT}/Modules/CheckFortranFunctionExists.cmake") else() - include(${CMAKE_ROOT}/Modules/CheckFunctionExists.cmake) -endif() -include(${CMAKE_ROOT}/Modules/CMakePushCheckState.cmake) - -cmake_push_check_state() -set(CMAKE_REQUIRED_QUIET ${LAPACK_FIND_QUIETLY}) - -set(LAPACK_FOUND FALSE) -set(LAPACK95_FOUND FALSE) - -# store original values for CMAKE_FIND_LIBRARY_SUFFIXES -set(_lapack_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES}) -if (CMAKE_SYSTEM_NAME STREQUAL "Linux") - list(APPEND CMAKE_FIND_LIBRARY_SUFFIXES .so.3gfs .so.3 .so.4 .so.5) + include("${CMAKE_ROOT}/Modules/CheckFunctionExists.cmake") endif() +include("${CMAKE_ROOT}/Modules/FindPackageHandleStandardArgs.cmake") + +function(_add_lapack_target) + if(LAPACK_FOUND AND NOT TARGET LAPACK::LAPACK) + add_library(LAPACK::LAPACK INTERFACE IMPORTED) + + # Filter out redundant BLAS info and replace with the BLAS target + set(_lapack_libs "${LAPACK_LIBRARIES}") + set(_lapack_flags "${LAPACK_LINKER_FLAGS}") + if(TARGET BLAS::BLAS) + if(_lapack_libs AND BLAS_LIBRARIES) + foreach(_blas_lib IN LISTS BLAS_LIBRARIES) + list(REMOVE_ITEM _lapack_libs "${_blas_lib}") + endforeach() + endif() + if(_lapack_flags AND BLAS_LINKER_FLAGS) + foreach(_blas_flag IN LISTS BLAS_LINKER_FLAGS) + list(REMOVE_ITEM _lapack_flags "${_blas_flag}") + endforeach() + endif() + list(APPEND _lapack_libs BLAS::BLAS) + endif() + if(_lapack_libs) + set_target_properties(LAPACK::LAPACK PROPERTIES + INTERFACE_LINK_LIBRARIES "${_lapack_libs}" + ) + endif() + if(_lapack_flags) + set_target_properties(LAPACK::LAPACK PROPERTIES + INTERFACE_LINK_OPTIONS "${_lapack_flags}" + ) + endif() + endif() +endfunction() # TODO: move this stuff to a separate module -macro(CHECK_LAPACK_LIBRARIES LIBRARIES _prefix _name _flags _list _threadlibs _addlibdir _subdirs _blas) - # This macro checks for the existence of the combination of fortran libraries - # given by _list. If the combination is found, this macro checks (using the - # Check_Fortran_Function_Exists macro) whether can link against that library - # combination using the name of a routine given by _name using the linker - # flags given by _flags. If the combination of libraries is found and passes - # the link test, LIBRARIES is set to the list of complete library paths that - # have been found. Otherwise, LIBRARIES is set to FALSE. - - # N.B. _prefix is the prefix applied to the names of all cached variables that - # are generated internally and marked advanced by this macro. - # _addlibdir is a list of additional search paths. _subdirs is a list of path - # suffixes to be used by find_library(). +function(CHECK_LAPACK_LIBRARIES LIBRARIES _prefix _name _flags _list _deps _addlibdir _subdirs _blas) + # This function checks for the existence of the combination of libraries + # given by _list. If the combination is found, this checks whether can link + # against that library combination using the name of a routine given by _name + # using the linker flags given by _flags. If the combination of libraries is + # found and passes the link test, ${LIBRARIES} is set to the list of complete + # library paths that have been found. Otherwise, ${LIBRARIES} is set to FALSE. set(_libraries_work TRUE) - set(${LIBRARIES}) + set(_libraries) set(_combined_name) + if(BLA_STATIC) + if(WIN32) + set(CMAKE_FIND_LIBRARY_SUFFIXES .lib ${CMAKE_FIND_LIBRARY_SUFFIXES}) + else() + set(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES}) + endif() + else() + if(CMAKE_SYSTEM_NAME STREQUAL "Linux") + # for ubuntu's libblas3gf and liblapack3gf packages + set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES} .so.3gf) + endif() + endif() + set(_extaddlibdir "${_addlibdir}") if(WIN32) list(APPEND _extaddlibdir ENV LIB) @@ -147,29 +163,37 @@ macro(CHECK_LAPACK_LIBRARIES LIBRARIES _prefix _name _flags _list _threadlibs _a list(APPEND _extaddlibdir "${CMAKE_C_IMPLICIT_LINK_DIRECTORIES}") foreach(_library ${_list}) - if(_library MATCHES "^-Wl,--(start|end)-group$") - # Respect linker flags like --start/end-group (required by MKL) - set(${LIBRARIES} ${${LIBRARIES}} "${_library}") + if(_library MATCHES "^-") + # Respect linker flags as-is (required by MKL) + list(APPEND _libraries "${_library}") else() - set(_combined_name ${_combined_name}_${_library}) + string(REGEX REPLACE "[^A-Za-z0-9]" "_" _lib_var "${_library}") + set(_combined_name ${_combined_name}_${_lib_var}) + if(NOT "${_deps}" STREQUAL "") + set(_combined_name ${_combined_name}_deps) + endif() if(_libraries_work) - find_library(${_prefix}_${_library}_LIBRARY + find_library(${_prefix}_${_lib_var}_LIBRARY NAMES ${_library} + NAMES_PER_DIR PATHS ${_extaddlibdir} PATH_SUFFIXES ${_subdirs} ) - #message("DEBUG: find_library(${_library}) got ${${_prefix}_${_library}_LIBRARY}") - mark_as_advanced(${_prefix}_${_library}_LIBRARY) - set(${LIBRARIES} ${${LIBRARIES}} ${${_prefix}_${_library}_LIBRARY}) - set(_libraries_work ${${_prefix}_${_library}_LIBRARY}) + mark_as_advanced(${_prefix}_${_lib_var}_LIBRARY) + list(APPEND _libraries ${${_prefix}_${_lib_var}_LIBRARY}) + set(_libraries_work ${${_prefix}_${_lib_var}_LIBRARY}) endif() endif() endforeach() + foreach(_flag ${_flags}) + string(REGEX REPLACE "[^A-Za-z0-9]" "_" _flag_var "${_flag}") + set(_combined_name ${_combined_name}_${_flag_var}) + endforeach() if(_libraries_work) # Test this combination of libraries. - set(CMAKE_REQUIRED_LIBRARIES ${_flags} ${${LIBRARIES}} ${_blas} ${_threadlibs}) - #message("DEBUG: CMAKE_REQUIRED_LIBRARIES = ${CMAKE_REQUIRED_LIBRARIES}") + set(CMAKE_REQUIRED_LIBRARIES ${_flags} ${_libraries} ${_blas} ${_deps}) + set(CMAKE_REQUIRED_QUIET ${LAPACK_FIND_QUIETLY}) if(CMAKE_Fortran_COMPILER_LOADED) check_fortran_function_exists("${_name}" ${_prefix}${_combined_name}_WORKS) else() @@ -181,354 +205,118 @@ macro(CHECK_LAPACK_LIBRARIES LIBRARIES _prefix _name _flags _list _threadlibs _a if(_libraries_work) if("${_list}${_blas}" STREQUAL "") - set(${LIBRARIES} "${LIBRARIES}-PLACEHOLDER-FOR-EMPTY-LIBRARIES") + set(_libraries "${LIBRARIES}-PLACEHOLDER-FOR-EMPTY-LIBRARIES") else() - set(${LIBRARIES} ${${LIBRARIES}} ${_blas} ${_threadlibs}) + list(APPEND _libraries ${_blas} ${_deps}) endif() else() - set(${LIBRARIES} FALSE) + set(_libraries FALSE) endif() - #message("DEBUG: ${LIBRARIES} = ${${LIBRARIES}}") -endmacro() - -set(LAPACK_LINKER_FLAGS) -set(LAPACK_LIBRARIES) -set(LAPACK95_LIBRARIES) - -include(CMakeFindDependencyMacro) -find_dependency(BLAS) + set(${LIBRARIES} "${_libraries}" PARENT_SCOPE) +endfunction() -if(BLAS_FOUND) - set(LAPACK_LINKER_FLAGS ${BLAS_LINKER_FLAGS}) - if(NOT $ENV{BLA_VENDOR} STREQUAL "") - set(BLA_VENDOR $ENV{BLA_VENDOR}) - else() - if(NOT BLA_VENDOR) - set(BLA_VENDOR "All") - endif() +macro(_lapack_find_dependency dep) + set(_lapack_quiet_arg) + if(LAPACK_FIND_QUIETLY) + set(_lapack_quiet_arg QUIET) endif() - - # LAPACK in the Intel MKL 10+ library? - if(BLA_VENDOR MATCHES "Intel" OR BLA_VENDOR STREQUAL "All") - if(NOT LAPACK_LIBRARIES) - if(CMAKE_C_COMPILER_LOADED OR CMAKE_CXX_COMPILER_LOADED) - # System-specific settings - if(NOT WIN32) - set(LAPACK_mkl_LM "-lm") - set(LAPACK_mkl_LDL "-ldl") - endif() - - if(LAPACK_FIND_QUIETLY OR NOT LAPACK_FIND_REQUIRED) - find_package(Threads) - else() - find_package(Threads REQUIRED) - endif() - - if(BLA_VENDOR MATCHES "_64ilp") - set(LAPACK_mkl_ILP_MODE "ilp64") - else() - set(LAPACK_mkl_ILP_MODE "lp64") - endif() - - set(LAPACK_SEARCH_LIBS "") - - if(BLA_F95) - set(LAPACK_mkl_SEARCH_SYMBOL "cheev_f95") - set(_LIBRARIES LAPACK95_LIBRARIES) - set(_BLAS_LIBRARIES ${BLAS95_LIBRARIES}) - - # old - list(APPEND LAPACK_SEARCH_LIBS - "mkl_lapack95") - # new >= 10.3 - list(APPEND LAPACK_SEARCH_LIBS - "mkl_intel_c") - list(APPEND LAPACK_SEARCH_LIBS - "mkl_lapack95_${LAPACK_mkl_ILP_MODE}") - else() - set(LAPACK_mkl_SEARCH_SYMBOL "cheev") - set(_LIBRARIES LAPACK_LIBRARIES) - set(_BLAS_LIBRARIES ${BLAS_LIBRARIES}) - - # old and new >= 10.3 - list(APPEND LAPACK_SEARCH_LIBS - "mkl_lapack") - endif() - - # MKL uses a multitude of partially platform-specific subdirectories: - if(BLA_VENDOR STREQUAL "Intel10_32") - set(LAPACK_mkl_ARCH_NAME "ia32") - else() - set(LAPACK_mkl_ARCH_NAME "intel64") - endif() - if(WIN32) - set(LAPACK_mkl_OS_NAME "win") - elseif(APPLE) - set(LAPACK_mkl_OS_NAME "mac") - else() - set(LAPACK_mkl_OS_NAME "lin") - endif() - if(DEFINED ENV{MKLROOT}) - file(TO_CMAKE_PATH "$ENV{MKLROOT}" LAPACK_mkl_MKLROOT) - # If MKLROOT points to the subdirectory 'mkl', use the parent directory instead - # so we can better detect other relevant libraries in 'compiler' or 'tbb': - get_filename_component(LAPACK_mkl_MKLROOT_LAST_DIR "${LAPACK_mkl_MKLROOT}" NAME) - if(LAPACK_mkl_MKLROOT_LAST_DIR STREQUAL "mkl") - get_filename_component(LAPACK_mkl_MKLROOT "${LAPACK_mkl_MKLROOT}" DIRECTORY) - endif() - endif() - set(LAPACK_mkl_LIB_PATH_SUFFIXES - "compiler/lib" "compiler/lib/${LAPACK_mkl_ARCH_NAME}_${LAPACK_mkl_OS_NAME}" - "mkl/lib" "mkl/lib/${LAPACK_mkl_ARCH_NAME}_${LAPACK_mkl_OS_NAME}" - "lib/${LAPACK_mkl_ARCH_NAME}_${LAPACK_mkl_OS_NAME}") - - # First try empty lapack libs - if(NOT ${_LIBRARIES}) - check_lapack_libraries( - ${_LIBRARIES} - LAPACK - ${LAPACK_mkl_SEARCH_SYMBOL} - "" - "" - "${CMAKE_THREAD_LIBS_INIT};${LAPACK_mkl_LM};${LAPACK_mkl_LDL}" - "${LAPACK_mkl_MKLROOT}" - "${LAPACK_mkl_LIB_PATH_SUFFIXES}" - "${_BLAS_LIBRARIES}" - ) - endif() - - # Then try the search libs - foreach(IT ${LAPACK_SEARCH_LIBS}) - string(REPLACE " " ";" SEARCH_LIBS ${IT}) - if(NOT ${_LIBRARIES}) - check_lapack_libraries( - ${_LIBRARIES} - LAPACK - ${LAPACK_mkl_SEARCH_SYMBOL} - "" - "${SEARCH_LIBS}" - "${CMAKE_THREAD_LIBS_INIT};${LAPACK_mkl_LM};${LAPACK_mkl_LDL}" - "${LAPACK_mkl_MKLROOT}" - "${LAPACK_mkl_LIB_PATH_SUFFIXES}" - "${_BLAS_LIBRARIES}" - ) - endif() - endforeach() - - unset(LAPACK_mkl_ILP_MODE) - unset(LAPACK_mkl_SEARCH_SYMBOL) - unset(LAPACK_mkl_LM) - unset(LAPACK_mkl_LDL) - unset(LAPACK_mkl_MKLROOT) - unset(LAPACK_mkl_ARCH_NAME) - unset(LAPACK_mkl_OS_NAME) - unset(LAPACK_mkl_LIB_PATH_SUFFIXES) - endif() - endif() - endif() - - # gotoblas? (http://www.tacc.utexas.edu/tacc-projects/gotoblas2) - if(BLA_VENDOR STREQUAL "Goto" OR BLA_VENDOR STREQUAL "All") - if(NOT LAPACK_LIBRARIES) - check_lapack_libraries( - LAPACK_LIBRARIES - LAPACK - cheev - "" - "goto2" - "" - "" - "" - "${BLAS_LIBRARIES}" - ) - endif() + set(_lapack_required_arg) + if(LAPACK_FIND_REQUIRED) + set(_lapack_required_arg REQUIRED) endif() - - # OpenBLAS? (http://www.openblas.net) - if(BLA_VENDOR STREQUAL "OpenBLAS" OR BLA_VENDOR STREQUAL "All") - if(NOT LAPACK_LIBRARIES) - check_lapack_libraries( - LAPACK_LIBRARIES - LAPACK - cheev - "" - "openblas" - "" - "" - "" - "${BLAS_LIBRARIES}" - ) - endif() + find_package(${dep} ${ARGN} + ${_lapack_quiet_arg} + ${_lapack_required_arg} + ) + if (NOT ${dep}_FOUND) + set(LAPACK_NOT_FOUND_MESSAGE "LAPACK could not be found because dependency ${dep} could not be found.") endif() - # ArmPL? (https://developer.arm.com/tools-and-software/server-and-hpc/compile/arm-compiler-for-linux/arm-performance-libraries) - if(BLA_VENDOR MATCHES "Arm" OR BLA_VENDOR STREQUAL "All") - - # Check for 64bit Integer support - if(BLA_VENDOR MATCHES "_ilp64") - set(LAPACK_armpl_LIB "armpl_ilp64") - else() - set(LAPACK_armpl_LIB "armpl_lp64") - endif() - - # Check for OpenMP support, VIA BLA_VENDOR of Arm_mp or Arm_ipl64_mp - if(BLA_VENDOR MATCHES "_mp") - set(LAPACK_armpl_LIB "${LAPACK_armpl_LIB}_mp") - endif() + set(_lapack_required_arg) + set(_lapack_quiet_arg) +endmacro() - if(NOT LAPACK_LIBRARIES) - check_lapack_libraries( - LAPACK_LIBRARIES - LAPACK - cheev - "" - "${LAPACK_armpl_LIB}" - "" - "" - "" - "${BLAS_LIBRARIES}" - ) - endif() - endif() +set(LAPACK_LINKER_FLAGS) +set(LAPACK_LIBRARIES) +set(LAPACK95_LIBRARIES) +set(_lapack_fphsa_req_var LAPACK_LIBRARIES) - # FLAME's blis library? (https://github.com/flame/blis) - if(BLA_VENDOR STREQUAL "FLAME" OR BLA_VENDOR STREQUAL "All") - if(NOT LAPACK_LIBRARIES) - check_lapack_libraries( - LAPACK_LIBRARIES - LAPACK - cheev - "" - "flame" - "" - "" - "" - "${BLAS_LIBRARIES}" - ) - endif() - endif() +# Check the language being used +if(NOT (CMAKE_C_COMPILER_LOADED OR CMAKE_CXX_COMPILER_LOADED OR CMAKE_Fortran_COMPILER_LOADED)) + set(LAPACK_NOT_FOUND_MESSAGE + "FindLAPACK requires Fortran, C, or C++ to be enabled.") +endif() - # BLAS in acml library? - if(BLA_VENDOR MATCHES "ACML" OR BLA_VENDOR STREQUAL "All") - if(BLAS_LIBRARIES MATCHES ".+acml.+") - set(LAPACK_LIBRARIES ${BLAS_LIBRARIES}) - endif() - endif() +# Load BLAS +if(NOT LAPACK_NOT_FOUND_MESSAGE) + _lapack_find_dependency(BLAS) +endif() - # Apple LAPACK library? - if(BLA_VENDOR STREQUAL "Apple" OR BLA_VENDOR STREQUAL "All") - if(NOT LAPACK_LIBRARIES) - check_lapack_libraries( - LAPACK_LIBRARIES - LAPACK - cheev - "" - "Accelerate" - "" - "" - "" - "${BLAS_LIBRARIES}" - ) +# Search with pkg-config if specified +if(BLA_PREFER_PKGCONFIG) + find_package(PkgConfig) + pkg_check_modules(PKGC_LAPACK lapack) + if(PKGC_LAPACK_FOUND) + set(LAPACK_FOUND TRUE) + set(LAPACK_LIBRARIES "${PKGC_LAPACK_LINK_LIBRARIES}") + if (BLAS_LIBRARIES) + list(APPEND LAPACK_LIBRARIES "${BLAS_LIBRARIES}") endif() + _add_lapack_target() + return() endif() +endif() - # Apple NAS (vecLib) library? - if(BLA_VENDOR STREQUAL "NAS" OR BLA_VENDOR STREQUAL "All") - if(NOT LAPACK_LIBRARIES) - check_lapack_libraries( - LAPACK_LIBRARIES - LAPACK - cheev - "" - "vecLib" - "" - "" - "" - "${BLAS_LIBRARIES}" - ) - endif() +# Search for different LAPACK distributions if BLAS is found +if(NOT LAPACK_NOT_FOUND_MESSAGE) + set(LAPACK_LINKER_FLAGS ${BLAS_LINKER_FLAGS}) + if(NOT $ENV{BLA_VENDOR} STREQUAL "") + set(BLA_VENDOR $ENV{BLA_VENDOR}) + elseif(NOT BLA_VENDOR) + set(BLA_VENDOR "All") endif() # Generic LAPACK library? - if(BLA_VENDOR STREQUAL "Generic" OR - BLA_VENDOR STREQUAL "ATLAS" OR - BLA_VENDOR STREQUAL "All") - if(NOT LAPACK_LIBRARIES) - check_lapack_libraries( - LAPACK_LIBRARIES - LAPACK - cheev - "" - "lapack" - "" - "" - "" - "${BLAS_LIBRARIES}" - ) - endif() - if(NOT LAPACK_LIBRARIES AND NOT WIN32) - check_lapack_libraries( - LAPACK_LIBRARIES - LAPACK - cheev - "" - "lapack;m;gfortran" - "" - "" - "" - "${BLAS_LIBRARIES}" - ) + if(NOT LAPACK_LIBRARIES + AND (BLA_VENDOR STREQUAL "Generic" + OR BLA_VENDOR STREQUAL "ATLAS" + OR BLA_VENDOR STREQUAL "All")) + if(BLA_STATIC) + # We do not know for sure how the LAPACK reference implementation + # is built on this host. Guess typical dependencies. + set(_lapack_generic_deps "-lgfortran;-lm") + else() + set(_lapack_generic_deps "") endif() + check_lapack_libraries( + LAPACK_LIBRARIES + LAPACK + cheev + "" + "lapack" + "${_lapack_generic_deps}" + "" + "" + "${BLAS_LIBRARIES}" + ) + unset(_lapack_generic_deps) endif() -else() - message(STATUS "LAPACK requires BLAS") endif() if(BLA_F95) - if(LAPACK95_LIBRARIES) - set(LAPACK95_FOUND TRUE) - else() - set(LAPACK95_FOUND FALSE) - endif() - if(NOT LAPACK_FIND_QUIETLY) - if(LAPACK95_FOUND) - message(STATUS "A library with LAPACK95 API found.") - else() - if(LAPACK_FIND_REQUIRED) - message(FATAL_ERROR - "A required library with LAPACK95 API not found. Please specify library location." - ) - else() - message(STATUS - "A library with LAPACK95 API not found. Please specify library location." - ) - endif() - endif() - endif() - set(LAPACK_FOUND "${LAPACK95_FOUND}") set(LAPACK_LIBRARIES "${LAPACK95_LIBRARIES}") -else() - if(LAPACK_LIBRARIES) - set(LAPACK_FOUND TRUE) - else() - set(LAPACK_FOUND FALSE) - endif() +endif() - if(NOT LAPACK_FIND_QUIETLY) - if(LAPACK_FOUND) - message(STATUS "A library with LAPACK API found.") - else() - if(LAPACK_FIND_REQUIRED) - message(FATAL_ERROR - "A required library with LAPACK API not found. Please specify library location." - ) - else() - message(STATUS - "A library with LAPACK API not found. Please specify library location." - ) - endif() - endif() - endif() +if(LAPACK_NOT_FOUND_MESSAGE) + set(LAPACK_NOT_FOUND_MESSAGE + REASON_FAILURE_MESSAGE ${LAPACK_NOT_FOUND_MESSAGE}) +endif() +find_package_handle_standard_args(LAPACK REQUIRED_VARS ${_lapack_fphsa_req_var} + ${LAPACK_NOT_FOUND_MESSAGE}) +unset(LAPACK_NOT_FOUND_MESSAGE) + +if(BLA_F95) + set(LAPACK95_FOUND ${LAPACK_FOUND}) endif() # On compilers that implicitly link LAPACK (such as ftn, cc, and CC on Cray HPC machines) @@ -537,23 +325,4 @@ if(LAPACK_LIBRARIES STREQUAL "LAPACK_LIBRARIES-PLACEHOLDER-FOR-EMPTY-LIBRARIES") set(LAPACK_LIBRARIES "") endif() -if(NOT TARGET LAPACK::LAPACK) - add_library(LAPACK::LAPACK INTERFACE IMPORTED) - set(_lapack_libs "${LAPACK_LIBRARIES}") - if(_lapack_libs AND TARGET BLAS::BLAS) - # remove the ${BLAS_LIBRARIES} from the interface and replace it - # with the BLAS::BLAS target - list(REMOVE_ITEM _lapack_libs "${BLAS_LIBRARIES}") - endif() - - if(_lapack_libs) - set_target_properties(LAPACK::LAPACK PROPERTIES - INTERFACE_LINK_LIBRARIES "${_lapack_libs}" - ) - endif() - unset(_lapack_libs) -endif() - -cmake_pop_check_state() -# restore original values for CMAKE_FIND_LIBRARY_SUFFIXES -set(CMAKE_FIND_LIBRARY_SUFFIXES ${_lapack_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES}) +_add_lapack_target() diff --git a/ports/lapack-reference/intel.patch b/ports/lapack-reference/intel.patch new file mode 100644 index 00000000000000..84c8002f21b2d6 --- /dev/null +++ b/ports/lapack-reference/intel.patch @@ -0,0 +1,28 @@ +diff --git a/INSTALL/dsecnd_EXT_ETIME.f b/INSTALL/dsecnd_EXT_ETIME.f +index 35377643b..f98aad7a9 100644 +--- a/INSTALL/dsecnd_EXT_ETIME.f ++++ b/INSTALL/dsecnd_EXT_ETIME.f +@@ -34,6 +34,9 @@ + * + * ===================================================================== + DOUBLE PRECISION FUNCTION DSECND( ) ++#if defined(__INTEL_COMPILER) ++ USE IFPORT ++#endif + * + * -- LAPACK auxiliary routine -- + * -- LAPACK is a software package provided by Univ. of Tennessee, -- +diff --git a/INSTALL/second_EXT_ETIME.f b/INSTALL/second_EXT_ETIME.f +index 43044cda7..0e2a9a331 100644 +--- a/INSTALL/second_EXT_ETIME.f ++++ b/INSTALL/second_EXT_ETIME.f +@@ -34,6 +34,9 @@ + * + * ===================================================================== + REAL FUNCTION SECOND( ) ++#if defined(__INTEL_COMPILER) ++ USE IFPORT ++#endif + * + * -- LAPACK auxiliary routine -- + * -- LAPACK is a software package provided by Univ. of Tennessee, -- diff --git a/ports/lapack-reference/portfile.cmake b/ports/lapack-reference/portfile.cmake index 8e7490c8f47b31..2dced0a9acf331 100644 --- a/ports/lapack-reference/portfile.cmake +++ b/ports/lapack-reference/portfile.cmake @@ -8,17 +8,24 @@ if(EXISTS "${CURRENT_INSTALLED_DIR}/share/clapack/copyright") message(FATAL_ERROR "Can't build ${PORT} if clapack is installed. Please remove clapack:${TARGET_TRIPLET}, and try to install ${PORT}:${TARGET_TRIPLET} again.") endif() -include(vcpkg_find_fortran) SET(VCPKG_POLICY_EMPTY_INCLUDE_FOLDER enabled) set(lapack_ver 3.10.0) +set(VCPKG_CRT_LINKAGE_BACKUP ${VCPKG_CRT_LINKAGE}) +x_vcpkg_find_fortran(FORTRAN_CMAKE) + +if(VCPKG_USE_INTERNAL_Fortran OR VCPKG_DETECTED_CMAKE_Fortran_COMPILER MATCHES "ifort${VCPKG_HOST_EXECUTABLE_SUFFIX}") + set(PATCHES intel.patch) +endif() + vcpkg_from_github( OUT_SOURCE_PATH SOURCE_PATH REPO "Reference-LAPACK/lapack" REF "v${lapack_ver}" SHA512 56055000c241bab8f318ebd79249ea012c33be0c4c3eca6a78e247f35ad9e8088f46605a0ba52fd5ad3e7898be3b7bc6c50ceb3af327c4986a266b06fe768cbf HEAD_REF master + PATCHES ${PATCHES} ) if(NOT VCPKG_TARGET_IS_WINDOWS) @@ -46,21 +53,6 @@ if("noblas" IN_LIST FEATURES) endif() endif() -set(VCPKG_CRT_LINKAGE_BACKUP ${VCPKG_CRT_LINKAGE}) -vcpkg_find_fortran(FORTRAN_CMAKE) -if(VCPKG_USE_INTERNAL_Fortran) - if(VCPKG_CRT_LINKAGE_BACKUP STREQUAL static) - # If openblas has been built with static crt linkage we cannot use it with gfortran! - set(USE_OPTIMIZED_BLAS OFF) - #Cannot use openblas from vcpkg if we are building with gfortran here. - if("noblas" IN_LIST FEATURES) - message(FATAL_ERROR "Feature 'noblas' cannot be used without supplying an external fortran compiler") - endif() - endif() -else() - set(USE_OPTIMIZED_BLAS ON) -endif() - vcpkg_cmake_configure( SOURCE_PATH "${SOURCE_PATH}" OPTIONS @@ -68,9 +60,7 @@ vcpkg_cmake_configure( "-DCBLAS=${CBLAS}" ${FORTRAN_CMAKE} ) - vcpkg_cmake_install() - vcpkg_cmake_config_fixup(PACKAGE_NAME lapack-${lapack_ver} CONFIG_PATH lib/cmake/lapack-${lapack_ver}) #Should the target path be lapack and not lapack-reference? set(pcfile "${CURRENT_PACKAGES_DIR}/lib/pkgconfig/lapack.pc") @@ -85,7 +75,7 @@ if(EXISTS "${pcfile}") set(_contents "prefix=${CURRENT_INSTALLED_DIR}/debug\n${_contents}") file(WRITE "${pcfile}" "${_contents}") endif() -if(NOT USE_OPTIMIZED_BLAS AND NOT (VCPKG_TARGET_IS_WINDOWS AND VCPKG_LIBRARY_LINKAGE STREQUAL "static")) +if(NOT USE_OPTIMIZED_BLAS) set(pcfile "${CURRENT_PACKAGES_DIR}/lib/pkgconfig/blas.pc") if(EXISTS "${pcfile}") file(READ "${pcfile}" _contents) @@ -119,24 +109,7 @@ vcpkg_fixup_pkgconfig() file(INSTALL "${SOURCE_PATH}/LICENSE" DESTINATION "${CURRENT_PACKAGES_DIR}/share/${PORT}" RENAME copyright) # remove debug includes -file(REMOVE_RECURSE ${CURRENT_PACKAGES_DIR}/debug/include) - -if(VCPKG_TARGET_IS_WINDOWS) - if(EXISTS "${CURRENT_PACKAGES_DIR}/lib/liblapack.lib") - file(RENAME "${CURRENT_PACKAGES_DIR}/lib/liblapack.lib" "${CURRENT_PACKAGES_DIR}/lib/lapack.lib") - endif() - if(EXISTS "${CURRENT_PACKAGES_DIR}/debug/lib/liblapack.lib") - file(RENAME "${CURRENT_PACKAGES_DIR}/debug/lib/liblapack.lib" "${CURRENT_PACKAGES_DIR}/debug/lib/lapack.lib") - endif() - if(NOT USE_OPTIMIZED_BLAS) - if(EXISTS "${CURRENT_PACKAGES_DIR}/lib/libblas.lib") - file(RENAME "${CURRENT_PACKAGES_DIR}/lib/libblas.lib" "${CURRENT_PACKAGES_DIR}/lib/blas.lib") - endif() - if(EXISTS "${CURRENT_PACKAGES_DIR}/debug/lib/libblas.lib") - file(RENAME "${CURRENT_PACKAGES_DIR}/debug/lib/libblas.lib" "${CURRENT_PACKAGES_DIR}/debug/lib/blas.lib") - endif() - endif() -endif() +file(REMOVE_RECURSE "${CURRENT_PACKAGES_DIR}/debug/include") -file(COPY ${CMAKE_CURRENT_LIST_DIR}/vcpkg-cmake-wrapper.cmake DESTINATION ${CURRENT_PACKAGES_DIR}/share/lapack) -file(COPY ${CMAKE_CURRENT_LIST_DIR}/FindLAPACK.cmake DESTINATION ${CURRENT_PACKAGES_DIR}/share/lapack) +configure_file("${CMAKE_CURRENT_LIST_DIR}/vcpkg-cmake-wrapper.cmake" "${CURRENT_PACKAGES_DIR}/share/lapack/vcpkg-cmake-wrapper.cmake" @ONLY) +file(COPY "${CMAKE_CURRENT_LIST_DIR}/FindLAPACK.cmake" DESTINATION "${CURRENT_PACKAGES_DIR}/share/lapack") diff --git a/ports/lapack-reference/vcpkg-cmake-wrapper.cmake b/ports/lapack-reference/vcpkg-cmake-wrapper.cmake index b3a7128fff0150..5aa0e61bdbd8d8 100644 --- a/ports/lapack-reference/vcpkg-cmake-wrapper.cmake +++ b/ports/lapack-reference/vcpkg-cmake-wrapper.cmake @@ -5,7 +5,10 @@ list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}) list(REMOVE_ITEM ARGS "NO_MODULE") list(REMOVE_ITEM ARGS "CONFIG") list(REMOVE_ITEM ARGS "MODULE") - +if(MSVC AND "@VCPKG_LIBRARY_LINKAGE@" STREQUAL "static") + set(CMAKE_REQUIRED_LINK_OPTIONS "-LIBPATH:${_VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/share/ifort/") + add_link_options("-LIBPATH:${_VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/share/ifort/") +endif() _find_package(${ARGS}) set(CMAKE_MODULE_PATH ${LAPACK_PREV_MODULE_PATH}) diff --git a/ports/lapack-reference/vcpkg.json b/ports/lapack-reference/vcpkg.json index e52b1ef84d7d33..2f6f2e9a9128b5 100644 --- a/ports/lapack-reference/vcpkg.json +++ b/ports/lapack-reference/vcpkg.json @@ -1,6 +1,7 @@ { "name": "lapack-reference", "version": "3.10.0", + "port-version": 1, "description": "LAPACK - Linear Algebra PACKage", "homepage": "http://www.netlib.org/lapack/", "license": "BSD-3-Clause-Open-MPI", @@ -14,9 +15,10 @@ "host": true }, { - "name": "vcpkg-gfortran", - "platform": "windows" - } + "name": "vcpkg-fortran", + "host": true + }, + "vcpkg-ifort" ], "default-features": [ "blas-select" @@ -30,8 +32,7 @@ "default-features": false, "features": [ "noblas" - ], - "platform": "!windows | !static" + ] } ] }, diff --git a/ports/vcpkg-cmake/vcpkg.json b/ports/vcpkg-cmake/vcpkg.json index db0c74d719c46a..f64205a462b423 100644 --- a/ports/vcpkg-cmake/vcpkg.json +++ b/ports/vcpkg-cmake/vcpkg.json @@ -1,5 +1,5 @@ { "name": "vcpkg-cmake", - "version-date": "2022-04-21", + "version-date": "2022-04-28", "license": "MIT" } diff --git a/ports/vcpkg-cmake/vcpkg_cmake_build.cmake b/ports/vcpkg-cmake/vcpkg_cmake_build.cmake index 5520f0de318e3c..7212614535a40b 100644 --- a/ports/vcpkg-cmake/vcpkg_cmake_build.cmake +++ b/ports/vcpkg-cmake/vcpkg_cmake_build.cmake @@ -58,11 +58,13 @@ function(vcpkg_cmake_build) set(parallel_args "-j${VCPKG_CONCURRENCY}") set(no_parallel_args "-j1") elseif(Z_VCPKG_CMAKE_GENERATOR MATCHES "^Visual Studio") - set(build_args - "/p:VCPkgLocalAppDataDisabled=true" - "/p:UseIntelMKL=No" - ) - set(parallel_args "/m") + if(NOT VCPKG_USE_INTERNAL_Fortran) + set(build_args + "/p:VCPkgLocalAppDataDisabled=true" + "/p:UseIntelMKL=No" + ) + set(parallel_args "/m") + endif() elseif(Z_VCPKG_CMAKE_GENERATOR STREQUAL "NMake Makefiles") # No options are currently added for nmake builds elseif(Z_VCPKG_CMAKE_GENERATOR STREQUAL "Unix Makefiles") diff --git a/ports/vcpkg-fortran/copyright b/ports/vcpkg-fortran/copyright new file mode 100644 index 00000000000000..2e4eac8264fa4c --- /dev/null +++ b/ports/vcpkg-fortran/copyright @@ -0,0 +1,23 @@ +Copyright (c) Microsoft Corporation + +All rights reserved. + +MIT License + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/ports/vcpkg-fortran/portfile.cmake b/ports/vcpkg-fortran/portfile.cmake new file mode 100644 index 00000000000000..e818fa67da405f --- /dev/null +++ b/ports/vcpkg-fortran/portfile.cmake @@ -0,0 +1,16 @@ +set(FUNCTION_NAME x_vcpkg_find_fortran) + +if(VCPKG_CROSSCOMPILING) + # make FATAL_ERROR in CI when issue #16773 fixed + message(WARNING "${PORT} is a host-only port; please mark it as a host port in your dependencies.") +endif() + +file(COPY + "${CMAKE_CURRENT_LIST_DIR}/${FUNCTION_NAME}.cmake" + "${CMAKE_CURRENT_LIST_DIR}/z_vcpkg_load_environment_from_batch.cmake" + "${CMAKE_CURRENT_LIST_DIR}/copyright" + DESTINATION "${CURRENT_PACKAGES_DIR}/share/${PORT}") + +configure_file("${CMAKE_CURRENT_LIST_DIR}/vcpkg-port-config.cmake.in" "${CURRENT_PACKAGES_DIR}/share/${PORT}/vcpkg-port-config.cmake" @ONLY) + +set(VCPKG_POLICY_EMPTY_PACKAGE enabled) diff --git a/ports/vcpkg-fortran/vcpkg-port-config.cmake.in b/ports/vcpkg-fortran/vcpkg-port-config.cmake.in new file mode 100644 index 00000000000000..e6109903cec223 --- /dev/null +++ b/ports/vcpkg-fortran/vcpkg-port-config.cmake.in @@ -0,0 +1,2 @@ +include("${CMAKE_CURRENT_LIST_DIR}/z_vcpkg_load_environment_from_batch.cmake") +include("${CMAKE_CURRENT_LIST_DIR}/@FUNCTION_NAME@.cmake") diff --git a/ports/vcpkg-fortran/vcpkg.json b/ports/vcpkg-fortran/vcpkg.json new file mode 100644 index 00000000000000..76ead92d5848a2 --- /dev/null +++ b/ports/vcpkg-fortran/vcpkg.json @@ -0,0 +1,7 @@ +{ + "name": "vcpkg-fortran", + "version-date": "2022-02-22", + "description": "Metaport to use a fortran compiler", + "license": "MIT", + "supports": "windows & !arm" +} diff --git a/ports/vcpkg-fortran/x_vcpkg_find_fortran.cmake b/ports/vcpkg-fortran/x_vcpkg_find_fortran.cmake new file mode 100644 index 00000000000000..8e29b22c5ba236 --- /dev/null +++ b/ports/vcpkg-fortran/x_vcpkg_find_fortran.cmake @@ -0,0 +1,73 @@ +#[===[.md: +# x_vcpkg_find_fortran + +Checks if a Fortran compiler can be found. +Windows(x86/x64) Only: If not it will search and enable Intel + ifort compiler if available. + +## Usage +```cmake +x_vcpkg_find_fortran() +``` + +## Example +```cmake +x_vcpkg_find_fortran(fortran_args) +# ... +vcpkg_configure_cmake(... + OPTIONS + ${fortran_args} +) +``` +#]===] + + +function(x_vcpkg_find_fortran out_var) + if("${ARGC}" GREATER "1") + message(WARNING "${CMAKE_CURRENT_FUNCTION} was passed extra args: ${ARGN}") + endif() + + vcpkg_list(SET additional_cmake_args) + + set(CMAKE_BINARY_DIR "${CURRENT_BUILDTREES_DIR}/${TARGET_TRIPLET}") + set(CMAKE_CURRENT_BINARY_DIR "${CMAKE_BINARY_DIR}") + set(CMAKE_PLATFORM_INFO_DIR "${CMAKE_BINARY_DIR}/Platform") + include(CMakeDetermineFortranCompiler) + if(CMAKE_Fortran_COMPILER) + set(VCPKG_DETECTED_CMAKE_Fortran_COMPILER "${CMAKE_Fortran_COMPILER}" PARENT_SCOPE) + endif() + if(NOT CMAKE_Fortran_COMPILER AND "${VCPKG_CHAINLOAD_TOOLCHAIN_FILE}" STREQUAL "") + # If a user uses their own VCPKG_CHAINLOAD_TOOLCHAIN_FILE, they _must_ figure out Fortran on their own. + if(WIN32) + message(STATUS "No Fortran compiler found on the PATH. Trying to find and use ifort!") + set(PATH_SUFFIX "bin/intel64") + if(VCPKG_TARGET_ARCHITECTURE STREQUAL "x86") + string(APPEND PATH_SUFFIX "_ia32") + endif() + find_program(IFORT NAMES ifort PATHS ENV IFORT_COMPILER21 IFORT_COMPILER20 IFORT_COMPILER19 PATH_SUFFIXES "${PATH_SUFFIX}") + if(NOT IFORT) + message(STATUS "IFORT_COMPILER21:$ENV{IFORT_COMPILER21}") + message(STATUS "ONEAPI_ROOT:$ENV{ONEAPI_ROOT}") + message(FATAL_ERROR "ifort not found! Please install ifort from the Intel oneAPI for HPC toolkit: https://software.intel.com/content/www/us/en/develop/tools/oneapi/hpc-toolkit/download.html!") + endif() + find_file(SETVARS NAMES setvars.bat PATHS ENV ONEAPI_ROOT) + if(NOT SETVARS) + message(FATAL_ERROR "Batch file to setup Intel oneAPI not found! Please provide a correct ONEAPI_ROOT and make sure it contains setvars.bat!") + endif() + z_vcpkg_load_environment_from_batch(BATCH_FILE_PATH "${SETVARS}") + if(VCPKG_TARGET_IS_UWP) + set(extra_uwp_flags "/NODEFAULTLIB /Qopenmp-stubs /D_UNICODE /DUNICODE /DWINAPI_FAMILY=WINAPI_FAMILY_APP /D__WRL_NO_DEFAULT_LIB__") + set(exta_uwp_link_flags "-DCMAKE_SHARED_LINKER_FLAGS_INIT:STRING=/APPCONTAINER") + endif() + + vcpkg_list(APPEND additional_cmake_args + "-DCMAKE_Fortran_COMPILER=${IFORT}" + "-DCMAKE_Fortran_FLAGS_INIT:STRING=/Z7 /names:lowercase /assume:underscore /assume:protect_parens ${extra_uwp_flags}" + "${exta_uwp_link_flags}") + set(VCPKG_USE_INTERNAL_Fortran TRUE CACHE INTERNAL "") + else() + message(FATAL_ERROR "Unable to find a Fortran compiler using 'CMakeDetermineFortranCompiler'. Please install one (e.g. gfortran) and make it available on the PATH!") + endif() + endif() + set("${out_var}" "${additional_cmake_args}" PARENT_SCOPE) +endfunction() diff --git a/ports/vcpkg-fortran/z_vcpkg_load_environment_from_batch.cmake b/ports/vcpkg-fortran/z_vcpkg_load_environment_from_batch.cmake new file mode 100644 index 00000000000000..53b320193a3c97 --- /dev/null +++ b/ports/vcpkg-fortran/z_vcpkg_load_environment_from_batch.cmake @@ -0,0 +1,86 @@ +#[===[.md: +# x_vcpkg_load_environment_from_batch + +Load environment variables from a batch filed + +## Usage +```cmake +z_vcpkg_load_environment_from_batch(BATCH_FILE_PATH + [ARGUMENTS ]) +``` + +## Parameters +### BATCH_FILE_PATH +Batch file to load +### BATCH_FILE_PATH +Arguments to pass to the batch file +#]===] +function(z_vcpkg_load_environment_from_batch) + cmake_parse_arguments(PARSE_ARGV 0 args "" "BATCH_FILE_PATH" "ARGUMENTS") + if(args_BATCH_FILE_PATH STREQUAL "") + message(FATAL_ERROR "'${CMAKE_CURRENT_FUNCTION}' requires argument BATCH_FILE_PATH") + endif() + + # Get original environment + vcpkg_execute_required_process( + COMMAND "${CMAKE_COMMAND}" "-E" "environment" + WORKING_DIRECTORY "${CURRENT_BUILDTREES_DIR}" + LOGNAME "environment-initial" + ) + file(READ "${CURRENT_BUILDTREES_DIR}/environment-initial-out.log" ENVIRONMENT_INITIAL) + + # Get modified envirnoment + string (REPLACE ";" " " SPACE_SEPARATED_ARGUMENTS "${args_ARGUMENTS}") + + file(WRITE "${CURRENT_BUILDTREES_DIR}/get-modified-environment.bat" "call \"${args_BATCH_FILE_PATH}\" ${SPACE_SEPARATED_ARGUMENTS}\n\"${CMAKE_COMMAND}\" -E environment") + vcpkg_execute_required_process( + COMMAND "cmd" "/c" "${CURRENT_BUILDTREES_DIR}/get-modified-environment.bat" + WORKING_DIRECTORY "${CURRENT_BUILDTREES_DIR}" + LOGNAME "environment-after" + ) + file(READ "${CURRENT_BUILDTREES_DIR}/environment-after-out.log" ENVIRONMENT_AFTER) + + # Escape characters that have a special meaning in CMake strings. + string(REPLACE "\\" "/" ENVIRONMENT_INITIAL "${ENVIRONMENT_INITIAL}") + string(REPLACE ";" "\\\\;" ENVIRONMENT_INITIAL "${ENVIRONMENT_INITIAL}") + string(REPLACE "\n" ";" ENVIRONMENT_INITIAL "${ENVIRONMENT_INITIAL}") + + string(REPLACE "\\" "/" ENVIRONMENT_AFTER "${ENVIRONMENT_AFTER}") + string(REPLACE ";" "\\\\;" ENVIRONMENT_AFTER "${ENVIRONMENT_AFTER}") + string(REPLACE "\n" ";" ENVIRONMENT_AFTER "${ENVIRONMENT_AFTER}") + + # Apply the environment changes to the current CMake environment + foreach(AFTER_LINE IN LISTS ENVIRONMENT_AFTER) + if("${AFTER_LINE}" MATCHES "^([^=]+)=(.+)$") + set(AFTER_VAR_NAME "${CMAKE_MATCH_1}") + set(AFTER_VAR_VALUE "${CMAKE_MATCH_2}") + + set(FOUND "FALSE") + foreach(INITIAL_LINE IN LISTS ENVIRONMENT_INITIAL) + if("${INITIAL_LINE}" MATCHES "^([^=]+)=(.+)$") + set(INITIAL_VAR_NAME "${CMAKE_MATCH_1}") + set(INITIAL_VAR_VALUE "${CMAKE_MATCH_2}") + + if("${AFTER_VAR_NAME}" STREQUAL "${INITIAL_VAR_NAME}") + set(FOUND "TRUE") + if(NOT "${AFTER_VAR_VALUE}" STREQUAL "${INITIAL_VAR_VALUE}") + + # Variable has been modified + # NOTE: we do not revert the escape changes that have previously been applied + # since the only change that should be visible in a single environment variable + # should be a conversion from `\` to `/` and this should not have any effect on + # windows paths. + #message(STATUS "MODIFIED ${AFTER_VAR_NAME}=${AFTER_VAR_VALUE}") + set(ENV{${AFTER_VAR_NAME}} "${AFTER_VAR_VALUE}") + endif() + endif() + endif() + endforeach() + + if(NOT FOUND) + # Variable has been added + set(ENV{${AFTER_VAR_NAME}} "${AFTER_VAR_VALUE}") + endif() + endif() + endforeach() +endfunction() \ No newline at end of file diff --git a/ports/vcpkg-ifort/portfile.cmake b/ports/vcpkg-ifort/portfile.cmake new file mode 100644 index 00000000000000..fadc8326cbcd96 --- /dev/null +++ b/ports/vcpkg-ifort/portfile.cmake @@ -0,0 +1,52 @@ +x_vcpkg_find_fortran(FORTRAN_CMAKE) +message(STATUS "VCPKG_USE_INTERNAL_Fortran:${VCPKG_USE_INTERNAL_Fortran}") +if(VCPKG_USE_INTERNAL_Fortran) + foreach(_ver IN ITEMS 21 20 19) + if(DEFINED ENV{IFORT_COMPILER${_ver}}) + cmake_path(CONVERT "$ENV{IFORT_COMPILER${_ver}}" TO_CMAKE_PATH_LIST IFORT_COMPILER_ROOT) + break() + endif() + endforeach() + message(STATUS "IFORT_COMPILER_ROOT:${IFORT_COMPILER_ROOT}" ) + message(STATUS "ENV{ONEAPI_ROOT}:$ENV{ONEAPI_ROOT}" ) + if(VCPKG_TARGET_ARCHITECTURE STREQUAL "x86") + set(subpath "ia32_win") + elseif(VCPKG_TARGET_ARCHITECTURE STREQUAL "x64") + set(subpath "intel64_win") + endif() + + if(VCPKG_LIBRARY_LINKAGE STREQUAL "static") + set(IFORT_BASEPATH_LIBS "${IFORT_COMPILER_ROOT}/compiler/lib/${subpath}/") + file(COPY "${IFORT_BASEPATH_LIBS}" DESTINATION "${CURRENT_PACKAGES_DIR}/share/ifort/") + endif() + if(VCPKG_LIBRARY_LINKAGE STREQUAL "dynamic") + set(IFORT_BASEPATH_DLLS "${IFORT_COMPILER_ROOT}/redist/${subpath}/compiler/") + set(IFORT_DLLS + libifportmd.dll + libirngmd.dll + svml_dispmd.dll + libiomp5md.dll + libiompstubs5md.dll + ) + set(IFORT_DLLS_DEBUG + libifcoremdd.dll + libmmdd.dll + ) + set(IFORT_DLLS_RELEASE + libifcoremd.dll + libmmd.dll + ) + list(TRANSFORM IFORT_DLLS PREPEND "${IFORT_BASEPATH_DLLS}") + list(TRANSFORM IFORT_DLLS_DEBUG PREPEND "${IFORT_BASEPATH_DLLS}") + list(TRANSFORM IFORT_DLLS_RELEASE PREPEND "${IFORT_BASEPATH_DLLS}") + + file(MAKE_DIRECTORY "${CURRENT_PACKAGES_DIR}/bin" "${CURRENT_PACKAGES_DIR}/debug/bin") + file(COPY ${IFORT_DLLS} ${IFORT_DLLS_RELEASE} DESTINATION "${CURRENT_PACKAGES_DIR}/bin") + file(COPY ${IFORT_DLLS} ${IFORT_DLLS_DEBUG} DESTINATION "${CURRENT_PACKAGES_DIR}/debug/bin") + endif() + file(INSTALL "${IFORT_COMPILER_ROOT}/../../../licensing/latest/license.htm" DESTINATION "${CURRENT_PACKAGES_DIR}/share/${PORT}" RENAME copyright) # ONEAPI_ROOT; please check if this is the correct license + set(VCPKG_POLICY_DLLS_WITHOUT_LIBS enabled) # libs are at share/ifort and reflect how they are installed by the compiler instead of splitting them. + set(VCPKG_POLICY_EMPTY_INCLUDE_FOLDER enabled) +else() + set(VCPKG_POLICY_EMPTY_PACKAGE enabled) +endif() \ No newline at end of file diff --git a/ports/vcpkg-ifort/vcpkg.json b/ports/vcpkg-ifort/vcpkg.json new file mode 100644 index 00000000000000..94c1e100739c99 --- /dev/null +++ b/ports/vcpkg-ifort/vcpkg.json @@ -0,0 +1,10 @@ +{ + "name": "vcpkg-ifort", + "version-date": "2022-02-22", + "description": "Metaport to install ifort dll dependencies from Intel oneAPI", + "license": "MIT", + "supports": "(windows & !arm) & !uwp", + "dependencies": [ + "vcpkg-fortran" + ] +} diff --git a/versions/baseline.json b/versions/baseline.json index c2cc893f919c15..f6a85fe599ace3 100644 --- a/versions/baseline.json +++ b/versions/baseline.json @@ -3326,7 +3326,7 @@ }, "lapack-reference": { "baseline": "3.10.0", - "port-version": 0 + "port-version": 1 }, "lastools": { "baseline": "2020-05-09", @@ -7305,13 +7305,17 @@ "port-version": 1 }, "vcpkg-cmake": { - "baseline": "2022-04-21", + "baseline": "2022-04-28", "port-version": 0 }, "vcpkg-cmake-config": { "baseline": "2022-02-06", "port-version": 0 }, + "vcpkg-fortran": { + "baseline": "2022-02-22", + "port-version": 0 + }, "vcpkg-get-python-packages": { "baseline": "2022-04-11", "port-version": 0 @@ -7324,6 +7328,10 @@ "baseline": "2021-11-16", "port-version": 1 }, + "vcpkg-ifort": { + "baseline": "2022-02-22", + "port-version": 0 + }, "vcpkg-pkgconfig-get-modules": { "baseline": "2022-02-10", "port-version": 0 diff --git a/versions/l-/lapack-reference.json b/versions/l-/lapack-reference.json index 999e4f135ff049..7e7ce84ca79204 100644 --- a/versions/l-/lapack-reference.json +++ b/versions/l-/lapack-reference.json @@ -1,5 +1,10 @@ { "versions": [ + { + "git-tree": "7c96ff545fc7a4cad11318ed9ada4dc415e142c5", + "version": "3.10.0", + "port-version": 1 + }, { "git-tree": "14b5e3ab7315ce36951f759c6254712ed41cc0af", "version": "3.10.0", diff --git a/versions/v-/vcpkg-cmake.json b/versions/v-/vcpkg-cmake.json index 6643af5d0fffd9..dd53b4c1726a90 100644 --- a/versions/v-/vcpkg-cmake.json +++ b/versions/v-/vcpkg-cmake.json @@ -1,5 +1,10 @@ { "versions": [ + { + "git-tree": "c5eba73afc6c0d3d1deee203d6c5b691ec499d1e", + "version-date": "2022-04-28", + "port-version": 0 + }, { "git-tree": "8273918a04a5822ad7cc21ea5249402f2e999a7a", "version-date": "2022-04-21", diff --git a/versions/v-/vcpkg-fortran.json b/versions/v-/vcpkg-fortran.json new file mode 100644 index 00000000000000..cdb7010d7a126d --- /dev/null +++ b/versions/v-/vcpkg-fortran.json @@ -0,0 +1,14 @@ +{ + "versions": [ + { + "git-tree": "5e7c82bbcf2c873fda20de735f1a69ac79012167", + "version-date": "2022-02-22", + "port-version": 0 + }, + { + "git-tree": "e507aa2294e4cea644aecfec7650b3199915362f", + "version-string": "1", + "port-version": 0 + } + ] +} diff --git a/versions/v-/vcpkg-ifort.json b/versions/v-/vcpkg-ifort.json new file mode 100644 index 00000000000000..98c9546eba7438 --- /dev/null +++ b/versions/v-/vcpkg-ifort.json @@ -0,0 +1,14 @@ +{ + "versions": [ + { + "git-tree": "542084b622d35453fb8c25201cddd0c09c597424", + "version-date": "2022-02-22", + "port-version": 0 + }, + { + "git-tree": "6f744136a748369fac20e25c14b3c16b2d823988", + "version-string": "1", + "port-version": 0 + } + ] +}