# Link in pre-compiled LSDalton static libraries

#  Copyright (C) 2017 The authors of Py-ChemShell
#
#  This file is part of Py-ChemShell.
#
#  Py-ChemShell is free software: you can redistribute it and/or modify
#  it under the terms of the GNU Lesser General Public License as
#  published by the Free Software Foundation, either version 3 of the
#  License, or (at your option) any later version.
#
#  Py-ChemShell is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU Lesser General Public License for more details.
#
#  You should have received a copy of the GNU Lesser General Public
#  License along with Py-ChemShell.  If not, see
#  <http://www.gnu.org/licenses/>.

# TWK Feb 2017 for LSDalton v1.2
# TWK Apr 2017: updated to match LSDalton release/1 branch
# TWK Nov 2021: updated to match LSDalton release/2020 branch

# YL Jan 2023: rewritten to make the procedure automated 

# YL 09/11/2021: since CMake 3.12 MPI_ROOT will be used for searching
#                see details by: cmake --help-policy CMP0074
# but seems not effective to the LSD5 CMake
if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.12")
    cmake_policy(SET CMP0074 NEW)
endif()
if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.24")
    cmake_policy(SET CMP0135 NEW)
endif()

# C++ compiler is mandatory
if("${CMAKE_CXX_COMPILER}" STREQUAL "" AND NOT "${LSDALTON}" STREQUAL "")
    message(FATAL_ERROR "ChemShell: Please specify a C++ compiler via --cpc for compiling LSDalton")
endif()

set(LSDALTON_DEFAULT_VERSION v2020.0)
set(LSDALTON_NAME lsdalton-2020)


# paths
file(MAKE_DIRECTORY ${CHEMSH_BUILD_DIR}/lib/lsdalton)
set(CHEMSH_LSDALTON_LIB_DIRECTORY ${CHEMSH_BUILD_DIR}/lib/lsdalton)
set(CMAKE_Fortran_MODULE_DIRECTORY ${CHEMSH_BUILD_DIR}/modules/lsdalton)
include_directories(${CHEMSH_BUILD_DIR}/modules
                    ${CHEMSH_BUILD_DIR}/modules/parallel
                    ${CHEMSH_BUILD_DIR}/modules/dl_py2f)

set(LSDALTON_BUILD_DIR ${LSDALTON})

# without LSDALTON
if("${LSDALTON}" STREQUAL "")
    # compile liblsdalton.so (containing only Py-ChemShell interface files and dummy LSDalton main routine)
    add_library(lsdalton SHARED lsdalton.f90 lsdalton_routines.f90 lsdalton_dummies.f90 ${NOTLINKED})
    target_link_libraries(lsdalton dl_py2f parallel)
    set_target_properties(lsdalton PROPERTIES LINK_FLAGS "${CHEMSH_LINK_FLAGS}")
    return()
endif()

if(NOT ${LSDALTON} STREQUAL "")
    get_filename_component(LSDALTON_ABSOLUTE ${LSDALTON} ABSOLUTE)
endif()

if(EXISTS ${LSDALTON_ABSOLUTE})
    # if is directory
    if(IS_DIRECTORY ${LSDALTON_ABSOLUTE})
        set(LSDALTON_DIR     ${LSDALTON_ABSOLUTE})
    # if file (tarball)
    else()
        set(LSDALTON_TARBALL  ${LSDALTON_ABSOLUTE})
        set(LSDALTON_DEST_DIR ${CMAKE_CURRENT_LIST_DIR}/${CHEMSH_ARCH}/src)
        set(LSDALTON_DIR      ${LSDALTON_DEST_DIR})
        # YL 02/10/2020: FetchContent is not available until CMake 3.11 (Ubuntu 18.04 comes with CMake 3.10 only)
        if(${CMAKE_VERSION} VERSION_LESS "3.11")
            include(${CHEMSH_DIR}/chemsh/utils/cmake/fetch_content.cmake)
        else()
            include(FetchContent)
        endif()
        FetchContent_Declare(
            lsdalton_source
            URL ${LSDALTON_TARBALL}
        )
        FetchContent_GetProperties(lsdalton_source)
        if(NOT lsdalton_source_POPULATED)
            FetchContent_Populate(
                lsdalton_source
                URL          ${LSDALTON_TARBALL}
                SOURCE_DIR   ${LSDALTON_DEST_DIR}
                BINARY_DIR   ${CMAKE_CURRENT_LIST_DIR}/${CHEMSH_ARCH}/build
                SUBBUILD_DIR ${CMAKE_CURRENT_LIST_DIR}/${CHEMSH_ARCH}/subbuild
            )
        endif()
    endif()
    set(LSDALTON_SRC_DIR ${LSDALTON_DIR})
    set(LSDALTON_GIT_REPO  "")

# Git
else()
    set(LSDALTON_GIT_REPO  "${LSDALTON}")
    set(LSDALTON_DIR       ${CMAKE_CURRENT_LIST_DIR}/${CHEMSH_ARCH})
    set(LSDALTON_SRC_DIR   ${CMAKE_CURRENT_LIST_DIR}/${CHEMSH_ARCH}/src)
endif()
set(LSDALTON_BUILD_DIR ${LSDALTON_SRC_DIR}/${CHEMSH_ARCH})

# YL 12/01/2023: LSDalton v2020 somehow does the testing at the configuration stage so that we must disable it by hacking
set(LSDALTON_CMAKE_DIR ${LSDALTON_SRC_DIR}/cmake/custom)
configure_file(hack.py.in hack.py @ONLY)

# debug
if(NOT DEBUG)
    set(LSD_CMAKE_FLAGS "-Wno-dev")
    set(LSD_CPP_EXTRA_FLAGS "-Wno-unused-but-set-variable")
endif()

# TWK 18/1/2024 Defaults for non-Cray environments
set(LSD_CRAY_WRAPPERS OFF)
set(LSD_AUTO_BLAS ON)
set(LSD_AUTO_LAPACK ON)

# determine if serial or parallel build required
if(WITH_MPI)
    message("${BoldWhite}LSDalton${EndColour} will be built with MPI support")

    # compile flag used below
    set(LSDALTON_MPI_MACRO "-DWITH_MPI")

    # ScaLAPACK
    set(LSD_SWITCH_SCALAPACK ON)

    # it MUST be a filename without directory (full path) specified to MPI_Fortran_COMPILER for LSDALTON, otherwise MPI_Fortran_INCLUDE_PATH goes wrong
    get_filename_component(LSD_MPI_Fortran_COMPILER ${CMAKE_Fortran_COMPILER} NAME)
# FIXME: this is a terrible solution as LSDALTON requires MPI_Fortran_COMPILER (e.g., mpiifort or mpifort.openmpi) and CMAKE_Fortran_COMPILER (e.g., ifort or gfortran) at the same time
    if(${CHEMSH_ARCH} STREQUAL "intel")
        set(LSD_BLACS_ARCH "intelmpi")
        set(LSD_Fortran_COMPILER "ifort")
        set(LSD_Fortran_FLAGS -fPIC)
        # YL: we temporarily ignore the missing symbols defined in ChemShell at this stage
        set(LSD_EXE_LINKER_FLAGS "-Wl,--unresolved-symbols=ignore-all -shared-intel")
    elseif(${CHEMSH_ARCH} STREQUAL "gnu")
        set(LSD_BLACS_ARCH "openmpi")
        set(LSD_Fortran_COMPILER "gfortran")
        if(${CMAKE_Fortran_COMPILER_VERSION} VERSION_GREATER_EQUAL "10.0")
            set(LSD_Fortran_FLAGS "-fPIC -std=legacy -fallow-argument-mismatch -Wno-all")
        else()
            set(LSD_Fortran_FLAGS "-fPIC -std=legacy -Wno-all")
        endif()
        set(LSD_CPP_FLAGS "-fPIC ${LSD_CPP_EXTRA_FLAGS}")
        set(LSD_EXE_LINKER_FLAGS "-Wl,--unresolved-symbols=ignore-all")
    # YL 18/11/2021: added for ARCHER2, otherwise LSD5 cannot find MPI (as always!)
    elseif(${CHEMSH_ARCH} STREQUAL "cpe-gnu")
	# TWK 18/1/2024 Settings for Cray wrapper compilers
        # These settings are equivalent to using LSDalton setup's --cray flag
	# Auto detection of BLAS and LAPACK must be switched off as it does not recognise Cray libsci
	set(LSD_CRAY_WRAPPERS ON)
	set(LSD_AUTO_BLAS OFF)
	set(LSD_AUTO_LAPACK OFF)
	# NB cpe-gnu does not actually use openmpi, but there is no Cray-specific setting
	# available in LSDalton release/2020, and LSDalton (inc. ScaLAPACK) will not compile if not set.
	set(LSD_BLACS_ARCH "openmpi")
        set(LSD_Fortran_COMPILER ${CMAKE_Fortran_COMPILER})
        if(${CMAKE_Fortran_COMPILER_VERSION} VERSION_GREATER_EQUAL "10.0")
            set(LSD_Fortran_FLAGS "-fPIC -std=legacy -fallow-argument-mismatch -Wno-all")
        else()
            set(LSD_Fortran_FLAGS "-fPIC -std=legacy -Wno-all")
        endif()
        set(LSD_CPP_FLAGS "-fPIC ${LSD_CPP_EXTRA_FLAGS}")
        string(REPLACE ";" " " LSD_MPI_LIBRARIES "${MPI_LIBRARIES}")
        # YL 22/12/2021: removed the flag for the ARCHER2 full system with CMake 3.21 otherwise LSDALTON tries to link with -l"-L/xxxx -lmpi" strangely
        if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.21")
        else()
            set(LSD_MPI_Fortran_LINK_FLAGS -DMPI_Fortran_LINK_FLAGS:STRING=-L${MPI_LIB_PATH} ${LSD_MPI_LIBRARIES})
        endif()
        set(LSD_EXE_LINKER_FLAGS "-Wl,--unresolved-symbols=ignore-all")
    endif()

    # YL 09/11/2021: -DNVIDIA to prevent LSD5 using compiler_version() which is F2008
    # YL 21/11/2021: removed -DNVIDIA which causes numerical error with GNU>=10.2
    set(LSDALTON_Fortran_FLAGS "-fPIC ${CMAKE_Fortran_FLAGS}")
    # the directory ${LSDALTON}:MUST be placed in the end, otherwise CMake goes crazy
    set(LSDALTON_CONFIGURE_COMMAND ${CMAKE_COMMAND} -DENABLE_MPI:BOOL=ON
                                                    -DENABLE_OMP:BOOL=ON
                                                    -DENABLE_64BIT_INTEGERS=OFF
                                                    -DENABLE_GPU=OFF
                                                    -DENABLE_CUBLAS=OFF
                                                    -DENABLE_CSR=OFF
                                                    -DENABLE_SCALASCA=OFF
                                                    -DENABLE_TIMINGS=OFF
                                                    -DENABLE_STATIC_LINKING=OFF
                                                    -DBLACS_IMPLEMENTATION:STRING=${LSD_BLACS_ARCH}
                                                    -DCMAKE_BUILD_TYPE=release
                                                    -DCMAKE_Fortran_COMPILER:STRING=${CMAKE_Fortran_COMPILER}
                                                    -DCMAKE_C_COMPILER:STRING=${CMAKE_C_COMPILER}
                                                    -DCMAKE_CXX_COMPILER:STRING=${CMAKE_CXX_COMPILER}
                                                    -DENABLE_CRAY_WRAPPERS:BOOL=${LSD_CRAY_WRAPPERS}
                                                    -DENABLE_AUTO_BLAS:BOOL=${LSD_AUTO_BLAS}
                                                    -DENABLE_AUTO_LAPACK:BOOL=${LSD_AUTO_LAPACK}
                                                    -DENABLE_SCALAPACK:BOOL=${LSD_SWITCH_SCALAPACK}
                                                    -DENABLE_CHEMSHELL:BOOL=ON
                                                    -DCMAKE_Fortran_FLAGS:STRING=${LSD_Fortran_FLAGS}
                                                    -DCMAKE_C_FLAGS:STRING=-fPIC
                                                    -DCMAKE_CXX_FLAGS:STRING=${LSD_CPP_FLAGS}
                                                    -DCMAKE_EXE_LINKER_FLAGS:STRING=${LSD_EXE_LINKER_FLAGS}
                                                    -DCMAKE_INSTALL_LIBDIR:PATH=lib
                                                    -DENABLE_LARGE_TEST:BOOL=OFF
                                                    -DBUILD_TESTING:BOOL=OFF
                                                    ${LSD_CMAKE_FLAGS}
                                                    ${LSDALTON_SRC_DIR})
else()

    message("${BoldWhite}${LSDALTON_NAME}${EndColour} library will be built without MPI support")

    if(${CHEMSH_ARCH} STREQUAL "intel")
        set(LSD_Fortran_FLAGS -fPIC)
    elseif(${CHEMSH_ARCH} STREQUAL "gnu")
        if(${CMAKE_Fortran_COMPILER_VERSION} VERSION_GREATER_EQUAL "10.0")
            set(LSD_Fortran_FLAGS "-fPIC -std=legacy -fallow-argument-mismatch -Wno-all")
        else()
            set(LSD_Fortran_FLAGS "-fPIC -std=legacy -Wno-all")
        endif()
        set(LSD_CPP_FLAGS "-fPIC ${LSD_CPP_EXTRA_FLAGS}")
    elseif(${CHEMSH_ARCH} STREQUAL "cpe-gnu")
        set(LSD_CRAY_WRAPPERS ON)
        set(LSD_AUTO_BLAS OFF)
        set(LSD_AUTO_LAPACK OFF)
        if(${CMAKE_Fortran_COMPILER_VERSION} VERSION_GREATER_EQUAL "10.0")
            set(LSD_Fortran_FLAGS "-fPIC -std=legacy -fallow-argument-mismatch -Wno-all")
        else()
            set(LSD_Fortran_FLAGS "-fPIC -std=legacy -Wno-all")
        endif()
        set(LSD_CPP_FLAGS "-fPIC ${LSD_CPP_EXTRA_FLAGS}")
    endif()
    # YL 09/11/2021: -DNVIDIA to prevent LSD5 using compiler_version() which is F2008
    # YL 21/11/2021: removed -DNVIDIA which causes numerical error with GNU>=10.2
    set(LSDALTON_MPI_MACRO "-UWITH_MPI")
    set(LSDALTON_Fortran_FLAGS "-fPIC ${CMAKE_Fortran_FLAGS}")

    set(LSDALTON_CONFIGURE_COMMAND ${CMAKE_COMMAND} -DENABLE_MPI:BOOL=OFF
                                                    -DENABLE_OMP:BOOL=OFF
                                                    -DENABLE_64BIT_INTEGERS=OFF
                                                    -DENABLE_GPU=OFF
                                                    -DENABLE_CUBLAS=OFF
                                                    -DENABLE_CSR=OFF
                                                    -DENABLE_SCALASCA=OFF
                                                    -DENABLE_TIMINGS=OFF
                                                    -DENABLE_STATIC_LINKING=OFF
                                                    -DCMAKE_BUILD_TYPE=release
                                                    -DCMAKE_Fortran_COMPILER:STRING=${CMAKE_Fortran_COMPILER}
                                                    -DCMAKE_C_COMPILER:STRING=${CMAKE_C_COMPILER}
                                                    -DCMAKE_CXX_COMPILER:STRING=${CMAKE_CXX_COMPILER}
                                                    -DENABLE_CRAY_WRAPPERS:BOOL=${LSD_CRAY_WRAPPERS}
                                                    -DENABLE_AUTO_BLAS:BOOL=${LSD_AUTO_BLAS}
                                                    -DENABLE_AUTO_LAPACK:BOOL=${LSD_AUTO_LAPACK}
                                                    -DENABLE_SCALAPACK:BOOL=OFF
                                                    -DENABLE_CHEMSHELL:BOOL=ON
                                                    -DCMAKE_Fortran_FLAGS:STRING=${LSD_Fortran_FLAGS}
                                                    -DCMAKE_C_FLAGS:STRING=-fPIC
                                                    -DCMAKE_CXX_FLAGS:STRING=${LSD_CPP_FLAGS}
                                                    -DCMAKE_INSTALL_LIBDIR:PATH=lib
                                                    -DENABLE_LARGE_TEST:BOOL=OFF
                                                    -DBUILD_TESTING:BOOL=OFF
                                                    ${LSD_CMAKE_FLAGS}
                                                    ${LSDALTON_SRC_DIR})
endif()
    
# switch: recompile
set(LSDALTON_CLEAN_COMMAND make clean)
set(LSDALTON_MAKE_COMMAND make -j8)

if(${LSDALTON_RECOMPILE})
    set(LSDALTON_RECOMPILE ON)
    file(REMOVE_RECURSE ${CHEMSH_ARCH}/stamp)
    file(REMOVE_RECURSE ${LSDALTON_BUILD_DIR})
    file(MAKE_DIRECTORY ${LSDALTON_BUILD_DIR})
    # do not overwrite the downloaded source code by a new clone (default: OFF)
    if(RECOMPILE_WITHOUT_DOWNLOAD)
        set(LSDALTON_GIT_REPO "")
    endif()
else()
    if(EXISTS ${CHEMSH_LSDALTON_LIB_DIRECTORY}/liblsdalton.a AND
       EXISTS ${CHEMSH_LSDALTON_LIB_DIRECTORY}/libxcint.a    AND
       EXISTS ${CHEMSH_LSDALTON_LIB_DIRECTORY}/libxcfun.a    AND
       EXISTS ${CHEMSH_LSDALTON_LIB_DIRECTORY}/libdensity.a  AND
       EXISTS ${CHEMSH_LSDALTON_LIB_DIRECTORY}/libbalboa.a   AND
       EXISTS ${CHEMSH_LSDALTON_LIB_DIRECTORY}/libopenrsp.a  AND
       EXISTS ${CHEMSH_LSDALTON_LIB_DIRECTORY}/libqcmatrix.a
      )
        set(LSDALTON_RECOMPILE OFF)
        set(LSDALTON_CLEAN_COMMAND   ${CMAKE_COMMAND} -E cmake_echo_color --switch=$(COLOR) --blue --bold "Found all required static libraries. Skipped cleaning step")
        set(LSDALTON_MAKE_COMMAND    ${CMAKE_COMMAND} -E cmake_echo_color --switch=$(COLOR) --blue --bold "Skipped recompile step")
        set(LSDALTON_INSTALL_COMMAND ${CMAKE_COMMAND} -E cmake_echo_color --switch=$(COLOR) --blue --bold "Skipped installation step")
        message("${BoldRed}LSDALTON_RECOMPILE${EndColour} set ${BoldWhite}OFF${EndColour}: will not recompile LSDALTON")
    else()
        set(LSDALTON_RECOMPILE ON)
        file(REMOVE_RECURSE ${CHEMSH_ARCH}/stamp)
        file(REMOVE_RECURSE ${LSDALTON_BUILD_DIR})
        file(MAKE_DIRECTORY ${LSDALTON_BUILD_DIR})
        message("${Green}LSDALTON_RECOMPILE${EndColour} set ${BoldWhite}OFF${EndColour} but necessary static libraries missing under ${Yellow}${CHEMSH_LSDALTON_LIB_DIRECTORY}${EndColour}: LSDALTON source code will still be recompiled")
    endif()
endif()

# if source code already downloaded
if(EXISTS ${LSDALTON_SRC_DIR}/src/lsdaltonsrc/LSDALTON.F90 AND NOT ${LSDALTON_GIT_REPO} STREQUAL "")
    set(LSDALTON_GIT_REPO "")
endif()

if(NOT ${LSDALTON_RECOMPILE})
    set(LSDALTON_CONFIGURE_COMMAND "")
    set(LSDALTON_CLEAN_COMMAND     "")
    set(LSDALTON_MAKE_COMMAND      "")
endif()

if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.17")
    set(CMAKE_REMOVE_COMMAND rm -rf)
else()
    set(CMAKE_REMOVE_COMMAND remove_directory)
endif()

include(ExternalProject)
# compile LSDALTON as an external project using its original Makefile
ExternalProject_Add(
    ${LSDALTON_NAME}
    GIT_REPOSITORY      ${LSDALTON_GIT_REPO}
    GIT_SHALLOW         1
    GIT_PROGRESS        ${DEBUG}
#    GIT_PROGRESS        ${DEBUG}
    GIT_CONFIG          advice.detachedHead=false
    
    GIT_TAG             ${LSDALTON_DEFAULT_VERSION}
    UPDATE_DISCONNECTED 1
    UPDATE_COMMAND      pwd
    PREFIX              ${CHEMSH_ARCH}
    STAMP_DIR           ${CHEMSH_ARCH}/stamp
    TMP_DIR             ${CHEMSH_ARCH}/tmp
    BUILD_ALWAYS        ${LSDALTON_RECOMPILE}
    SOURCE_DIR          ${LSDALTON_SRC_DIR}
    BINARY_DIR          ${LSDALTON_DIR}/build
    CONFIGURE_COMMAND   ${CMAKE_COMMAND} -E cmake_echo_color --switch=$(COLOR) --magenta --bold "Architecture for which '${LSDALTON_NAME}' is built: '${CHEMSH_ARCH}'"
    BUILD_COMMAND       ${CMAKE_COMMAND} -E cmake_echo_color --switch=$(COLOR) --magenta --bold "LSDalton build directory: ${LSDALTON_BUILD_DIR}"
    INSTALL_COMMAND     ""
)

# create the build dir (the ALWAYS switch doesn't work)
if(${LSDALTON_RECOMPILE})
    set(LSDALTON_MKDIR_COMMAND
                      ${CMAKE_COMMAND} -E ${CMAKE_REMOVE_COMMAND} ${LSDALTON_BUILD_DIR}
    COMMAND           ${CMAKE_COMMAND} -E make_directory ${LSDALTON_BUILD_DIR})
else()
    set(LSDALTON_MKDIR_COMMAND "")
endif()
ExternalProject_Add_Step(
    ${LSDALTON_NAME}  LSDALTON_CLEAN
    COMMENT           "Cleaning preivous LSDalton build..."
    ALWAYS            ${LSDALTON_RECOMPILE}
    DEPENDEES         configure
    COMMAND           ${LSDALTON_MKDIR_COMMAND}
    WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
)

ExternalProject_Add_Step(
    ${LSDALTON_NAME}  LSDALTON_HACK
    COMMENT           "Hacking LSDalton configuration..."
    ALWAYS            1
    DEPENDEES         LSDALTON_CLEAN
    # YL 17/08/2021: CMake doesn't have a standard patchting method (`cmake -E patch ...` won't work) and file/string processing actions at the configure stage
    COMMAND           ${Python3_EXECUTABLE} hack.py
    WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
)

ExternalProject_Add_Step(
    ${LSDALTON_NAME}  LSDALTON_CONFIGURE
    COMMENT           "Configuring '${LSDALTON_NAME}'..."
    ALWAYS            ${LSDALTON_RECOMPILE}
    DEPENDEES         LSDALTON_HACK
    COMMAND           ${LSDALTON_CONFIGURE_COMMAND}
    WORKING_DIRECTORY ${LSDALTON_BUILD_DIR}
)

ExternalProject_Add_Step(
    ${LSDALTON_NAME}  LSDALTON_BUILD
    COMMENT           "Building static library for '${LSDALTON_NAME}'..."
    ALWAYS            ${LSDALTON_RECOMPILE}
    # always preceded by LSDALTON_CONFIGURE
    DEPENDEES         LSDALTON_CONFIGURE
    COMMAND           ${LSDALTON_CLEAN_COMMAND} COMMAND ${LSDALTON_MAKE_COMMAND}
    WORKING_DIRECTORY ${LSDALTON_BUILD_DIR}
)

# install the static libs (the ALWAYS switch doesn't work)
if(${LSDALTON_RECOMPILE})
    # by default LSDalton finds the system XCFun static lib
    find_package(XCFun QUIET)
    if(TARGET XCFun::xcfun)
        get_property(_loc TARGET XCFun::xcfun PROPERTY LOCATION)
        set(LIBXCFUN_PATH ${_loc})
    else()
        set(LIBXCFUN_PATH ${LSDALTON_BUILD_DIR}/lib/libxcfun.a)
    endif()

    set(LSDALTON_INSTALL_COMMAND
                      ${CMAKE_COMMAND} -E copy ${LSDALTON_BUILD_DIR}/lib/liblsdalton.a ${CHEMSH_LSDALTON_LIB_DIRECTORY}
    COMMAND           ${CMAKE_COMMAND} -E copy ${LSDALTON_BUILD_DIR}/lib/libxcint.a    ${CHEMSH_LSDALTON_LIB_DIRECTORY}
    COMMAND           ${CMAKE_COMMAND} -E copy ${LSDALTON_BUILD_DIR}/lib/libdensity.a  ${CHEMSH_LSDALTON_LIB_DIRECTORY}
    COMMAND           ${CMAKE_COMMAND} -E copy ${LSDALTON_BUILD_DIR}/_deps/xcint_sources-build/src/balboa/lib/libbalboa.a ${CHEMSH_LSDALTON_LIB_DIRECTORY}
    COMMAND           ${CMAKE_COMMAND} -E copy ${LSDALTON_BUILD_DIR}/lib/libopenrsp.a  ${CHEMSH_LSDALTON_LIB_DIRECTORY}
    COMMAND           ${CMAKE_COMMAND} -E copy ${LSDALTON_BUILD_DIR}/lib/libqcmatrix.a ${CHEMSH_LSDALTON_LIB_DIRECTORY}
    COMMAND           ${CMAKE_COMMAND} -E copy ${LIBXCFUN_PATH}                        ${CHEMSH_LSDALTON_LIB_DIRECTORY})
else()
    set(LSDALTON_INSTALL_COMMAND "")
endif()
ExternalProject_Add_Step(
    ${LSDALTON_NAME}  LSDALTON_INSTALL
    COMMENT           "Installing static libraries to ${CHEMSH_LSDALTON_LIB_DIRECTORY}"
    ALWAYS            ${LSDALTON_RECOMPILE}
    # always preceded by LSDALTON_BUILD
    DEPENDEES         LSDALTON_BUILD
    COMMAND           ${LSDALTON_INSTALL_COMMAND}
    WORKING_DIRECTORY ${LSDALTON_BUILD_DIR}
)

# Link in LSDALTON
# compile liblsdalton.so (containing only Py-ChemShell interface files)
add_library(lsdalton SHARED lsdalton.f90 lsdalton_routines.f90 ${LINKED})

add_dependencies(lsdalton ${LSDALTON_NAME} parallel)

# YL 31/07/2023: C++
set(LSDALTON_LINK_EXTRA_FLAGS -lstdc++)
if(${CHEMSH_ARCH} STREQUAL "intel")
    target_link_libraries(lsdalton "${CHEMSH_MKL_FLAGS}")
elseif(${CHEMSH_ARCH} STREQUAL "gnu")
    target_link_libraries(lsdalton ${BLAS_LIBRARIES} ${LAPACK_LIBRARIES})
    # enable OpenMP and BLACS/ScaLAPACK for parallel version
    if(WITH_MPI)
        set(LSDALTON_LINK_EXTRA_FLAGS "${LSDALTON_LINK_EXTRA_FLAGS} -fopenmp ${CHEMSH_ScaLAPACK_FLAGS}")
    endif()
endif()

set_target_properties(lsdalton PROPERTIES LINK_FLAGS "-Wl,--export-dynamic                                      \
                                                      -Wl,--whole-archive                                       \
                                                      ${CHEMSH_LSDALTON_LIB_DIRECTORY}/liblsdalton.a            \
                                                      ${CHEMSH_LSDALTON_LIB_DIRECTORY}/libxcint.a               \
                                                      ${CHEMSH_LSDALTON_LIB_DIRECTORY}/libxcfun.a               \
                                                      ${CHEMSH_LSDALTON_LIB_DIRECTORY}/libdensity.a             \
                                                      ${CHEMSH_LSDALTON_LIB_DIRECTORY}/libbalboa.a              \
                                                      ${CHEMSH_LSDALTON_LIB_DIRECTORY}/libopenrsp.a             \
                                                      ${CHEMSH_LSDALTON_LIB_DIRECTORY}/libqcmatrix.a            \
                                                      -Wl,--no-whole-archive ${LSDALTON_LINK_EXTRA_FLAGS}       \
						      ${CHEMSH_LINK_FLAGS}")
# YL TODO: export.map
#                                                      -Wl,--version-script=${CMAKE_CURRENT_LIST_DIR}/export.map")

# link the static library against liblsdalton.so
target_link_libraries(lsdalton dl_py2f parallel)
