# FDEFINES : -DHAVE_LAPACK -DHAVE_FINAL -DHAVE_ISO_FORTRAN_ENV -DHAVE_FLUSH_STMT -DHAVE_VOLATILE -DSERIAL_MPI -DMPI_MOD # CDEFINES : -DLowerUnderscore -DPtr64Bits #----------------------------------- # Set oldest allowable CMake version #----------------------------------- cmake_minimum_required(VERSION 3.11) cmake_policy(VERSION 3.11.1...3.13.3) set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake") #---------------------------------------------- # Define canonical CMake build types and extras #---------------------------------------------- set ( CMAKE_CONFIGURATION_TYPES "Debug" "Release" "MinSizeRel" "RelWithDebInfo" "CodeCoverage" ) set ( CMAKE_BUILD_TYPE "Release" CACHE STRING "Select which configuration to build." ) set_property ( CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS ${CMAKE_CONFIGURATION_TYPES} ) #----------------------------------------------------- # Determine version from .VERSION file or git describe #----------------------------------------------------- include(setVersion) set_version( VERSION_VARIABLE PSBLAS_Version GIT_DESCRIBE_VAR full_git_describe CUSTOM_VERSION_FILE "${CMAKE_SOURCE_DIR}/.VERSION") message( STATUS "Building PSBLAS1 version: ${full_git_describe}" ) #------------------------------------------ # Name project and specify source languages #------------------------------------------ project(psblas VERSION "${PSBLAS_Version}" LANGUAGES C Fortran) #-------------------------------------------------- # Set option to allow building against OpenCoarrays #-------------------------------------------------- if(CMAKE_Fortran_COMPILER_ID MATCHES "GNU") option(PSBLAS_USE_OpenCoarrays "Build enabling linkage to programs using OpenCoarrays" OFF) endif() #----------------------------------------------------------------- # Define a target to create a checksummed & signed release archive #----------------------------------------------------------------- set(${CMAKE_PROJECT_NAME}_dist_string "${CMAKE_PROJECT_NAME}-${full_git_describe}") if(GIT_FOUND) add_custom_target(dist # OUTPUT "${CMAKE_BINARY_DIR}/${_package_stem_name}.tar.gz" COMMAND "${CMAKE_COMMAND}" -P "${CMAKE_SOURCE_DIR}/cmake/makeDist.cmake" "${CMAKE_SOURCE_DIR}" "${CMAKE_BINARY_DIR}" COMMENT "Creating source release asset, ${_package_stem_name}.tar.gz, from ${_full_git_describe} using the `git archive` command." VERBATIM) endif() #-------------------------- # Prohibit in-source builds #-------------------------- include(CheckOutOfSourceBuild) #---------------------------------------------------- # Define coverage flags and report untested compilers #---------------------------------------------------- if ("${CMAKE_Fortran_COMPILER_ID}" MATCHES "GNU" ) set(gfortran_compiler true) #TODO: check if it is needed an mpi compiler set(CMAKE_Fortran_COMPILER mpifort) set ( CMAKE_C_FLAGS_CODECOVERAGE "-fprofile-arcs -ftest-coverage -O0" CACHE STRING "Code coverage C compiler flags") set ( CMAKE_Fortran_FLAGS_CODECOVERAGE "-fprofile-arcs -ftest-coverage -O0" CACHE STRING "Code coverage Fortran compiler flags") else() message(WARNING "\n" "Attempting untested CMake build with Fortran compiler: ${CMAKE_Fortran_COMPILER_ID}. " "Please report any failures at https://github.com/sfilippone/psblas3\n\n" ) endif() message(STATUS "cmake flags? ${CMAKE_Fortran_FLAGS};") #------------------------------------ # Fortran name mangling introspection #------------------------------------ include("${CMAKE_CURRENT_LIST_DIR}/cmake/CapitalizeString.cmake") include(FortranCInterface) CapitalizeString(${FortranCInterface_GLOBAL__CASE} fc_case) message(STATUS "Name mangling capitalization: ${fc_case}") message(STATUS "Name mangling fortran global suffix underscore: ${FortranCInterface_GLOBAL__SUFFIX}") if(FortranCInterface_GLOBAL__SUFFIX STREQUAL "") add_compile_options("-D${fc_case}Case") elseif(FortranCInterface_GLOBAL__SUFFIX STREQUAL "_") add_compile_options("-D${fc_case}Underscore") elseif(FortranCInterface_GLOBAL__SUFFIX STREQUAL "__") add_compile_options("-D${fc_case}DoubleUnderscore") else() message( FATAL_ERROR "Fortran name mangling suffix, \'${FortranCInterface_GLOBAL__SUFFIX}\', unknown to PSBLAS") endif() message(STATUS "win? ${WIN32};") if(TRUE )#NOT ${WIN32}) #previous check did not work if WIN32 is empty string #---------------------------------------------- # Determine system endian-ness and pointer size #---------------------------------------------- include(TestBigEndian) TEST_BIG_ENDIAN(IS_BIG_ENDIAN) if(IS_BIG_ENDIAN) message( STATUS "System appears to be big endian.") else() message( STATUS "System appears to be little endian.") add_compile_options(-DLittleEndian) endif() include(CheckTypeSize) CHECK_TYPE_SIZE("void *" VOID_P_SIZE LANGUAGE C) if(${VOID_P_SIZE} EQUAL 8) add_compile_options(-DPtr64Bits) endif() message(STATUS "Have 64bit pointers") #add define values for integer size (IPKx) and long size (LPKx) CHECK_TYPE_SIZE("int" INT_SIZE LANGUAGE C) CHECK_TYPE_SIZE("long" LONG_SIZE LANGUAGE C) message(STATUS "INT SIZE ${INT_SIZE}") add_compile_options(-DIPK${INT_SIZE}) add_compile_options(-DLPK${LONG_SIZE}) endif() #----------------------------------------- # Check for some Fortran compiler features #----------------------------------------- include(CheckFortranSourceCompiles) CHECK_Fortran_SOURCE_COMPILES( " integer, allocatable :: a(:), b(:) allocate(a(5)) a = [1,2,3,4,5] call move_alloc(from=a, to=b) end " HAVE_MOVE_ALLOC SRC_EXT f90 ) if(HAVE_MOVE_ALLOC) add_compile_options(-DHAVE_MOVE_ALLOC) message(STATUS "-DHAVE_MOVE_ALLOC") endif() CHECK_Fortran_SOURCE_COMPILES( "integer, volatile :: i ; end" HAVE_VOLATILE SRC_EXT f90 ) if(HAVE_VOLATILE) add_compile_options(-DHAVE_VOLATILE) message(STATUS "-DHAVE_VOLATILE") endif() CHECK_Fortran_SOURCE_COMPILES( "use ISO_FORTRAN_ENV ; end" HAVE_ISO_FORTRAN_ENV SRC_EXT f90 ) if(HAVE_ISO_FORTRAN_ENV) add_compile_options(-DHAVE_ISO_FORTRAN_ENV) message(STATUS "-DHAVE_ISO_FORTRAN_ENV") endif() CHECK_Fortran_SOURCE_COMPILES( "flush(5); end" HAVE_FLUSH_STMT SRC_EXT f90 ) if(HAVE_FLUSH_STMT) add_compile_options(-DHAVE_FLUSH_STMT) message(STATUS "-DHAVE_FLUSH_STMT") endif() CHECK_Fortran_SOURCE_COMPILES( " module conftest_mod type foo integer :: i contains final :: destroy_foo end type foo private destroy_foo contains subroutine destroy_foo(a) type(foo) :: a ! Just a test end subroutine destroy_foo end module conftest_mod program conftest use conftest_mod type(foo) :: foovar end program" HAVE_FINAL SRC_EXT f90 ) if(HAVE_FINAL) add_compile_options(-DHAVE_FINAL) message(STATUS "-DHAVE_FINAL") endif() CHECK_Fortran_SOURCE_COMPILES( " program xtt type foo integer :: i end type foo type, extends(foo) :: new_foo integer :: j end type new_foo class(foo), allocatable :: fooab type(new_foo) :: nfv integer :: info allocate(fooab, mold=nfv, stat=info) end program" HAVE_MOLD SRC_EXT f90) if(HAVE_MOLD) add_compile_options(-DHAVE_MOLD) message(STATUS "-DHAVE_MOLD") endif() CHECK_Fortran_SOURCE_COMPILES( " program conftest type foo integer :: i end type foo type, extends(foo) :: bar integer j end type bar type(bar) :: barvar end program " HAVE_EXTENDS_TYPE_OF SRC_EXT f90) if(HAVE_EXTENDS_TYPE_OF) add_compile_options(-DHAVE_EXTENDS_TYPE_OF) message(STATUS "-DHAVE_EXTENDS_TYPE_OF") endif() CHECK_Fortran_SOURCE_COMPILES( " program stt type foo integer :: i end type foo type, extends(foo) :: new_foo integer :: j end type new_foo type(foo) :: foov type(new_foo) :: nfv1, nfv2 write(*,*) 'foov == nfv1? ', same_type_as(foov,nfv1) write(*,*) 'nfv2 == nfv1? ', same_type_as(nfv2,nfv1) end program" HAVE_SAME_TYPE_AS SRC_EXT f90) if(HAVE_SAME_TYPE_AS) add_compile_options(-DHAVE_SAME_TYPE_AS) message(STATUS "-DHAVE_SAME_TYPE_AS") endif() #---------------------------------------------------------------------------- # Find MPI and set some flags so that FC and CC can point to gfortran and gcc #---------------------------------------------------------------------------- find_package( MPI REQUIRED Fortran ) if(MPI_FOUND) #----------------------------------------------- # Work around an issue present on fedora systems #----------------------------------------------- if( (MPI_C_LINK_FLAGS MATCHES "noexecstack") OR (MPI_Fortran_LINK_FLAGS MATCHES "noexecstack") ) message ( WARNING "The `noexecstack` linker flag was found in the MPI__LINK_FLAGS variable. This is known to cause segmentation faults for some Fortran codes. See, e.g., https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71729 or https://github.com/sourceryinstitute/OpenCoarrays/issues/317. `noexecstack` is being replaced with `execstack`" ) string(REPLACE "noexecstack" "execstack" MPI_C_LINK_FLAGS_FIXED ${MPI_C_LINK_FLAGS}) string(REPLACE "noexecstack" "execstack" MPI_Fortran_LINK_FLAGS_FIXED ${MPI_Fortran_LINK_FLAGS}) set(MPI_C_LINK_FLAGS "${MPI_C_LINK_FLAGS_FIXED}" CACHE STRING "MPI C linking flags" FORCE) set(MPI_Fortran_LINK_FLAGS "${MPI_Fortran_LINK_FLAGS_FIXED}" CACHE STRING "MPI Fortran linking flags" FORCE) endif() message(STATUS "Found MPI: ${MPI_C_LIBRARIES} ${MPI_Fortran_LIBRARIES}") #---------------- # Setup MPI flags #---------------- list(REMOVE_DUPLICATES MPI_Fortran_INCLUDE_PATH) set(CMAKE_C_COMPILE_FLAGS ${CMAKE_C_COMPILE_FLAGS} ${MPI_C_COMPILE_FLAGS}) set(CMAKE_C_LINK_FLAGS ${CMAKE_C_LINK_FLAGS} ${MPI_C_LINK_FLAGS}) set(CMAKE_Fortran_COMPILE_FLAGS ${CMAKE_Fortran_COMPILE_FLAGS} ${MPI_Fortran_COMPILE_FLAGS}) set(CMAKE_Fortran_LINK_FLAGS ${CMAKE_Fortran_LINK_FLAGS} ${MPI_Fortran_LINK_FLAGS}) include_directories(BEFORE ${MPI_C_INCLUDE_PATH} ${MPI_Fortran_INCLUDE_PATH}) message(STATUS "${MPI_C_INCLUDE_PATH}; ${MPI_Fortran_INCLUDE_PATH};; ${CMAKE_Fortran_LINK_FLAGS} ;") if(MPI_Fortran_HAVE_F90_MODULE OR MPI_Fortran_HAVE_F08_MODULE) add_compile_options(-DMPI_MOD) message(STATUS "-DMPI_MOD") #add_compile_options(-DSERIAL_MPI) # Is it right?? #message(STATUS "-DSERIAL_MPI") endif() set(SERIAL_MPI OFF) else() message(STATUS "MPI not found, serial ahead") add_compile_options(-DSERIAL_MPI) add_compile_options(-DMPI_MOD) set(SERIAL_MPI ON) endif() #------------------------------------------------------- # Find and Use OpenCoarrays IFF gfortran AND options set #------------------------------------------------------- if("${PSBLAS_USE_OpenCoarrays}" AND CMAKE_Fortran_COMPILER_ID MATCHES GNU) message(STATUS "Set openCoarrays") find_package(OpenCoarrays) endif() #------------------------------ # Find Linear Algebra Libraries #------------------------------ if(NOT APPLE) set(BLA_STATIC ON) endif() find_package(BLAS REQUIRED) find_package(LAPACK REQUIRED) add_compile_options(-DHAVE_LAPACK) #-------------------------------- # Find METIS partitioning library #-------------------------------- include(${CMAKE_CURRENT_LIST_DIR}/cmake/FindMETIS.cmake) find_package(METIS) #--------------------------------------------------- # Use standardized GNU install directory conventions #--------------------------------------------------- include(GNUInstallDirs) #set(mod_dir_tail "${${CMAKE_PROJECT_NAME}_dist_string}_${CMAKE_Fortran_COMPILER_ID}-${CMAKE_Fortran_COMPILER_VERSION}") set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}/${${CMAKE_PROJECT_NAME}_dist_string}-tests") set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}") set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}") #----------------------------------- # Turn on testing/ctest capabilities #----------------------------------- enable_testing() #------------------------------------------------------------------------------ # Add custom properties on targets for controling number of ranks during tests #------------------------------------------------------------------------------ define_property(TARGET PROPERTY MIN_RANKS BRIEF_DOCS "Minimum allowable ranks for the test " FULL_DOCS "Property to mark executable targets run as tests that they require at least ranks to run" ) define_property(TARGET PROPERTY POWER_2_RANKS BRIEF_DOCS "True if test must be run with a power of 2 ranks (T/F)" FULL_DOCS "Property to mark executable targets run as tests that they require 2^n ranks." ) #----------------------------------------------------- # Publicize installed location to other CMake projects #----------------------------------------------------- #install(EXPORT ${CMAKE_PROJECT_NAME}-targets # DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake" #) install(EXPORT ${CMAKE_PROJECT_NAME}-targets FILE ${CMAKE_PROJECT_NAME}Config.cmake NAMESPACE ${CMAKE_PROJECT_NAME}:: DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake" ) include(CMakePackageConfigHelpers) # standard CMake module write_basic_package_version_file( "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_PROJECT_NAME}ConfigVersion.cmake" VERSION "${psblas_VERSION}" COMPATIBILITY SameMajorVersion ) configure_file("${CMAKE_SOURCE_DIR}/cmake/pkg/${CMAKE_PROJECT_NAME}Config.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${CMAKE_PROJECT_NAME}Config.cmake" @ONLY) install( FILES "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${CMAKE_PROJECT_NAME}Config.cmake" "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_PROJECT_NAME}ConfigVersion.cmake" DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/psblas" ) #------------------------------------------ # Add portable unistall command to makefile #------------------------------------------ # Adapted from the CMake Wiki FAQ configure_file ( "${CMAKE_SOURCE_DIR}/cmake/uninstall.cmake.in" "${CMAKE_BINARY_DIR}/uninstall.cmake" @ONLY) add_custom_target ( uninstall COMMAND ${CMAKE_COMMAND} -P "${CMAKE_BINARY_DIR}/uninstall.cmake" ) add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure) # See JSON-Fortran's CMakeLists.txt file to find out how to get the check target to depend # on the test executables #---------------------------------- # Determine if we're using Open MPI #--------------------------------- if(MPI_FOUND) execute_process(COMMAND ${MPIEXEC} --version OUTPUT_VARIABLE mpi_version_out) if (mpi_version_out MATCHES "[Oo]pen[ -][Mm][Pp][Ii]") message( STATUS "OpenMPI detected") set ( openmpi true ) endif() endif() #--------------------------------------- # Add the PSBLAS libraries and utilities #--------------------------------------- # Link order, left to right: # cbind.a, util.a linsolve.a prec.a base.a include(${CMAKE_CURRENT_LIST_DIR}/base/CMakeLists.txt) include_directories("${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_INCLUDEDIR}") if(WIN32) add_library(psb_base_C STATIC ${base_source_C_files}) target_compile_definitions(psb_base_C PRIVATE -DWIN32 -D_LIB -DWIN64) set_target_properties(psb_base_C PROPERTIES LINKER_LANGUAGE C POSITION_INDEPENDENT_CODE TRUE) target_link_libraries(psb_base_C PUBLIC kernel32 user32 shell32) add_library(base ${base_source_files}) target_link_libraries(base PUBLIC psb_base_C) else() add_library(base_C OBJECT ${base_source_C_files}) add_library(base ${base_source_files} $) endif() # Set the Fortran module output directory for all targets set(CMAKE_Fortran_MODULE_DIRECTORY ${CMAKE_BINARY_DIR}/modules) #set(CMAKE_Fortran_MODULE_DIRECTORY "${CMAKE_BINARY_DIR}/include") message(STATUS "fortran module direcotry ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_INCLUDEDIR}") include_directories(${MPI_Fortran_INCLUDE_PATH}) message(STATUS "Using MPI include at: ${MPI_Fortran_INCLUDE_PATH}") set_target_properties(base PROPERTIES Fortran_MODULE_DIRECTORY "${CMAKE_BINARY_DIR}/modules" POSITION_INDEPENDENT_CODE TRUE OUTPUT_NAME psb_base LINKER_LANGUAGE Fortran ) target_include_directories(base PUBLIC $ $) message(STATUS "include dir := ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_INCLUDEDIR}") #target_include_directories(base PUBLIC ${CMAKE_Fortran_MODULE_DIRECTORY}) target_link_libraries(base PUBLIC ${LAPACK_LINKER_FLAGS} ${LAPACK_LIBRARIES} ${LAPACK95_LIBRARIES} PUBLIC ${BLAS_LINKER_FLAGS} ${BLAS_LIBRARIES} ${BLAS95_LIBRARIES}) #add_custom_command( # TARGET base POST_BUILD # COMMAND ${CMAKE_COMMAND} -E cmake_copy_f90_mod # ${MPI_Fortran_INCLUDE_PATH}mpi.mod ${CMAKE_BINARY_DIR}/include/mpi.mod #) include(${CMAKE_CURRENT_LIST_DIR}/prec/CMakeLists.txt) add_library(prec ${prec_source_files}) set_target_properties(prec PROPERTIES Fortran_MODULE_DIRECTORY "${CMAKE_BINARY_DIR}/modules" POSITION_INDEPENDENT_CODE TRUE OUTPUT_NAME psb_prec LINKER_LANGUAGE Fortran ) target_include_directories(prec PUBLIC $ $) target_link_libraries(prec PUBLIC base) include(${CMAKE_CURRENT_LIST_DIR}/linsolve/CMakeLists.txt) add_library(linsolve ${linsolve_source_files}) set_target_properties(linsolve PROPERTIES Fortran_MODULE_DIRECTORY "${CMAKE_BINARY_DIR}/modules" POSITION_INDEPENDENT_CODE TRUE OUTPUT_NAME psb_linsolve LINKER_LANGUAGE Fortran ) target_include_directories(linsolve PUBLIC $ $) target_link_libraries(linsolve PUBLIC base prec) include(${CMAKE_CURRENT_LIST_DIR}/ext/CMakeLists.txt) add_library(ext ${ext_source_files}) set_target_properties(ext PROPERTIES Fortran_MODULE_DIRECTORY "${CMAKE_BINARY_DIR}/modules" POSITION_INDEPENDENT_CODE TRUE OUTPUT_NAME psb_ext LINKER_LANGUAGE Fortran ) target_include_directories(ext PUBLIC $ $) target_link_libraries(ext PUBLIC base prec) #TODO: check actual dependencies include(${CMAKE_CURRENT_LIST_DIR}/util/CMakeLists.txt) if(WIN32) if(METIS_FOUND) add_library(psb_util_C STATIC ${util_source_C_files}) target_compile_definitions(psb_util_C PRIVATE -DWIN32 -D_LIB -DWIN64) set_target_properties(psb_util_C PROPERTIES LINKER_LANGUAGE C POSITION_INDEPENDENT_CODE TRUE) target_link_libraries(psb_util_C PUBLIC kernel32 user32 shell32) endif() add_library(util ${util_source_files}) if(METIS_FOUND) target_link_libraries(util PUBLIC psb_util_C) endif() else() add_library(psb_util_C OBJECT ${util_source_C_files}) add_library(util ${util_source_files} $) endif() set_target_properties(util PROPERTIES Fortran_MODULE_DIRECTORY "${CMAKE_BINARY_DIR}/modules" POSITION_INDEPENDENT_CODE TRUE OUTPUT_NAME psb_util LINKER_LANGUAGE Fortran ) target_include_directories(util PUBLIC $ $) target_link_libraries(util PUBLIC base prec) if(METIS_FOUND) message(STATUS "METIS PATH ${METIS_INCLUDES} and metis libraries ${METIS_LIBRARIES}") # Make sure this path is correct set(METISINCFILE "metis.h") # Adjust this to your actual path # Specify the configuration file set(HEADER_TEMPLATE "${CMAKE_CURRENT_SOURCE_DIR}/util/psb_metis_int.h.in") set(HEADER_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/include/psb_metis_int.h") # Configure the header file configure_file(${HEADER_TEMPLATE} ${HEADER_OUTPUT} @ONLY) # Check for real sizes using try_compile include(CheckCSourceCompiles) # Function to check the size of a type function(check_metis_real_type type_name) set(source_code " #include #include int main() { printf(\"%zu\\n\", sizeof(${type_name})); return 0; }") # Create a temporary source file file(WRITE "${CMAKE_BINARY_DIR}/CMakeFiles/CMakeTmp/test_size.c" "${source_code}") # Try to compile it try_compile(COMPILER_RESULT "${CMAKE_BINARY_DIR}/CMakeFiles/CMakeTmp" "${CMAKE_BINARY_DIR}/CMakeFiles/CMakeTmp/test_size.c") # Check the result and read the output if (COMPILER_RESULT) execute_process(COMMAND "${CMAKE_BINARY_DIR}/CMakeFiles/CMakeTmp/test_size" OUTPUT_VARIABLE type_size) string(STRIP "${type_size}" type_size) if (type_name STREQUAL "float") set(METIS_REAL_32 "${type_size}") add_definitions(-DMETIS_REAL_32) elseif (type_name STREQUAL "double") set(METIS_REAL_64 "${type_size}") add_definitions(-DMETIS_REAL_64) endif() else() message(WARNING "Failed to compile test for type size: ${type_name}") endif() endfunction() # Check for both float and double check_metis_real_type(float) check_metis_real_type(double) # Set HAVE_METIS if METIS is found add_compile_options(-DHAVE_METIS) target_include_directories(util PUBLIC ${METIS_INCLUDES}) target_include_directories(psb_util_C PUBLIC ${METIS_INCLUDES}) target_link_libraries(util PUBLIC ${METIS_LIBRARIES}) target_compile_definitions(psb_util_C PUBLIC HAVE_METIS_) target_compile_definitions(util PUBLIC HAVE_METIS) endif() # Include headers from the 'include' directory in the current directory include_directories(${CMAKE_BINARY_DIR}/include) include(${CMAKE_CURRENT_LIST_DIR}/cbind/CMakeLists.txt) if(WIN32) add_library(psb_cbind_C STATIC ${base_source_C_files}) target_compile_definitions(psb_cbind_C PRIVATE -DWIN32 -D_LIB -DWIN64) set_target_properties(psb_cbind_C PROPERTIES LINKER_LANGUAGE C POSITION_INDEPENDENT_CODE TRUE) target_link_libraries(psb_cbind_C PUBLIC kernel32 user32 shell32) add_library(cbind ${cbind_source_files}) target_link_libraries(cbind PUBLIC psb_cbind_C) else() add_library(cbind_C OBJECT ${cbind_source_C_files}) add_library(cbind ${cbind_source_files}) endif() #add_library(cbind ${cbind_source_files}) set_target_properties(cbind PROPERTIES Fortran_MODULE_DIRECTORY "${CMAKE_BINARY_DIR}/modules" POSITION_INDEPENDENT_CODE TRUE OUTPUT_NAME psb_cbind LINKER_LANGUAGE Fortran ) #target_include_directories(cbind PUBLIC # $ # $) # Include directories for the cbind library target_include_directories(cbind PUBLIC $ # Path for building $ # Path for installation ) target_link_libraries(cbind PUBLIC base prec linsolve ext util) # Custom command to copy all header files #add_custom_command( # OUTPUT ${CMAKE_BINARY_DIR}/include/ # Dummy output to represent the target directory # COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/include # Create the include directory if it doesn't exist # COMMAND ${CMAKE_COMMAND} -E copy_if_different ${cbind_header_C_files} ${CMAKE_BINARY_DIR}/include/ # Copy all headers # DEPENDS ${cbind_header_C_files} # Make the copy depend on the header files # COMMENT "Copying header files to include directory" #) # Create a custom target to copy headers #add_custom_target(copy_headers ALL DEPENDS ${CMAKE_BINARY_DIR}/include/) foreach(path IN LISTS cbind_header_C_files) # Copy the header file to the include directory file(COPY "${path}" DESTINATION "${CMAKE_BINARY_DIR}/include") endforeach() message(STATUS "Copied .h files to ${CMAKE_BINARY_DIR}/include") #target_include_directories(cbind PUBLIC # $ # $) # Include directories for the cbind library #target_include_directories(cbind_C PUBLICF # $ # Path for building # $ # Path for installation # ${CMAKE_BINARY_DIR}/include # Include the copied headers #) if(MPI_FOUND) # Copy mpi.mod from the first available path in MPI_Fortran_INCLUDE_PATH set(MPI_MOD_COPIED FALSE) foreach(path IN LISTS MPI_Fortran_INCLUDE_PATH) # Construct the full path to the mpi.mod file set(mpi_mod_path "${path}/mpi.mod") # Check if the mpi.mod file exists if(EXISTS "${mpi_mod_path}") # Copy the mpi.mod file to the module directory file(COPY "${mpi_mod_path}" DESTINATION "${CMAKE_Fortran_MODULE_DIRECTORY}") message(STATUS "Copied mpi.mod from ${mpi_mod_path} to ${CMAKE_Fortran_MODULE_DIRECTORY}") set(MPI_MOD_COPIED TRUE) break() # Exit the loop once we've copied the file endif() endforeach() if(NOT MPI_MOD_COPIED) message(WARNING "mpi.mod not found in any of the specified paths: ${MPI_Fortran_INCLUDE_PATH}") endif() foreach(lib base prec linsolve ext util cbind) target_link_libraries(${lib} PUBLIC ${MPI_C_LIBRARIES} ${MPI_Fortran_LIBRARIES}) endforeach() endif() if(OpenCoarrays_FOUND) foreach(lib base prec linsolve ext util cbind) #TODO: check if cbind goes here! target_link_libraries(${lib} PUBLIC OpenCoarrays::caf_mpi_static) endforeach() endif() message(STATUS "\t\t ${CMAKE_INSTALL_LIBDIR}") # Install the header files to the include directory #install(FILES ${cbind_header_C_files} # DESTINATION include #) install(DIRECTORY "${CMAKE_BINARY_DIR}/include" DESTINATION "include" FILES_MATCHING PATTERN "*.h") install(DIRECTORY "${CMAKE_BINARY_DIR}/modules" DESTINATION "modules" FILES_MATCHING PATTERN "*.mod") install(TARGETS base prec linsolve ext util cbind EXPORT ${CMAKE_PROJECT_NAME}-targets DESTINATION "${CMAKE_INSTALL_LIBDIR}" LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" ) if(WIN32) install(TARGETS psb_base_C EXPORT ${CMAKE_PROJECT_NAME}-targets DESTINATION "${CMAKE_INSTALL_LIBDIR}" LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" ) if(METIS_FOUND) install(TARGETS psb_util_C EXPORT ${CMAKE_PROJECT_NAME}-targets DESTINATION "${CMAKE_INSTALL_LIBDIR}" LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" ) endif() endif() # Step 2: Create the configuration file from the template configure_package_config_file( "${CMAKE_CURRENT_SOURCE_DIR}/cmake/psblasConfig.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/psblasConfig.cmake" INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/psblas" ) # Step 3: Install the generated config files install(FILES "${CMAKE_CURRENT_BINARY_DIR}/psblasConfig.cmake" "${CMAKE_CURRENT_BINARY_DIR}/psblasConfigVersion.cmake" DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/psblas" ) # Step 4: Export targets so that the build directory can be used directly export( EXPORT ${CMAKE_PROJECT_NAME}-targets FILE "${CMAKE_CURRENT_BINARY_DIR}/psblasTargets.cmake" NAMESPACE psblas:: ) #----------------- # Add PSBLAS tests #----------------- # Unit tests targeting each function, argument, and branch of code # add_mpi_test(initialize_mpi 2 initialize_mpi)