
cmake_minimum_required(VERSION 3.14)

project(
  "libpsml"
  LANGUAGES "Fortran"
  VERSION "2.0.1"
  DESCRIPTION "Library to process PSML pseudopotential files"
)

list(PREPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/config/cmake")

# Set build type as CMake does not provide defaults
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
  set(
    CMAKE_BUILD_TYPE "RelWithDebInfo"
    CACHE STRING "Build type to be used."
    FORCE
  )
  message(
    STATUS
    "Setting build type to '${CMAKE_BUILD_TYPE}' as none was specified."
  )
endif()

option(BUILD_SHARED_LIBS "Whether the libraries built should be shared" FALSE)

if (NOT TARGET "xmlf90::xmlf90")
   message(STATUS "   --- libpsml needs target xmlf90::xmlf90")
   find_package(Customxmlf90)
endif()

# Avoid "liblibpsml.a" names...
set(LIBRARY_OUTPUT_NAME "psml")

# Collect source of the project
set(srcs)
add_subdirectory("src")

add_library("${PROJECT_NAME}-lib" "${srcs}")

#-------------
#  These are records of features that could be checked programmatically when
#  configuring clients if libpsml is used as a pre-compiled library, but
#  not if the libpsml source is compiled by the client.
#
set(LIBPSML_HAS_ERROR_PROCEDURE_POINTER TRUE CACHE BOOL "libpsml uses a procedure pointer for error handling")
set(LIBPSML_READER_HAS_STAT TRUE CACHE BOOL "psml_reader has an optional 'stat' return argument")
#-------------

set_target_properties(
  "${PROJECT_NAME}-lib"
  PROPERTIES
  POSITION_INDEPENDENT_CODE TRUE
  OUTPUT_NAME "${LIBRARY_OUTPUT_NAME}"
  VERSION "${PROJECT_VERSION}"
  SOVERSION "${PROJECT_VERSION_MAJOR}"
  Fortran_MODULE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/include"
)

# Check for xmlf90 feature

include(check_xmlf90_stat)
if (XMLF90_PARSE_HAS_STAT)
 target_compile_definitions("${PROJECT_NAME}-lib" PRIVATE XMLF90_PARSE_HAS_STAT)
endif()

target_link_libraries("${PROJECT_NAME}-lib" PUBLIC xmlf90::xmlf90)

### -----
# Install

# Follow GNU conventions for installing directories
include(GNUInstallDirs)

set(module-dir
  "${PROJECT_NAME}/${CMAKE_Fortran_COMPILER_ID}-${CMAKE_Fortran_COMPILER_VERSION}"
)

target_include_directories(
  "${PROJECT_NAME}-lib"
  PUBLIC
  $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include>
  $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
  $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/${module-dir}>
)

# Export targets for other projects
add_library("${PROJECT_NAME}" INTERFACE)
target_link_libraries("${PROJECT_NAME}" INTERFACE "${PROJECT_NAME}-lib")
install(
  TARGETS
  "${PROJECT_NAME}"
  "${PROJECT_NAME}-lib"
  EXPORT
  "${PROJECT_NAME}-targets"
  LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
  ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
)
install(
  EXPORT
  "${PROJECT_NAME}-targets"
  NAMESPACE
  "${PROJECT_NAME}::"
  DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
)
install(
  DIRECTORY
  "${CMAKE_CURRENT_BINARY_DIR}/include/"
  DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/${module-dir}"
)
# Package license files
install(
  FILES
  "COPYING"
  DESTINATION "${CMAKE_INSTALL_DATADIR}/licenses/${PROJECT_NAME}"
)

include(CMakePackageConfigHelpers)
configure_package_config_file(
  "${CMAKE_CURRENT_SOURCE_DIR}/config/template.cmake"
  "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config.cmake"
  INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
)
#
# Use "AnyNewerVersion" but recommend checking for new features
# (i.e. procedure pointers) at client's configuration time.
# In this way we can request, say, a minimum version of 1.1.12, and
# still be able to use 2.X if found.
#
write_basic_package_version_file(
  "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake"
  VERSION "${PROJECT_VERSION}"
  COMPATIBILITY AnyNewerVersion
)
install(
  FILES
  "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config.cmake"
  "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake"
  DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
)

#
# Copy also search helpers
#
install(
  DIRECTORY
  "${PROJECT_SOURCE_DIR}/config/cmake/"
  DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
)

configure_file(
  "${CMAKE_CURRENT_SOURCE_DIR}/config/template.pkgconf"
  "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc"
  @ONLY
)
install(
  FILES
  "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc"
  DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig"
)

# add the testsuite
include(CTest)
add_subdirectory("examples")

list(POP_FRONT CMAKE_MODULE_PATH)
