From 94a49a656a8bdc3002bae0684fbff5713ae48a32 Mon Sep 17 00:00:00 2001 From: Eduard Date: Mon, 22 Sep 2025 11:31:28 +0200 Subject: [PATCH 1/5] modularize BLAS and LAPACK --- src/CMakeLists.txt | 206 +++++++++++++++++++++++++++++++++++--- src/blas/CMakeLists.txt | 20 ---- src/lapack/CMakeLists.txt | 58 ----------- 3 files changed, 193 insertions(+), 91 deletions(-) delete mode 100644 src/blas/CMakeLists.txt delete mode 100644 src/lapack/CMakeLists.txt diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 424854bf1..7fb7b90f3 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,6 +1,197 @@ #### Pre-process: .fpp -> .f90 via Fypp # Create a list of the files to be preprocessed +set(blas_fppFiles + stdlib_kinds.fypp + blas/stdlib_blas_constants.fypp + blas/stdlib_blas.fypp + blas/stdlib_blas_level1.fypp + blas/stdlib_blas_level2_ban.fypp + blas/stdlib_blas_level2_gen.fypp + blas/stdlib_blas_level2_pac.fypp + blas/stdlib_blas_level2_sym.fypp + blas/stdlib_blas_level2_tri.fypp + blas/stdlib_blas_level3_gen.fypp + blas/stdlib_blas_level3_sym.fypp + blas/stdlib_blas_level3_tri.fypp + blas/stdlib_linalg_blas_aux.fypp +) +set(blas_cppFiles stdlib_linalg_constants.fypp stdlib_linalg_blas.fypp) + +fypp_f90("${fyppFlags}" "${blas_fppFiles}" blas_outFiles) +fypp_f90pp("${fyppFlags}" "${blas_cppFiles}" blas_outPreprocFiles) + +add_library(stdlib_blas ${blas_outFiles} ${blas_outPreprocFiles}) + +if(BLAS_FOUND) + target_link_libraries(stdlib_blas PUBLIC "BLAS::BLAS") +endif() + +set_target_properties( + stdlib_blas + PROPERTIES POSITION_INDEPENDENT_CODE ON WINDOWS_EXPORT_ALL_SYMBOLS ON +) + +if( + CMAKE_Fortran_COMPILER_ID STREQUAL GNU + AND CMAKE_Fortran_COMPILER_VERSION VERSION_LESS 10.0 +) + target_compile_options( + stdlib_blas + PRIVATE $<$:-fno-range-check> + ) +endif() + +set(LIB_MOD_DIR ${CMAKE_CURRENT_BINARY_DIR}/mod_files/blas/) +# We need the module directory before we finish the configure stage since the +# build interface might resolve before the module directory is generated by CMake +if(NOT EXISTS "${LIB_MOD_DIR}") + file(MAKE_DIRECTORY "${LIB_MOD_DIR}") +endif() + +set_target_properties( + stdlib_blas + PROPERTIES Fortran_MODULE_DIRECTORY ${LIB_MOD_DIR} +) +target_include_directories( + stdlib_blas + PUBLIC + $ + $ +) + +install( + TARGETS stdlib_blas + EXPORT ${PROJECT_NAME}-targets + RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" + ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" + LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" +) +install(DIRECTORY ${LIB_MOD_DIR} DESTINATION "${CMAKE_INSTALL_MODULEDIR}/blas") + +set(lapack_fppFiles + stdlib_kinds.fypp + stdlib_linalg_state.fypp + stdlib_error.fypp + stdlib_optval.fypp + stdlib_io.fypp + stdlib_ascii.fypp + stdlib_string_type.fypp + lapack/stdlib_lapack_base.fypp + lapack/stdlib_lapack_solve.fypp + lapack/stdlib_lapack_others.fypp + lapack/stdlib_lapack_orthogonal_factors.fypp + lapack/stdlib_lapack_eig_svd_lsq.fypp + lapack/stdlib_linalg_lapack_aux.fypp + lapack/stdlib_lapack_auxiliary.fypp + lapack/stdlib_lapack_blas_like_base.fypp + lapack/stdlib_lapack_blas_like_l1.fypp + lapack/stdlib_lapack_blas_like_l2.fypp + lapack/stdlib_lapack_blas_like_l3.fypp + lapack/stdlib_lapack_blas_like_mnorm.fypp + lapack/stdlib_lapack_blas_like_scalar.fypp + lapack/stdlib_lapack_cosine_sine.fypp + lapack/stdlib_lapack_cosine_sine2.fypp + lapack/stdlib_lapack_eigv_comp.fypp + lapack/stdlib_lapack_eigv_comp2.fypp + lapack/stdlib_lapack_eigv_gen.fypp + lapack/stdlib_lapack_eigv_gen2.fypp + lapack/stdlib_lapack_eigv_gen3.fypp + lapack/stdlib_lapack_eigv_std_driver.fypp + lapack/stdlib_lapack_eigv_svd_bidiag_dc.fypp + lapack/stdlib_lapack_eigv_svd_drivers.fypp + lapack/stdlib_lapack_eigv_svd_drivers2.fypp + lapack/stdlib_lapack_eigv_svd_drivers3.fypp + lapack/stdlib_lapack_eigv_sym_comp.fypp + lapack/stdlib_lapack_eigv_sym.fypp + lapack/stdlib_lapack_eigv_tridiag.fypp + lapack/stdlib_lapack_eigv_tridiag2.fypp + lapack/stdlib_lapack_eigv_tridiag3.fypp + lapack/stdlib_lapack_givens_jacobi_rot.fypp + lapack/stdlib_lapack_householder_reflectors.fypp + lapack/stdlib_lapack_lsq.fypp + lapack/stdlib_lapack_lsq_aux.fypp + lapack/stdlib_lapack_lsq_constrained.fypp + lapack/stdlib_lapack_orthogonal_factors_ql.fypp + lapack/stdlib_lapack_orthogonal_factors_qr.fypp + lapack/stdlib_lapack_orthogonal_factors_rz.fypp + lapack/stdlib_lapack_others_sm.fypp + lapack/stdlib_lapack_solve_aux.fypp + lapack/stdlib_lapack_solve_chol_comp.fypp + lapack/stdlib_lapack_solve_chol.fypp + lapack/stdlib_lapack_solve_ldl_comp.fypp + lapack/stdlib_lapack_solve_ldl_comp2.fypp + lapack/stdlib_lapack_solve_ldl_comp3.fypp + lapack/stdlib_lapack_solve_ldl_comp4.fypp + lapack/stdlib_lapack_solve_ldl.fypp + lapack/stdlib_lapack_solve_lu_comp.fypp + lapack/stdlib_lapack_solve_lu.fypp + lapack/stdlib_lapack_solve_tri_comp.fypp + lapack/stdlib_lapack_svd_bidiag_qr.fypp + lapack/stdlib_lapack_svd_comp.fypp + lapack/stdlib_lapack_svd_comp2.fypp +) +set(lapack_cppFiles stdlib_linalg_constants.fypp stdlib_linalg_lapack.fypp) + +fypp_f90("${fyppFlags}" "${lapack_fppFiles}" lapack_outFiles) +fypp_f90pp("${fyppFlags}" "${lapack_cppFiles}" lapack_outPreprocFiles) + +add_library(stdlib_lapack ${lapack_outFiles} ${lapack_outPreprocFiles}) + +if(LAPACK_FOUND) + target_link_libraries(stdlib_lapack PUBLIC "LAPACK::LAPACK") +endif() +target_link_libraries(stdlib_lapack PUBLIC stdlib_blas) + +set_target_properties( + stdlib_lapack + PROPERTIES POSITION_INDEPENDENT_CODE ON WINDOWS_EXPORT_ALL_SYMBOLS ON +) + +if( + CMAKE_Fortran_COMPILER_ID STREQUAL GNU + AND CMAKE_Fortran_COMPILER_VERSION VERSION_LESS 10.0 +) + target_compile_options( + stdlib_lapack + PRIVATE $<$:-fno-range-check> + ) +endif() + +set(LIB_MOD_DIR ${CMAKE_CURRENT_BINARY_DIR}/mod_files/lapack/) +# We need the module directory before we finish the configure stage since the +# build interface might resolve before the module directory is generated by CMake +if(NOT EXISTS "${LIB_MOD_DIR}") + file(MAKE_DIRECTORY "${LIB_MOD_DIR}") +endif() + +set_target_properties( + stdlib_lapack + PROPERTIES Fortran_MODULE_DIRECTORY ${LIB_MOD_DIR} +) + +if(f18errorstop) + target_sources(stdlib_lapack PRIVATE f18estop.f90) +else() + target_sources(stdlib_lapack PRIVATE f08estop.f90) +endif() + +target_include_directories( + stdlib_lapack + PUBLIC + $ + $ +) + +install( + TARGETS stdlib_lapack + EXPORT ${PROJECT_NAME}-targets + RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" + ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" + LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" +) +install(DIRECTORY ${LIB_MOD_DIR} DESTINATION "${CMAKE_INSTALL_MODULEDIR}") + set(fppFiles stdlib_ascii.fypp stdlib_bitsets.fypp @@ -91,14 +282,7 @@ set(fppFiles ) # Preprocessed files to contain preprocessor directives -> .F90 -set(cppFiles - stdlib_linalg_constants.fypp - stdlib_linalg_blas.fypp - stdlib_linalg_lapack.fypp -) - -add_subdirectory(blas) -add_subdirectory(lapack) +set(cppFiles stdlib_linalg_constants.fypp) fypp_f90("${fyppFlags}" "${fppFiles}" outFiles) fypp_f90pp("${fyppFlags}" "${cppFiles}" outPreprocFiles) @@ -130,11 +314,7 @@ set(SRC add_library(${PROJECT_NAME} ${SRC}) -# Link to BLAS and LAPACK -if(BLAS_FOUND AND LAPACK_FOUND) - target_link_libraries(${PROJECT_NAME} "BLAS::BLAS") - target_link_libraries(${PROJECT_NAME} "LAPACK::LAPACK") -endif() +target_link_libraries(${PROJECT_NAME} PUBLIC stdlib_blas stdlib_lapack) set_target_properties( ${PROJECT_NAME} diff --git a/src/blas/CMakeLists.txt b/src/blas/CMakeLists.txt deleted file mode 100644 index 5099b909e..000000000 --- a/src/blas/CMakeLists.txt +++ /dev/null @@ -1,20 +0,0 @@ -#### - -set(dir "${CMAKE_CURRENT_SOURCE_DIR}") - -list(APPEND fppFiles - blas/stdlib_blas_constants.fypp - blas/stdlib_blas.fypp - blas/stdlib_blas_level1.fypp - blas/stdlib_blas_level2_ban.fypp - blas/stdlib_blas_level2_gen.fypp - blas/stdlib_blas_level2_pac.fypp - blas/stdlib_blas_level2_sym.fypp - blas/stdlib_blas_level2_tri.fypp - blas/stdlib_blas_level3_gen.fypp - blas/stdlib_blas_level3_sym.fypp - blas/stdlib_blas_level3_tri.fypp - blas/stdlib_linalg_blas_aux.fypp -) - -set(fppFiles "${fppFiles}" PARENT_SCOPE) diff --git a/src/lapack/CMakeLists.txt b/src/lapack/CMakeLists.txt deleted file mode 100644 index a8f3445ce..000000000 --- a/src/lapack/CMakeLists.txt +++ /dev/null @@ -1,58 +0,0 @@ -list(APPEND fppFiles - lapack/stdlib_lapack_base.fypp - lapack/stdlib_lapack_solve.fypp - lapack/stdlib_lapack_others.fypp - lapack/stdlib_lapack_orthogonal_factors.fypp - lapack/stdlib_lapack_eig_svd_lsq.fypp - lapack/stdlib_linalg_lapack_aux.fypp - - lapack/stdlib_lapack_auxiliary.fypp - lapack/stdlib_lapack_blas_like_base.fypp - lapack/stdlib_lapack_blas_like_l1.fypp - lapack/stdlib_lapack_blas_like_l2.fypp - lapack/stdlib_lapack_blas_like_l3.fypp - lapack/stdlib_lapack_blas_like_mnorm.fypp - lapack/stdlib_lapack_blas_like_scalar.fypp - lapack/stdlib_lapack_cosine_sine.fypp - lapack/stdlib_lapack_cosine_sine2.fypp - lapack/stdlib_lapack_eigv_comp.fypp - lapack/stdlib_lapack_eigv_comp2.fypp - lapack/stdlib_lapack_eigv_gen.fypp - lapack/stdlib_lapack_eigv_gen2.fypp - lapack/stdlib_lapack_eigv_gen3.fypp - lapack/stdlib_lapack_eigv_std_driver.fypp - lapack/stdlib_lapack_eigv_svd_bidiag_dc.fypp - lapack/stdlib_lapack_eigv_svd_drivers.fypp - lapack/stdlib_lapack_eigv_svd_drivers2.fypp - lapack/stdlib_lapack_eigv_svd_drivers3.fypp - lapack/stdlib_lapack_eigv_sym_comp.fypp - lapack/stdlib_lapack_eigv_sym.fypp - lapack/stdlib_lapack_eigv_tridiag.fypp - lapack/stdlib_lapack_eigv_tridiag2.fypp - lapack/stdlib_lapack_eigv_tridiag3.fypp - lapack/stdlib_lapack_givens_jacobi_rot.fypp - lapack/stdlib_lapack_householder_reflectors.fypp - lapack/stdlib_lapack_lsq.fypp - lapack/stdlib_lapack_lsq_aux.fypp - lapack/stdlib_lapack_lsq_constrained.fypp - lapack/stdlib_lapack_orthogonal_factors_ql.fypp - lapack/stdlib_lapack_orthogonal_factors_qr.fypp - lapack/stdlib_lapack_orthogonal_factors_rz.fypp - lapack/stdlib_lapack_others_sm.fypp - lapack/stdlib_lapack_solve_aux.fypp - lapack/stdlib_lapack_solve_chol_comp.fypp - lapack/stdlib_lapack_solve_chol.fypp - lapack/stdlib_lapack_solve_ldl_comp.fypp - lapack/stdlib_lapack_solve_ldl_comp2.fypp - lapack/stdlib_lapack_solve_ldl_comp3.fypp - lapack/stdlib_lapack_solve_ldl_comp4.fypp - lapack/stdlib_lapack_solve_ldl.fypp - lapack/stdlib_lapack_solve_lu_comp.fypp - lapack/stdlib_lapack_solve_lu.fypp - lapack/stdlib_lapack_solve_tri_comp.fypp - lapack/stdlib_lapack_svd_bidiag_qr.fypp - lapack/stdlib_lapack_svd_comp.fypp - lapack/stdlib_lapack_svd_comp2.fypp -) - -set(fppFiles "${fppFiles}" PARENT_SCOPE) From d43ae5cfcc90d5e33dc049dc62095a03d08b272f Mon Sep 17 00:00:00 2001 From: Eduard Date: Mon, 22 Sep 2025 13:03:09 +0200 Subject: [PATCH 2/5] abstract the configuration of the targets --- src/CMakeLists.txt | 219 +++++++++++++-------------------------------- 1 file changed, 64 insertions(+), 155 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7fb7b90f3..81f6ef7c6 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,6 +1,56 @@ -#### Pre-process: .fpp -> .f90 via Fypp +# Helper function to configure stdlib targets +function(configure_stdlib_target target_name regular_sources_var fypp_files_var cpp_files_var) + #### Pre-process: .fpp -> .f90 via Fypp + fypp_f90("${fyppFlags}" "${${fypp_files_var}}" ${target_name}_fypp_outFiles) + #### Pre-process: .fypp -> .F90 via Fypp (for C preprocessor directives) + fypp_f90pp("${fyppFlags}" "${${cpp_files_var}}" ${target_name}_cpp_outFiles) + + list(APPEND all_sources ${${target_name}_fypp_outFiles}) + list(APPEND all_sources ${${target_name}_cpp_outFiles}) + list(APPEND all_sources ${${regular_sources_var}}) + + add_library(${target_name} ${all_sources}) + + set_target_properties( + ${target_name} + PROPERTIES + POSITION_INDEPENDENT_CODE ON + WINDOWS_EXPORT_ALL_SYMBOLS ON + ) + + if(CMAKE_Fortran_COMPILER_ID STREQUAL GNU AND CMAKE_Fortran_COMPILER_VERSION VERSION_LESS 10.0) + target_compile_options( + ${target_name} + PRIVATE + $<$:-fno-range-check> + ) + endif() + + set(LIB_MOD_DIR ${CMAKE_CURRENT_BINARY_DIR}/mod_files/${target_name}/) + set(INSTALL_MOD_DIR "${CMAKE_INSTALL_MODULEDIR}/${target_name}") + # We need the module directory before we finish the configure stage since the + # build interface might resolve before the module directory is generated by CMake + if(NOT EXISTS "${LIB_MOD_DIR}") + file(MAKE_DIRECTORY "${LIB_MOD_DIR}") + endif() + + set_target_properties(${target_name} PROPERTIES + Fortran_MODULE_DIRECTORY ${LIB_MOD_DIR} + ) + target_include_directories(${target_name} PUBLIC + $ + $ + ) + + install(TARGETS ${target_name} + EXPORT ${PROJECT_NAME}-targets + RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" + ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" + LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" + ) + install(DIRECTORY ${LIB_MOD_DIR} DESTINATION "${INSTALL_MOD_DIR}") +endfunction() -# Create a list of the files to be preprocessed set(blas_fppFiles stdlib_kinds.fypp blas/stdlib_blas_constants.fypp @@ -18,57 +68,12 @@ set(blas_fppFiles ) set(blas_cppFiles stdlib_linalg_constants.fypp stdlib_linalg_blas.fypp) -fypp_f90("${fyppFlags}" "${blas_fppFiles}" blas_outFiles) -fypp_f90pp("${fyppFlags}" "${blas_cppFiles}" blas_outPreprocFiles) - -add_library(stdlib_blas ${blas_outFiles} ${blas_outPreprocFiles}) +configure_stdlib_target(stdlib_blas "" blas_fppFiles blas_cppFiles) if(BLAS_FOUND) target_link_libraries(stdlib_blas PUBLIC "BLAS::BLAS") endif() -set_target_properties( - stdlib_blas - PROPERTIES POSITION_INDEPENDENT_CODE ON WINDOWS_EXPORT_ALL_SYMBOLS ON -) - -if( - CMAKE_Fortran_COMPILER_ID STREQUAL GNU - AND CMAKE_Fortran_COMPILER_VERSION VERSION_LESS 10.0 -) - target_compile_options( - stdlib_blas - PRIVATE $<$:-fno-range-check> - ) -endif() - -set(LIB_MOD_DIR ${CMAKE_CURRENT_BINARY_DIR}/mod_files/blas/) -# We need the module directory before we finish the configure stage since the -# build interface might resolve before the module directory is generated by CMake -if(NOT EXISTS "${LIB_MOD_DIR}") - file(MAKE_DIRECTORY "${LIB_MOD_DIR}") -endif() - -set_target_properties( - stdlib_blas - PROPERTIES Fortran_MODULE_DIRECTORY ${LIB_MOD_DIR} -) -target_include_directories( - stdlib_blas - PUBLIC - $ - $ -) - -install( - TARGETS stdlib_blas - EXPORT ${PROJECT_NAME}-targets - RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" - ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" - LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" -) -install(DIRECTORY ${LIB_MOD_DIR} DESTINATION "${CMAKE_INSTALL_MODULEDIR}/blas") - set(lapack_fppFiles stdlib_kinds.fypp stdlib_linalg_state.fypp @@ -131,67 +136,21 @@ set(lapack_fppFiles lapack/stdlib_lapack_svd_comp.fypp lapack/stdlib_lapack_svd_comp2.fypp ) -set(lapack_cppFiles stdlib_linalg_constants.fypp stdlib_linalg_lapack.fypp) - -fypp_f90("${fyppFlags}" "${lapack_fppFiles}" lapack_outFiles) -fypp_f90pp("${fyppFlags}" "${lapack_cppFiles}" lapack_outPreprocFiles) +set(lapack_cppFiles + stdlib_linalg_constants.fypp + stdlib_linalg_lapack.fypp +) +set(lapack_f90Files + $,f18estop.f90,f08estop.f90> +) -add_library(stdlib_lapack ${lapack_outFiles} ${lapack_outPreprocFiles}) +configure_stdlib_target(stdlib_lapack lapack_f90Files lapack_fppFiles lapack_cppFiles) if(LAPACK_FOUND) target_link_libraries(stdlib_lapack PUBLIC "LAPACK::LAPACK") endif() target_link_libraries(stdlib_lapack PUBLIC stdlib_blas) -set_target_properties( - stdlib_lapack - PROPERTIES POSITION_INDEPENDENT_CODE ON WINDOWS_EXPORT_ALL_SYMBOLS ON -) - -if( - CMAKE_Fortran_COMPILER_ID STREQUAL GNU - AND CMAKE_Fortran_COMPILER_VERSION VERSION_LESS 10.0 -) - target_compile_options( - stdlib_lapack - PRIVATE $<$:-fno-range-check> - ) -endif() - -set(LIB_MOD_DIR ${CMAKE_CURRENT_BINARY_DIR}/mod_files/lapack/) -# We need the module directory before we finish the configure stage since the -# build interface might resolve before the module directory is generated by CMake -if(NOT EXISTS "${LIB_MOD_DIR}") - file(MAKE_DIRECTORY "${LIB_MOD_DIR}") -endif() - -set_target_properties( - stdlib_lapack - PROPERTIES Fortran_MODULE_DIRECTORY ${LIB_MOD_DIR} -) - -if(f18errorstop) - target_sources(stdlib_lapack PRIVATE f18estop.f90) -else() - target_sources(stdlib_lapack PRIVATE f08estop.f90) -endif() - -target_include_directories( - stdlib_lapack - PUBLIC - $ - $ -) - -install( - TARGETS stdlib_lapack - EXPORT ${PROJECT_NAME}-targets - RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" - ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" - LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" -) -install(DIRECTORY ${LIB_MOD_DIR} DESTINATION "${CMAKE_INSTALL_MODULEDIR}") - set(fppFiles stdlib_ascii.fypp stdlib_bitsets.fypp @@ -280,14 +239,8 @@ set(fppFiles stdlib_strings.fypp stdlib_version.fypp ) - -# Preprocessed files to contain preprocessor directives -> .F90 set(cppFiles stdlib_linalg_constants.fypp) - -fypp_f90("${fyppFlags}" "${fppFiles}" outFiles) -fypp_f90pp("${fyppFlags}" "${cppFiles}" outPreprocFiles) - -set(SRC +set(f90Files stdlib_ansi.f90 stdlib_ansi_operator.f90 stdlib_ansi_to_string.f90 @@ -308,53 +261,9 @@ set(SRC stdlib_specialfunctions_legendre.f90 stdlib_quadrature_gauss.f90 stdlib_stringlist_type.f90 - ${outFiles} - ${outPreprocFiles} + $,f18estop.f90,f08estop.f90> ) -add_library(${PROJECT_NAME} ${SRC}) +configure_stdlib_target(${PROJECT_NAME} f90Files fppFiles cppFiles) target_link_libraries(${PROJECT_NAME} PUBLIC stdlib_blas stdlib_lapack) - -set_target_properties( - ${PROJECT_NAME} - PROPERTIES - POSITION_INDEPENDENT_CODE ON - WINDOWS_EXPORT_ALL_SYMBOLS ON -) - -if(CMAKE_Fortran_COMPILER_ID STREQUAL GNU AND CMAKE_Fortran_COMPILER_VERSION VERSION_LESS 10.0) - target_compile_options( - ${PROJECT_NAME} - PRIVATE - $<$:-fno-range-check> - ) -endif() - -set(LIB_MOD_DIR ${CMAKE_CURRENT_BINARY_DIR}/mod_files/) -# We need the module directory before we finish the configure stage since the -# build interface might resolve before the module directory is generated by CMake -if(NOT EXISTS "${LIB_MOD_DIR}") - file(MAKE_DIRECTORY "${LIB_MOD_DIR}") -endif() - -set_target_properties(${PROJECT_NAME} PROPERTIES - Fortran_MODULE_DIRECTORY ${LIB_MOD_DIR}) -target_include_directories(${PROJECT_NAME} PUBLIC - $ - $ -) - -if(f18errorstop) - target_sources(${PROJECT_NAME} PRIVATE f18estop.f90) -else() - target_sources(${PROJECT_NAME} PRIVATE f08estop.f90) -endif() - -install(TARGETS ${PROJECT_NAME} - EXPORT ${PROJECT_NAME}-targets - RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" - ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" - LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" -) -install(DIRECTORY ${LIB_MOD_DIR} DESTINATION "${CMAKE_INSTALL_MODULEDIR}") From 3a782fb1f33a1eb827df56ab39fb5f4631c7bbb9 Mon Sep 17 00:00:00 2001 From: Eduard Date: Mon, 22 Sep 2025 14:27:20 +0200 Subject: [PATCH 3/5] nicer targets when importing with FetchContent --- src/CMakeLists.txt | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 81f6ef7c6..202ee0010 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -10,6 +10,7 @@ function(configure_stdlib_target target_name regular_sources_var fypp_files_var list(APPEND all_sources ${${regular_sources_var}}) add_library(${target_name} ${all_sources}) + add_library(${PROJECT_NAME}::${target_name} ALIAS ${target_name}) set_target_properties( ${target_name} @@ -68,10 +69,10 @@ set(blas_fppFiles ) set(blas_cppFiles stdlib_linalg_constants.fypp stdlib_linalg_blas.fypp) -configure_stdlib_target(stdlib_blas "" blas_fppFiles blas_cppFiles) +configure_stdlib_target(blas "" blas_fppFiles blas_cppFiles) if(BLAS_FOUND) - target_link_libraries(stdlib_blas PUBLIC "BLAS::BLAS") + target_link_libraries(blas PUBLIC "BLAS::BLAS") endif() set(lapack_fppFiles @@ -144,12 +145,12 @@ set(lapack_f90Files $,f18estop.f90,f08estop.f90> ) -configure_stdlib_target(stdlib_lapack lapack_f90Files lapack_fppFiles lapack_cppFiles) +configure_stdlib_target(lapack lapack_f90Files lapack_fppFiles lapack_cppFiles) if(LAPACK_FOUND) - target_link_libraries(stdlib_lapack PUBLIC "LAPACK::LAPACK") + target_link_libraries(lapack PUBLIC "LAPACK::LAPACK") endif() -target_link_libraries(stdlib_lapack PUBLIC stdlib_blas) +target_link_libraries(lapack PUBLIC blas) set(fppFiles stdlib_ascii.fypp @@ -266,4 +267,4 @@ set(f90Files configure_stdlib_target(${PROJECT_NAME} f90Files fppFiles cppFiles) -target_link_libraries(${PROJECT_NAME} PUBLIC stdlib_blas stdlib_lapack) +target_link_libraries(${PROJECT_NAME} PUBLIC blas lapack) From 4263c83364d534f323da4a524c9fb63d9a570aba Mon Sep 17 00:00:00 2001 From: Eduard Date: Tue, 23 Sep 2025 10:08:09 +0200 Subject: [PATCH 4/5] restore separate BLAS/LAPACK CMakeLists --- cmake/stdlib.cmake | 65 +++++++++++++++- src/CMakeLists.txt | 155 +------------------------------------- src/blas/CMakeLists.txt | 25 ++++++ src/lapack/CMakeLists.txt | 77 +++++++++++++++++++ 4 files changed, 168 insertions(+), 154 deletions(-) create mode 100644 src/blas/CMakeLists.txt create mode 100644 src/lapack/CMakeLists.txt diff --git a/cmake/stdlib.cmake b/cmake/stdlib.cmake index bdaf87d1f..0ec86e299 100644 --- a/cmake/stdlib.cmake +++ b/cmake/stdlib.cmake @@ -12,7 +12,8 @@ function(preprocess preproc preprocopts srcext trgext srcfiles trgfiles) set(_trgfiles) foreach(srcfile IN LISTS srcfiles) - string(REGEX REPLACE "\\.${srcext}$" ".${trgext}" trgfile ${srcfile}) + get_filename_component(filename ${srcfile} NAME) + string(REGEX REPLACE "\\.${srcext}$" ".${trgext}" trgfile ${filename}) add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${trgfile} COMMAND ${preproc} ${preprocopts} ${CMAKE_CURRENT_SOURCE_DIR}/${srcfile} ${CMAKE_CURRENT_BINARY_DIR}/${trgfile} @@ -47,3 +48,65 @@ function (fypp_f90pp fyppopts fyppfiles F90files) set(${F90files} ${_F90files} PARENT_SCOPE) endfunction() +# Helper function to configure stdlib targets +# +# It preprocesses the given fypp and fypp+cpp files, combines them with the +# regular Fortran files, and creates a library target with the given name. +# Args: +# target_name [in]: Name of the library target to create +# regular_sources_var [in]: Regular Fortran sources +# fypp_files_var [in]: Sources to be preprocessed with fypp +# cpp_files_var [in]: Sources to be preprocessed with fypp and cpp +# +function(configure_stdlib_target target_name regular_sources_var fypp_files_var cpp_files_var) + #### Pre-process: .fpp -> .f90 via Fypp + fypp_f90("${fyppFlags}" "${${fypp_files_var}}" ${target_name}_fypp_outFiles) + #### Pre-process: .fypp -> .F90 via Fypp (for C preprocessor directives) + fypp_f90pp("${fyppFlags}" "${${cpp_files_var}}" ${target_name}_cpp_outFiles) + + list(APPEND all_sources ${${target_name}_fypp_outFiles}) + list(APPEND all_sources ${${target_name}_cpp_outFiles}) + list(APPEND all_sources ${${regular_sources_var}}) + + add_library(${target_name} ${all_sources}) + add_library(${PROJECT_NAME}::${target_name} ALIAS ${target_name}) + + set_target_properties( + ${target_name} + PROPERTIES + POSITION_INDEPENDENT_CODE ON + WINDOWS_EXPORT_ALL_SYMBOLS ON + ) + + if(CMAKE_Fortran_COMPILER_ID STREQUAL GNU AND CMAKE_Fortran_COMPILER_VERSION VERSION_LESS 10.0) + target_compile_options( + ${target_name} + PRIVATE + $<$:-fno-range-check> + ) + endif() + + set(LIB_MOD_DIR ${CMAKE_CURRENT_BINARY_DIR}/mod_files/${target_name}/) + set(INSTALL_MOD_DIR "${CMAKE_INSTALL_MODULEDIR}/${target_name}") + # We need the module directory before we finish the configure stage since the + # build interface might resolve before the module directory is generated by CMake + if(NOT EXISTS "${LIB_MOD_DIR}") + file(MAKE_DIRECTORY "${LIB_MOD_DIR}") + endif() + + set_target_properties(${target_name} PROPERTIES + Fortran_MODULE_DIRECTORY ${LIB_MOD_DIR} + ) + target_include_directories(${target_name} PUBLIC + $ + $ + ) + + install(TARGETS ${target_name} + EXPORT ${PROJECT_NAME}-targets + RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" + ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" + LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" + ) + install(DIRECTORY ${LIB_MOD_DIR} DESTINATION "${INSTALL_MOD_DIR}") +endfunction() diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 202ee0010..54b84bdd3 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,156 +1,5 @@ -# Helper function to configure stdlib targets -function(configure_stdlib_target target_name regular_sources_var fypp_files_var cpp_files_var) - #### Pre-process: .fpp -> .f90 via Fypp - fypp_f90("${fyppFlags}" "${${fypp_files_var}}" ${target_name}_fypp_outFiles) - #### Pre-process: .fypp -> .F90 via Fypp (for C preprocessor directives) - fypp_f90pp("${fyppFlags}" "${${cpp_files_var}}" ${target_name}_cpp_outFiles) - - list(APPEND all_sources ${${target_name}_fypp_outFiles}) - list(APPEND all_sources ${${target_name}_cpp_outFiles}) - list(APPEND all_sources ${${regular_sources_var}}) - - add_library(${target_name} ${all_sources}) - add_library(${PROJECT_NAME}::${target_name} ALIAS ${target_name}) - - set_target_properties( - ${target_name} - PROPERTIES - POSITION_INDEPENDENT_CODE ON - WINDOWS_EXPORT_ALL_SYMBOLS ON - ) - - if(CMAKE_Fortran_COMPILER_ID STREQUAL GNU AND CMAKE_Fortran_COMPILER_VERSION VERSION_LESS 10.0) - target_compile_options( - ${target_name} - PRIVATE - $<$:-fno-range-check> - ) - endif() - - set(LIB_MOD_DIR ${CMAKE_CURRENT_BINARY_DIR}/mod_files/${target_name}/) - set(INSTALL_MOD_DIR "${CMAKE_INSTALL_MODULEDIR}/${target_name}") - # We need the module directory before we finish the configure stage since the - # build interface might resolve before the module directory is generated by CMake - if(NOT EXISTS "${LIB_MOD_DIR}") - file(MAKE_DIRECTORY "${LIB_MOD_DIR}") - endif() - - set_target_properties(${target_name} PROPERTIES - Fortran_MODULE_DIRECTORY ${LIB_MOD_DIR} - ) - target_include_directories(${target_name} PUBLIC - $ - $ - ) - - install(TARGETS ${target_name} - EXPORT ${PROJECT_NAME}-targets - RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" - ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" - LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" - ) - install(DIRECTORY ${LIB_MOD_DIR} DESTINATION "${INSTALL_MOD_DIR}") -endfunction() - -set(blas_fppFiles - stdlib_kinds.fypp - blas/stdlib_blas_constants.fypp - blas/stdlib_blas.fypp - blas/stdlib_blas_level1.fypp - blas/stdlib_blas_level2_ban.fypp - blas/stdlib_blas_level2_gen.fypp - blas/stdlib_blas_level2_pac.fypp - blas/stdlib_blas_level2_sym.fypp - blas/stdlib_blas_level2_tri.fypp - blas/stdlib_blas_level3_gen.fypp - blas/stdlib_blas_level3_sym.fypp - blas/stdlib_blas_level3_tri.fypp - blas/stdlib_linalg_blas_aux.fypp -) -set(blas_cppFiles stdlib_linalg_constants.fypp stdlib_linalg_blas.fypp) - -configure_stdlib_target(blas "" blas_fppFiles blas_cppFiles) - -if(BLAS_FOUND) - target_link_libraries(blas PUBLIC "BLAS::BLAS") -endif() - -set(lapack_fppFiles - stdlib_kinds.fypp - stdlib_linalg_state.fypp - stdlib_error.fypp - stdlib_optval.fypp - stdlib_io.fypp - stdlib_ascii.fypp - stdlib_string_type.fypp - lapack/stdlib_lapack_base.fypp - lapack/stdlib_lapack_solve.fypp - lapack/stdlib_lapack_others.fypp - lapack/stdlib_lapack_orthogonal_factors.fypp - lapack/stdlib_lapack_eig_svd_lsq.fypp - lapack/stdlib_linalg_lapack_aux.fypp - lapack/stdlib_lapack_auxiliary.fypp - lapack/stdlib_lapack_blas_like_base.fypp - lapack/stdlib_lapack_blas_like_l1.fypp - lapack/stdlib_lapack_blas_like_l2.fypp - lapack/stdlib_lapack_blas_like_l3.fypp - lapack/stdlib_lapack_blas_like_mnorm.fypp - lapack/stdlib_lapack_blas_like_scalar.fypp - lapack/stdlib_lapack_cosine_sine.fypp - lapack/stdlib_lapack_cosine_sine2.fypp - lapack/stdlib_lapack_eigv_comp.fypp - lapack/stdlib_lapack_eigv_comp2.fypp - lapack/stdlib_lapack_eigv_gen.fypp - lapack/stdlib_lapack_eigv_gen2.fypp - lapack/stdlib_lapack_eigv_gen3.fypp - lapack/stdlib_lapack_eigv_std_driver.fypp - lapack/stdlib_lapack_eigv_svd_bidiag_dc.fypp - lapack/stdlib_lapack_eigv_svd_drivers.fypp - lapack/stdlib_lapack_eigv_svd_drivers2.fypp - lapack/stdlib_lapack_eigv_svd_drivers3.fypp - lapack/stdlib_lapack_eigv_sym_comp.fypp - lapack/stdlib_lapack_eigv_sym.fypp - lapack/stdlib_lapack_eigv_tridiag.fypp - lapack/stdlib_lapack_eigv_tridiag2.fypp - lapack/stdlib_lapack_eigv_tridiag3.fypp - lapack/stdlib_lapack_givens_jacobi_rot.fypp - lapack/stdlib_lapack_householder_reflectors.fypp - lapack/stdlib_lapack_lsq.fypp - lapack/stdlib_lapack_lsq_aux.fypp - lapack/stdlib_lapack_lsq_constrained.fypp - lapack/stdlib_lapack_orthogonal_factors_ql.fypp - lapack/stdlib_lapack_orthogonal_factors_qr.fypp - lapack/stdlib_lapack_orthogonal_factors_rz.fypp - lapack/stdlib_lapack_others_sm.fypp - lapack/stdlib_lapack_solve_aux.fypp - lapack/stdlib_lapack_solve_chol_comp.fypp - lapack/stdlib_lapack_solve_chol.fypp - lapack/stdlib_lapack_solve_ldl_comp.fypp - lapack/stdlib_lapack_solve_ldl_comp2.fypp - lapack/stdlib_lapack_solve_ldl_comp3.fypp - lapack/stdlib_lapack_solve_ldl_comp4.fypp - lapack/stdlib_lapack_solve_ldl.fypp - lapack/stdlib_lapack_solve_lu_comp.fypp - lapack/stdlib_lapack_solve_lu.fypp - lapack/stdlib_lapack_solve_tri_comp.fypp - lapack/stdlib_lapack_svd_bidiag_qr.fypp - lapack/stdlib_lapack_svd_comp.fypp - lapack/stdlib_lapack_svd_comp2.fypp -) -set(lapack_cppFiles - stdlib_linalg_constants.fypp - stdlib_linalg_lapack.fypp -) -set(lapack_f90Files - $,f18estop.f90,f08estop.f90> -) - -configure_stdlib_target(lapack lapack_f90Files lapack_fppFiles lapack_cppFiles) - -if(LAPACK_FOUND) - target_link_libraries(lapack PUBLIC "LAPACK::LAPACK") -endif() -target_link_libraries(lapack PUBLIC blas) +add_subdirectory(blas) +add_subdirectory(lapack) set(fppFiles stdlib_ascii.fypp diff --git a/src/blas/CMakeLists.txt b/src/blas/CMakeLists.txt new file mode 100644 index 000000000..6b4f4b048 --- /dev/null +++ b/src/blas/CMakeLists.txt @@ -0,0 +1,25 @@ +set(blas_fppFiles + ../stdlib_kinds.fypp + stdlib_blas_constants.fypp + stdlib_blas.fypp + stdlib_blas_level1.fypp + stdlib_blas_level2_ban.fypp + stdlib_blas_level2_gen.fypp + stdlib_blas_level2_pac.fypp + stdlib_blas_level2_sym.fypp + stdlib_blas_level2_tri.fypp + stdlib_blas_level3_gen.fypp + stdlib_blas_level3_sym.fypp + stdlib_blas_level3_tri.fypp + stdlib_linalg_blas_aux.fypp +) +set(blas_cppFiles + ../stdlib_linalg_constants.fypp + ../stdlib_linalg_blas.fypp +) + +configure_stdlib_target(blas "" blas_fppFiles blas_cppFiles) + +if(BLAS_FOUND) + target_link_libraries(blas PUBLIC "BLAS::BLAS") +endif() diff --git a/src/lapack/CMakeLists.txt b/src/lapack/CMakeLists.txt new file mode 100644 index 000000000..c988164c0 --- /dev/null +++ b/src/lapack/CMakeLists.txt @@ -0,0 +1,77 @@ + +set(lapack_fppFiles + ../stdlib_kinds.fypp + ../stdlib_linalg_state.fypp + ../stdlib_error.fypp + ../stdlib_optval.fypp + ../stdlib_io.fypp + ../stdlib_ascii.fypp + ../stdlib_string_type.fypp + stdlib_lapack_base.fypp + stdlib_lapack_solve.fypp + stdlib_lapack_others.fypp + stdlib_lapack_orthogonal_factors.fypp + stdlib_lapack_eig_svd_lsq.fypp + stdlib_linalg_lapack_aux.fypp + stdlib_lapack_auxiliary.fypp + stdlib_lapack_blas_like_base.fypp + stdlib_lapack_blas_like_l1.fypp + stdlib_lapack_blas_like_l2.fypp + stdlib_lapack_blas_like_l3.fypp + stdlib_lapack_blas_like_mnorm.fypp + stdlib_lapack_blas_like_scalar.fypp + stdlib_lapack_cosine_sine.fypp + stdlib_lapack_cosine_sine2.fypp + stdlib_lapack_eigv_comp.fypp + stdlib_lapack_eigv_comp2.fypp + stdlib_lapack_eigv_gen.fypp + stdlib_lapack_eigv_gen2.fypp + stdlib_lapack_eigv_gen3.fypp + stdlib_lapack_eigv_std_driver.fypp + stdlib_lapack_eigv_svd_bidiag_dc.fypp + stdlib_lapack_eigv_svd_drivers.fypp + stdlib_lapack_eigv_svd_drivers2.fypp + stdlib_lapack_eigv_svd_drivers3.fypp + stdlib_lapack_eigv_sym_comp.fypp + stdlib_lapack_eigv_sym.fypp + stdlib_lapack_eigv_tridiag.fypp + stdlib_lapack_eigv_tridiag2.fypp + stdlib_lapack_eigv_tridiag3.fypp + stdlib_lapack_givens_jacobi_rot.fypp + stdlib_lapack_householder_reflectors.fypp + stdlib_lapack_lsq.fypp + stdlib_lapack_lsq_aux.fypp + stdlib_lapack_lsq_constrained.fypp + stdlib_lapack_orthogonal_factors_ql.fypp + stdlib_lapack_orthogonal_factors_qr.fypp + stdlib_lapack_orthogonal_factors_rz.fypp + stdlib_lapack_others_sm.fypp + stdlib_lapack_solve_aux.fypp + stdlib_lapack_solve_chol_comp.fypp + stdlib_lapack_solve_chol.fypp + stdlib_lapack_solve_ldl_comp.fypp + stdlib_lapack_solve_ldl_comp2.fypp + stdlib_lapack_solve_ldl_comp3.fypp + stdlib_lapack_solve_ldl_comp4.fypp + stdlib_lapack_solve_ldl.fypp + stdlib_lapack_solve_lu_comp.fypp + stdlib_lapack_solve_lu.fypp + stdlib_lapack_solve_tri_comp.fypp + stdlib_lapack_svd_bidiag_qr.fypp + stdlib_lapack_svd_comp.fypp + stdlib_lapack_svd_comp2.fypp +) +set(lapack_cppFiles + ../stdlib_linalg_constants.fypp + ../stdlib_linalg_lapack.fypp +) +set(lapack_f90Files + $,../f18estop.f90,../f08estop.f90> +) + +configure_stdlib_target(lapack lapack_f90Files lapack_fppFiles lapack_cppFiles) + +if(LAPACK_FOUND) + target_link_libraries(lapack PUBLIC "LAPACK::LAPACK") +endif() +target_link_libraries(lapack PUBLIC blas) From 08b2ea95af11a8dd12f86068f0f1e4b1d73c5fe6 Mon Sep 17 00:00:00 2001 From: Eduard Date: Thu, 25 Sep 2025 14:06:25 +0200 Subject: [PATCH 5/5] iterative solvers in CMake --- src/CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 54b84bdd3..9280d3397 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -36,6 +36,9 @@ set(fppFiles stdlib_linalg_determinant.fypp stdlib_linalg_qr.fypp stdlib_linalg_inverse.fypp + stdlib_linalg_iterative_solvers.fypp + stdlib_linalg_iterative_solvers_cg.fypp + stdlib_linalg_iterative_solvers_pcg.fypp stdlib_linalg_pinv.fypp stdlib_linalg_norms.fypp stdlib_linalg_state.fypp