diff --git a/.github/workflows/fortran-build.yml b/.github/workflows/fortran-build.yml index c3aac5402..b49402e29 100644 --- a/.github/workflows/fortran-build.yml +++ b/.github/workflows/fortran-build.yml @@ -73,15 +73,15 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v3 - + uses: actions/checkout@v4 + - name: Setup Python uses: actions/setup-python@v4 with: python-version: 3.x - name: Install CMake - run: pip3 install ninja cmake==3.26.4 + run: pip3 install ninja cmake - name: Configure build run: cmake -B ${{ env.BUILD_DIR }} -G Ninja @@ -157,7 +157,7 @@ jobs: python-version: 3.x - name: Install CMake - run: pip3 install ninja cmake==3.26.4 + run: pip3 install ninja cmake - name: Configure build run: cmake -B ${{ env.BUILD_DIR }} -DWITH_CPCMX=false -DWITH_TBLITE=false -G Ninja diff --git a/CMakeLists.txt b/CMakeLists.txt index d1c1d8a93..da67f5bb2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,22 +14,31 @@ # You should have received a copy of the GNU Lesser General Public License # along with xtb. If not, see . -cmake_minimum_required(VERSION 3.9) +cmake_minimum_required(VERSION 3.17) +option(WITH_OBJECT "To build using object library" TRUE) -# Setup the XTB Project +# Buggy CMake versions +if (CMAKE_VERSION VERSION_GREATER_EQUAL 3.27.0) + set(WITH_OBJECT FALSE) +endif() + +# Setup the xtb Project project( "xtb" - VERSION "6.6.1" + VERSION "6.6.1" LANGUAGES "C" "Fortran" ) + enable_testing() # Follow GNU conventions for installing directories include(GNUInstallDirs) + # Include CMake specific configurations add_subdirectory("cmake") +# Check a specific CMake targets for xtb build & execute corresponding Find scripts if(NOT TARGET "mctc-lib::mctc-lib") find_package("mctc-lib" REQUIRED) endif() @@ -50,77 +59,107 @@ endif() set(prog) set(srcs) +# add filenames to the list variables add_subdirectory("src") add_subdirectory("symmetry") -# Find dependencies + +# CMake modules for third-party software if(NOT TARGET "OpenMP::OpenMP_Fortran" AND WITH_OpenMP) find_package("OpenMP" REQUIRED) endif() find_package("LAPACK" REQUIRED) find_package("BLAS" REQUIRED) -# Object library + if(NOT EXISTS "${PROJECT_BINARY_DIR}/include") - file(MAKE_DIRECTORY "${PROJECT_BINARY_DIR}/include") + file(MAKE_DIRECTORY "${PROJECT_BINARY_DIR}/include") endif() -add_library( - "${PROJECT_NAME}-object" - OBJECT - ${srcs} -) -set_target_properties( - "${PROJECT_NAME}-object" - PROPERTIES - Fortran_MODULE_DIRECTORY "${PROJECT_BINARY_DIR}/include" - POSITION_INDEPENDENT_CODE ON -) -target_link_libraries( - "${PROJECT_NAME}-object" - PUBLIC - "mctc-lib::mctc-lib" - "$<$:cpcmx::cpcmx>" - "$<$:tblite::tblite>" - "$<$:OpenMP::OpenMP_Fortran>" -) -target_include_directories( - "${PROJECT_NAME}-object" - PUBLIC - ${xtb-config-dir} - ${PROJECT_BINARY_DIR} - $ - $ - $/${CMAKE_INSTALL_INCLUDEDIR}> -) -target_compile_definitions( - "${PROJECT_NAME}-object" - PRIVATE -) -# Static Library -add_library( - "lib-${PROJECT_NAME}-static" - STATIC - $ -) +################## +# OBJECT LIBRARY # +################## +if(WITH_OBJECT) + + add_library( + "${PROJECT_NAME}-object" + OBJECT + ${srcs} + ) + + + # customize object library + set_target_properties( + "${PROJECT_NAME}-object" + PROPERTIES + Fortran_MODULE_DIRECTORY "${PROJECT_BINARY_DIR}/include" + POSITION_INDEPENDENT_CODE ON + ) + + # link object library against mctc-lib & + # & conditionally against OpenMP, tblite, cpcmx + target_link_libraries( + "${PROJECT_NAME}-object" + PUBLIC + "mctc-lib::mctc-lib" + "$<$:cpcmx::cpcmx>" + "$<$:tblite::tblite>" + "$<$:OpenMP::OpenMP_Fortran>" + ) + + # include directories + target_include_directories( + "${PROJECT_NAME}-object" + PUBLIC + ${xtb-config-dir} + ${PROJECT_BINARY_DIR} + $ + $ + $/${CMAKE_INSTALL_INCLUDEDIR}> + ) + +endif() + +################## +# Static Library # +################## +if(WITH_OBJECT) + add_library( + "lib-${PROJECT_NAME}-static" + STATIC + $ + ) +else() + add_library( + "lib-${PROJECT_NAME}-static" + STATIC + ${srcs} + ) +endif() + + target_link_libraries( - "lib-${PROJECT_NAME}-static" - PUBLIC - ${BLAS_LIBRARIES} - ${LAPACK_LIBRARIES} - "$<$:OpenMP::OpenMP_Fortran>" - "mctc-lib::mctc-lib" - "$<$:cpcmx::cpcmx>" - "$<$:tblite::tblite>" -) -set_target_properties( - "lib-${PROJECT_NAME}-static" - PROPERTIES - Fortran_MODULE_DIRECTORY "${PROJECT_BINARY_DIR}/include" - ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}" - POSITION_INDEPENDENT_CODE ON - OUTPUT_NAME "${PROJECT_NAME}" + "lib-${PROJECT_NAME}-static" + PUBLIC + ${BLAS_LIBRARIES} + ${LAPACK_LIBRARIES} + "$<$:OpenMP::OpenMP_Fortran>" + "mctc-lib::mctc-lib" + "$<$:cpcmx::cpcmx>" + "$<$:tblite::tblite>" ) + + + set_target_properties( + "lib-${PROJECT_NAME}-static" + PROPERTIES + Fortran_MODULE_DIRECTORY "${PROJECT_BINARY_DIR}/include" + ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}" + POSITION_INDEPENDENT_CODE ON + OUTPUT_NAME "${PROJECT_NAME}" + ) + + target_include_directories( "lib-${PROJECT_NAME}-static" PUBLIC @@ -129,48 +168,60 @@ target_include_directories( $/${CMAKE_INSTALL_INCLUDEDIR}> ) -# Shared Library -add_library( - "lib-${PROJECT_NAME}-shared" - SHARED - $ -) -target_link_libraries( - "lib-${PROJECT_NAME}-shared" - PUBLIC - ${BLAS_LIBRARIES} - ${LAPACK_LIBRARIES} - "$<$:OpenMP::OpenMP_Fortran>" - "mctc-lib::mctc-lib" - "$<$:cpcmx::cpcmx>" - "$<$:tblite::tblite>" -) -set_target_properties( - "lib-${PROJECT_NAME}-shared" - PROPERTIES - Fortran_MODULE_DIRECTORY "${PROJECT_BINARY_DIR}/include" - LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}" - OUTPUT_NAME "${PROJECT_NAME}" - VERSION "${PROJECT_VERSION}" - SOVERSION "${PROJECT_VERSION_MAJOR}" -) -target_include_directories( - "lib-${PROJECT_NAME}-shared" - PUBLIC - $ - $ - $/${CMAKE_INSTALL_INCLUDEDIR}> -) -# Executables +################## +# Shared Library # +################## +if (WITH_OBJECT) + add_library( + "lib-${PROJECT_NAME}-shared" + SHARED + $ + ) + + target_link_libraries( + "lib-${PROJECT_NAME}-shared" + PUBLIC + ${BLAS_LIBRARIES} + ${LAPACK_LIBRARIES} + "$<$:OpenMP::OpenMP_Fortran>" + "mctc-lib::mctc-lib" + "$<$:cpcmx::cpcmx>" + "$<$:tblite::tblite>" + ) + + set_target_properties( + "lib-${PROJECT_NAME}-shared" + PROPERTIES + Fortran_MODULE_DIRECTORY "${PROJECT_BINARY_DIR}/include" + LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}" + OUTPUT_NAME "${PROJECT_NAME}" + VERSION "${PROJECT_VERSION}" + SOVERSION "${PROJECT_VERSION_MAJOR}" + ) + + target_include_directories( + "lib-${PROJECT_NAME}-shared" + PUBLIC + $ + $ + $/${CMAKE_INSTALL_INCLUDEDIR}> + ) +endif() + +############### +# Executables # +############### + add_executable( - "${PROJECT_NAME}-exe" + ${PROJECT_NAME}-exe ${prog} ) + target_link_libraries( - "${PROJECT_NAME}-exe" - PRIVATE - "lib-${PROJECT_NAME}-static" + ${PROJECT_NAME}-exe + PRIVATE + "lib-${PROJECT_NAME}-static" ) set_target_properties( ${PROJECT_NAME}-exe @@ -179,51 +230,80 @@ set_target_properties( RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR} OUTPUT_NAME "${PROJECT_NAME}" ) -target_include_directories(${PROJECT_NAME}-exe PRIVATE "${PROJECT_SOURCE_DIR}/include") -# Install -install( - FILES - "${PROJECT_SOURCE_DIR}/include/xtb.h" - DESTINATION - "${CMAKE_INSTALL_INCLUDEDIR}" +target_include_directories( + ${PROJECT_NAME}-exe + PRIVATE + ${PROJECT_SOURCE_DIR}/include + $ ) + +###################### +# Installation rules # +###################### +# API for C/C++ install( - FILES - "${PROJECT_SOURCE_DIR}/param_gfn0-xtb.txt" - "${PROJECT_SOURCE_DIR}/param_gfn1-xtb.txt" - "${PROJECT_SOURCE_DIR}/param_gfn1-si-xtb.txt" - "${PROJECT_SOURCE_DIR}/param_gfn2-xtb.txt" - "${PROJECT_SOURCE_DIR}/param_ipea-xtb.txt" - "${PROJECT_SOURCE_DIR}/.param_gfnff.xtb" - DESTINATION - "${CMAKE_INSTALL_DATADIR}/${PROJECT_NAME}" + FILES + "${PROJECT_SOURCE_DIR}/include/xtb.h" + DESTINATION + "${CMAKE_INSTALL_INCLUDEDIR}" ) + +# xtb-parameters install( - TARGETS - "lib-${PROJECT_NAME}-static" - "lib-${PROJECT_NAME}-shared" - "${PROJECT_NAME}-exe" - EXPORT "${PROJECT_NAME}-targets" - LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" - ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" - RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" - INCLUDES DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" + FILES + "${PROJECT_SOURCE_DIR}/param_gfn0-xtb.txt" + "${PROJECT_SOURCE_DIR}/param_gfn1-xtb.txt" + "${PROJECT_SOURCE_DIR}/param_gfn1-si-xtb.txt" + "${PROJECT_SOURCE_DIR}/param_gfn2-xtb.txt" + "${PROJECT_SOURCE_DIR}/param_ipea-xtb.txt" + "${PROJECT_SOURCE_DIR}/.param_gfnff.xtb" + DESTINATION + "${CMAKE_INSTALL_DATADIR}/${PROJECT_NAME}" ) + +# Build output artifacts +if (WITH_OBJECT) + install( + TARGETS + "lib-${PROJECT_NAME}-static" + "lib-${PROJECT_NAME}-shared" + "${PROJECT_NAME}-exe" + EXPORT "${PROJECT_NAME}-targets" + LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" + ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" + RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" + INCLUDES DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" + ) +else() + install( + TARGETS + "lib-${PROJECT_NAME}-static" + "${PROJECT_NAME}-exe" + EXPORT "${PROJECT_NAME}-targets" + ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" + RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" + INCLUDES DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" + ) +endif() + # CMake package files include(CMakePackageConfigHelpers) + # -- Config version file write_basic_package_version_file( "${PROJECT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake" VERSION "${PROJECT_VERSION}" COMPATIBILITY AnyNewerVersion ) + # -- Config file configure_package_config_file( "${PROJECT_SOURCE_DIR}/cmake/config.cmake.in" "${PROJECT_BINARY_DIR}/${PROJECT_NAME}-config.cmake" INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}" ) + # -- Install config and configVersion install( FILES @@ -231,17 +311,20 @@ install( "${PROJECT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake" DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}" ) + # -- Targets file # -- This makes the project importable from the build directory export( - EXPORT "${PROJECT_NAME}-targets" - FILE "${PROJECT_BINARY_DIR}/${PROJECT_NAME}-targets.cmake" + EXPORT "${PROJECT_NAME}-targets" + FILE "${PROJECT_BINARY_DIR}/${PROJECT_NAME}-targets.cmake" ) + # -- This makes the project importable from the install directory install( - EXPORT "${PROJECT_NAME}-targets" - FILE "${PROJECT_NAME}-targets.cmake" - DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}" + EXPORT "${PROJECT_NAME}-targets" + FILE "${PROJECT_NAME}-targets.cmake" + DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}" ) - + +# Tests add_subdirectory("test") diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index cc9b9fd2f..9a48db34f 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -14,21 +14,11 @@ # You should have received a copy of the Lesser GNU General Public License # along with xtb. If not, see . +# Some user-configurable features option(WITH_OpenMP "Enable support for shared memory parallelisation with OpenMP" TRUE) option(WITH_TBLITE "Use tblite library as backend for xTB" TRUE) option(WITH_CPCMX "Use CPCM-X solvation library for xTB" TRUE) -if(NOT DEFINED "${PROJECT_NAME}-dependeny-method") - set( - "${PROJECT_NAME}-dependency-method" - "subproject" "cmake" "pkgconf" "fetch" - ) -endif() -set( - module-dir - "${PROJECT_NAME}/${CMAKE_Fortran_COMPILER_ID}-${CMAKE_Fortran_COMPILER_VERSION}" -) -set(module-dir "${module-dir}" PARENT_SCOPE) # Set build type as CMake does not provide defaults if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) @@ -43,29 +33,34 @@ if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) ) endif() +# Add modules to the CMake build list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/modules") set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH}" PARENT_SCOPE) + +# specify module installation directory install( DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/modules/" DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}" ) +# Compiler-specific configurations if(CMAKE_Fortran_COMPILER_ID MATCHES "GNU") - set(dialect "-fdefault-real-8 -fdefault-double-8 -ffree-line-length-none -fbacktrace") - set(bounds "-fbounds-check") -endif() -if(CMAKE_Fortran_COMPILER_ID MATCHES "Intel") - set(dialect "-axAVX2 -r8 -traceback") - set(bounds "-check bounds") -endif() -if(CMAKE_Fortran_COMPILER_ID MATCHES "PGI") - set(dialect "-Mbackslash -Mallocatable=03 -r8 -traceback") + set(dialects "-fdefault-real-8 -fdefault-double-8 -ffree-line-length-none -fbacktrace") + set(bounds "-fbounds-check -ffpe-trap=invalid,zero,overflow") +elseif(CMAKE_Fortran_COMPILER_ID MATCHES "Intel") + set(dialects "-axAVX2 -r8 -traceback") + set(bounds "-check all -fpe0") +elseif(CMAKE_Fortran_COMPILER_ID MATCHES "PGI") + set(dialects "-Mbackslash -Mallocatable=03 -r8 -traceback") endif() + +# Customize compiler flags set(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG} ${bounds}" PARENT_SCOPE) -set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} ${dialect}" PARENT_SCOPE) +set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} ${dialects}" PARENT_SCOPE) + -# Populate xtb_version.fh +# Populate xtb_version.fh with metadata set(version ${PROJECT_VERSION}) execute_process(COMMAND git rev-parse HEAD RESULT_VARIABLE git_return @@ -75,11 +70,11 @@ if(git_return) else() string(REGEX REPLACE "\n$" "" commit ${commit}) endif() -string(TIMESTAMP date "%m/%d/%Y") +string(TIMESTAMP date "%Y/%m/%d") set(author $ENV{USERNAME}) set(origin ${CMAKE_HOST_SYSTEM_NAME}) configure_file( "${PROJECT_SOURCE_DIR}/assets/templates/version.f90" - "${PROJECT_BINARY_DIR}/xtb_version.fh" + "${PROJECT_BINARY_DIR}/include/xtb_version.fh" @ONLY ) diff --git a/cmake/modules/Findcpcmx.cmake b/cmake/modules/Findcpcmx.cmake index a39328a73..7fba27a97 100644 --- a/cmake/modules/Findcpcmx.cmake +++ b/cmake/modules/Findcpcmx.cmake @@ -70,22 +70,13 @@ set(_pkg "cpcmx") set(_url "https://github.com/grimme-lab/CPCM-X") if(NOT DEFINED "${_pkg}_FIND_METHOD") - if(DEFINED "${PROJECT_NAME}-dependency-method") - set("${_pkg}_FIND_METHOD" "${${PROJECT_NAME}-dependency-method}") - else() - set("${_pkg}_FIND_METHOD" "cmake" "pkgconf" "subproject" "fetch") - endif() - set("_${_pkg}_FIND_METHOD") + set("${_pkg}_FIND_METHOD" "cmake" "pkgconf" "subproject" "fetch") endif() include("${CMAKE_CURRENT_LIST_DIR}/xtb-utils.cmake") xtb_find_package("${_lib}" "${${_pkg}_FIND_METHOD}" "${_url}") -if(DEFINED "_${_pkg}_FIND_METHOD") - unset("${_pkg}_FIND_METHOD") - unset("_${_pkg}_FIND_METHOD") -endif() unset(_lib) unset(_pkg) unset(_url) diff --git a/cmake/modules/Findmctc-lib.cmake b/cmake/modules/Findmctc-lib.cmake index 83c60aaf7..670e509c6 100644 --- a/cmake/modules/Findmctc-lib.cmake +++ b/cmake/modules/Findmctc-lib.cmake @@ -19,22 +19,13 @@ set(_pkg "MCTCLIB") set(_url "https://github.com/grimme-lab/mctc-lib") if(NOT DEFINED "${_pkg}_FIND_METHOD") - if(DEFINED "${PROJECT_NAME}-dependency-method") - set("${_pkg}_FIND_METHOD" "${${PROJECT_NAME}-dependency-method}") - else() - set("${_pkg}_FIND_METHOD" "cmake" "pkgconf" "subproject" "fetch") - endif() - set("_${_pkg}_FIND_METHOD") + set("${_pkg}_FIND_METHOD" "cmake" "pkgconf" "subproject" "fetch") endif() include("${CMAKE_CURRENT_LIST_DIR}/xtb-utils.cmake") xtb_find_package("${_lib}" "${${_pkg}_FIND_METHOD}" "${_url}") -if(DEFINED "_${_pkg}_FIND_METHOD") - unset("${_pkg}_FIND_METHOD") - unset("_${_pkg}_FIND_METHOD") -endif() unset(_lib) unset(_pkg) unset(_url) diff --git a/cmake/modules/Findtblite.cmake b/cmake/modules/Findtblite.cmake index f4dbbd7b2..ccaa7cc96 100644 --- a/cmake/modules/Findtblite.cmake +++ b/cmake/modules/Findtblite.cmake @@ -19,22 +19,14 @@ set(_pkg "TBLITE") set(_url "https://github.com/tblite/tblite") if(NOT DEFINED "${_pkg}_FIND_METHOD") - if(DEFINED "${PROJECT_NAME}-dependency-method") - set("${_pkg}_FIND_METHOD" "${${PROJECT_NAME}-dependency-method}") - else() - set("${_pkg}_FIND_METHOD" "cmake" "pkgconf" "subproject" "fetch") - endif() - set("_${_pkg}_FIND_METHOD") + set("${_pkg}_FIND_METHOD" "cmake" "pkgconf" "subproject" "fetch") + set("_${_pkg}_FIND_METHOD") endif() include("${CMAKE_CURRENT_LIST_DIR}/xtb-utils.cmake") xtb_find_package("${_lib}" "${${_pkg}_FIND_METHOD}" "${_url}") -if(DEFINED "_${_pkg}_FIND_METHOD") - unset("${_pkg}_FIND_METHOD") - unset("_${_pkg}_FIND_METHOD") -endif() unset(_lib) unset(_pkg) unset(_url) diff --git a/cmake/modules/Findtest-drive.cmake b/cmake/modules/Findtest-drive.cmake index 491e625ee..5c49137e9 100644 --- a/cmake/modules/Findtest-drive.cmake +++ b/cmake/modules/Findtest-drive.cmake @@ -70,22 +70,14 @@ set(_pkg "TEST_DRIVE") set(_url "https://github.com/fortran-lang/test-drive") if(NOT DEFINED "${_pkg}_FIND_METHOD") - if(DEFINED "${PROJECT_NAME}-dependency-method") - set("${_pkg}_FIND_METHOD" "${${PROJECT_NAME}-dependency-method}") - else() - set("${_pkg}_FIND_METHOD" "cmake" "pkgconf" "subproject" "fetch") - endif() - set("_${_pkg}_FIND_METHOD") + set("${_pkg}_FIND_METHOD" "cmake" "pkgconf" "subproject" "fetch") + set("_${_pkg}_FIND_METHOD") endif() include("${CMAKE_CURRENT_LIST_DIR}/xtb-utils.cmake") xtb_find_package("${_lib}" "${${_pkg}_FIND_METHOD}" "${_url}") -if(DEFINED "_${_pkg}_FIND_METHOD") - unset("${_pkg}_FIND_METHOD") - unset("_${_pkg}_FIND_METHOD") -endif() unset(_lib) unset(_pkg) unset(_url) diff --git a/cmake/modules/xtb-utils.cmake b/cmake/modules/xtb-utils.cmake index 3b0604886..7c510fa34 100644 --- a/cmake/modules/xtb-utils.cmake +++ b/cmake/modules/xtb-utils.cmake @@ -16,124 +16,113 @@ # Handling of subproject dependencies macro( - "xtb_find_package" - package - methods - url + "xtb_find_package" + package + methods + url ) - string(TOLOWER "${package}" _pkg_lc) - string(TOUPPER "${package}" _pkg_uc) +string(TOLOWER "${package}" _pkg_lc) +string(TOUPPER "${package}" _pkg_uc) - foreach(method ${methods}) +# iterate through all methods +foreach(method ${methods}) - if(TARGET "${package}::${package}") + if(TARGET "${package}::${package}") break() - endif() + endif() - if("${method}" STREQUAL "cmake") + # cmake case + if("${method}" STREQUAL "cmake") if(DEFINED "${_pkg_uc}_DIR") - set("_${_pkg_uc}_DIR") - set("${package}_DIR" "${_pkg_uc}_DIR") + set("_${_pkg_uc}_DIR") + set("${package}_DIR" "${_pkg_uc}_DIR") endif() - find_package("${package}" CONFIG) + find_package("${package}" CONFIG QUIET) if("${package}_FOUND") - message(STATUS "Found ${package} via CMake config") - break() + message(STATUS "Found ${package} via CMake config") + break() endif() - endif() - if("${method}" STREQUAL "pkgconf") - find_package(PkgConfig QUIET) - pkg_check_modules("${_pkg_uc}" QUIET "${package}") + # pkgconf case + elseif("${method}" STREQUAL "pkgconf") + find_package("PkgConfig" QUIET) # built-in Find script + pkg_check_modules("${_pkg_uc}" QUIET "${package}") # check if it is a pkg-config module if("${_pkg_uc}_FOUND") - message(STATUS "Found ${package} via pkg-config") - - add_library("${package}::${package}" INTERFACE IMPORTED) - target_link_libraries( - "${package}::${package}" - INTERFACE - "${${_pkg_uc}_LINK_LIBRARIES}" - ) - target_include_directories( - "${package}::${package}" - INTERFACE - "${${_pkg_uc}_INCLUDE_DIRS}" - ) - break() + message(STATUS "Found ${package} via pkg-config") + add_library("${package}::${package}" INTERFACE IMPORTED) # interface library + target_link_libraries( + "${package}::${package}" + INTERFACE + "${${_pkg_uc}_LINK_LIBRARIES}" + ) + target_include_directories( + "${package}::${package}" + INTERFACE + "${${_pkg_uc}_INCLUDE_DIRS}" + ) + break() endif() - endif() - if("${method}" STREQUAL "subproject") + # subproject case + elseif("${method}" STREQUAL "subproject") if(NOT DEFINED "${_pkg_uc}_SUBPROJECT") - set("_${_pkg_uc}_SUBPROJECT") - set("${_pkg_uc}_SUBPROJECT" "subprojects/${package}") + set("${_pkg_uc}_SUBPROJECT" "subprojects/${package}") endif() set("${_pkg_uc}_SOURCE_DIR" "${PROJECT_SOURCE_DIR}/${${_pkg_uc}_SUBPROJECT}") set("${_pkg_uc}_BINARY_DIR" "${PROJECT_BINARY_DIR}/${${_pkg_uc}_SUBPROJECT}") + + # if can be configured from the subprojects dir if(EXISTS "${${_pkg_uc}_SOURCE_DIR}/CMakeLists.txt") - message(STATUS "Include ${package} from ${${_pkg_uc}_SUBPROJECT}") - add_subdirectory( - "${${_pkg_uc}_SOURCE_DIR}" - "${${_pkg_uc}_BINARY_DIR}" - ) - - add_library("${package}::${package}" INTERFACE IMPORTED) - target_link_libraries("${package}::${package}" INTERFACE "${package}") - - # We need the module directory in the subproject before we finish the configure stage - if(NOT EXISTS "${${_pkg_uc}_BINARY_DIR}/include") - file(MAKE_DIRECTORY "${${_pkg_uc}_BINARY_DIR}/include") - endif() - - break() + message(STATUS "Include ${package} from ${${_pkg_uc}_SUBPROJECT}") + + add_subdirectory( + "${${_pkg_uc}_SOURCE_DIR}" + "${${_pkg_uc}_BINARY_DIR}" + ) + + # create interface directory and manage it's dependencies + add_library("${package}::${package}" INTERFACE IMPORTED) + target_link_libraries("${package}::${package}" INTERFACE "${package}") + + # We need the module directory in the subproject before we finish the configure stage + if(NOT EXISTS "${${_pkg_uc}_BINARY_DIR}/include") + file(MAKE_DIRECTORY "${${_pkg_uc}_BINARY_DIR}/include") + endif() + + break() endif() - endif() - if("${method}" STREQUAL "fetch") + # fetch from url case + elseif("${method}" STREQUAL "fetch") message(STATUS "Retrieving ${package} from ${url}") - include(FetchContent) + include(FetchContent) # module for fetching from repo + if(CMAKE_BUILD_TYPE STREQUAL "Debug") + set(FETCHCONTENT_QUIET FALSE) + endif() FetchContent_Declare( - "${_pkg_lc}" - GIT_REPOSITORY "${url}" - GIT_TAG "HEAD" + "${_pkg_lc}" + GIT_REPOSITORY "${url}" + GIT_TAG "HEAD" ) FetchContent_MakeAvailable("${_pkg_lc}") - + add_library("${package}::${package}" INTERFACE IMPORTED) target_link_libraries("${package}::${package}" INTERFACE "${package}") - # We need the module directory in the subproject before we finish the configure stage - FetchContent_GetProperties("${_pkg_lc}" SOURCE_DIR "${_pkg_uc}_SOURCE_DIR") - FetchContent_GetProperties("${_pkg_lc}" BINARY_DIR "${_pkg_uc}_BINARY_DIR") - if(NOT EXISTS "${${_pkg_uc}_BINARY_DIR}/include") - file(MAKE_DIRECTORY "${${_pkg_uc}_BINARY_DIR}/include") + if(NOT EXISTS "${${_pkg_lc}_BINARY_DIR}/include") + file(MAKE_DIRECTORY "${${_pkg_lc}_BINARY_DIR}/include") endif() break() - endif() - - endforeach() - - if(TARGET "${package}::${package}") - set("${_pkg_uc}_FOUND" TRUE) - else() - set("${_pkg_uc}_FOUND" FALSE) - endif() + endif() - unset(_pkg_lc) - unset(_pkg_uc) +endforeach() - if(DEFINED "_${_pkg_uc}_SUBPROJECT") - unset("${_pkg_uc}_SUBPROJECT") - unset("_${_pkg_uc}_SUBPROJECT") - endif() - - if(DEFINED "_${_pkg_pc}_DIR") - unset("${package}_DIR") - unset("_${_pkg_pc}_DIR") - endif() +unset(_pkg_lc) +unset(_pkg_uc) - if(NOT TARGET "${package}::${package}") - message(FATAL_ERROR "Could not find dependency ${package}") - endif() +# sanity check +if(NOT TARGET "${package}::${package}") + message(FATAL_ERROR "Could not find dependency ${package}") +endif() endmacro() diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index bfc927bcf..31eca80c5 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -14,5 +14,8 @@ # You should have received a copy of the Lesser GNU General Public License # along with xtb. If not, see . -add_subdirectory("api") +iF (WITH_OBJECT) + add_subdirectory("api") +endif() + add_subdirectory("unit") diff --git a/test/unit/CMakeLists.txt b/test/unit/CMakeLists.txt index e925814e5..751c395c6 100644 --- a/test/unit/CMakeLists.txt +++ b/test/unit/CMakeLists.txt @@ -15,8 +15,10 @@ # You should have received a copy of the GNU Lesser General Public License # along with xtb. If not, see . +# allocate dir set(dir "${CMAKE_CURRENT_SOURCE_DIR}") +# collect source files set( tests "atomlist" @@ -46,35 +48,43 @@ set( "wsc" "cpx" ) + set( test-srcs "main.f90" "molstock.f90" ) + foreach(t IN LISTS tests) string(MAKE_C_IDENTIFIER ${t} t) list(APPEND test-srcs "test_${t}.f90") endforeach() + +# executable add_executable( "${PROJECT_NAME}-tester" "${test-srcs}" ) + target_link_libraries( "${PROJECT_NAME}-tester" PRIVATE - "lib-${PROJECT_NAME}-static" - "test-drive::test-drive" + "lib-${PROJECT_NAME}-static" # static xtb + "test-drive::test-drive" # testing framework ) + +if(NOT EXISTS "${CMAKE_CURRENT_BINARY_DIR}/include") + file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/include") +endif() + set_target_properties( "${PROJECT_NAME}-tester" PROPERTIES Fortran_MODULE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/include" ) -if(NOT EXISTS "${CMAKE_CURRENT_BINARY_DIR}/include") - file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/include") -endif() +# test-drive foreach(t IN LISTS tests) add_test("${PROJECT_NAME}/${t}" "${PROJECT_NAME}-tester" "${t}") set_tests_properties( @@ -84,7 +94,7 @@ foreach(t IN LISTS tests) ) endforeach() - +# xtb set(XTB-EXE "${PROJECT_BINARY_DIR}/${PROJECT_NAME}") add_test("xtb/Argparser_print_version" ${XTB-EXE} --version)