# ##############################################################################
# ##############################################################################
# CMake configuration 3.18.4 in oldstable as of 2024 - 07 - 15
cmake_minimum_required(VERSION 3.18.4)

set(CMAKE_PROJECT_INCLUDE_BEFORE ${CMAKE_SOURCE_DIR}/CMakeStuff/ancillary-project-include-before.cmake)

# ##############################################################################
# ##############################################################################
# Basic information about project

project(
    XpertMass
    VERSION 1.12.1
    DESCRIPTION "Libraries [XpertMass::Core (non-GUI) and XpertMass::Gui) for the MsXpertSuite project."
    HOMEPAGE_URL "http://wwww.msxpertsuite.org/libxpertmass"
    LANGUAGES CXX
)

set(LOWCASE_PROJECT_NAME xpertmass)

# project(VERSION) above sets: PROJECT_VERSION, <PROJECT-NAME>_VERSION
# PROJECT_VERSION_MAJOR, <PROJECT-NAME>_VERSION_MAJOR PROJECT_VERSION_MINOR,
# <PROJECT-NAME>_VERSION_MINOR PROJECT_VERSION_PATCH,
# <PROJECT-NAME>_VERSION_PATCH

message("\n${BoldGreen}Building version ${PROJECT_VERSION} of \
${PROJECT_NAME} (${CMAKE_PROJECT_DESCRIPTION})${ColourReset}\n"
)

# Set additional project information
set(COMPANY "MsXpertSuite.org")
set(COPYRIGHT "Copyright (c) 2008-2025 Filippo Rusconi. Licensed under GPLv3+")
set(IDENTIFIER "org.msxpertsuite.libxpertmass")

# This line MUST be located prior to include'ing GNUInstallDirs !!!
#############################################################
#############################################################
# Installation prefix
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
    set(CMAKE_INSTALL_PREFIX
        "/usr/local"
        CACHE PATH "Install path" FORCE
    )
else()
    set(CMAKE_INSTALL_PREFIX
        "${CMAKE_INSTALL_PREFIX}"
        CACHE PATH "Install path" FORCE
    )
    message(STATUS "Setting CMAKE_INSTALL_PREFIX to ${CMAKE_INSTALL_PREFIX}")
endif()

include(GNUInstallDirs)
include(FeatureSummary)

# Add folder where are supportive functions
set(CMAKE_UTILS_PATH ${CMAKE_SOURCE_DIR}/CMakeStuff)
set(CMAKE_MODULE_PATH ${CMAKE_UTILS_PATH}/modules)
set(CMAKE_TOOLCHAINS_PATH ${CMAKE_UTILS_PATH}/toolchains)

# Our build scripts take for granted that this files is available.
configure_file(${CMAKE_UTILS_PATH}/version.cmake.in ${CMAKE_BINARY_DIR}/version.txt)

set(HOME_DEVEL_DIR $ENV{HOME}/devel)
message("\n${BoldYellow}The devel directory where all the development projects \
should reside: ${HOME_DEVEL_DIR}.${ColourReset}\n"
)

set(CMAKE_COLOR_MAKEFILE ON)
set(CMAKE_VERBOSE_MAKEFILE ON)

message("\n${BoldGreen}Configuring build for project ${CMAKE_PROJECT_NAME}${ColourReset}\n")

# This export will allow using the flags to be used by the Clang-based code
# analyzer.
set(CMAKE_EXPORT_COMPILE_COMMANDS 1)

if(EXISTS "${CMAKE_CURRENT_BINARY_DIR}/compile_commands.json")
    execute_process(
        COMMAND cmake -E copy_if_different ${CMAKE_CURRENT_BINARY_DIR}/compile_commands.json
                ${CMAKE_CURRENT_SOURCE_DIR}/compile_commands.json
    )
endif()

# We want C++17
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
message(STATUS "CMAKE_CXX_STANDARD: ${CMAKE_CXX_STANDARD}")
message(STATUS "CMAKE_CXX_STANDARD_REQUIRED: ${CMAKE_CXX_STANDARD_REQUIRED}")

message(STATUS "CMAKE_CXX_COMPILER: ${CMAKE_CXX_COMPILER}")

# ##############################################################################
# Setting command line compiler definitions:
message(STATUS "${BoldYellow}Setting compiler command line definitions.${ColourReset}")

# We do not want warnings for unknown pragmas:
message("Setting definition -Wno-unknown-pragmas.")
add_definitions(-Wno-unknown-pragmas)

# Enable warnings and possibly treat them as errors
message("Setting definition -Wall -pedantic.")
add_definitions(-Wall -pedantic)
message("Setting definition -Wextra.")
add_definitions(-Wextra)

if(WARN_AS_ERROR)
    message("Setting definition -Werror.")
    add_definitions(-Werror)
else()
    message("NOT setting definition -Werror.")
endif()

message(STATUS "\nCMAKE_SOURCE_DIR: ${CMAKE_SOURCE_DIR}\n")

option(MXE "Use the cross-compiling environment MXE" OFF)

option(PAPPSO_LOCAL_DEV "Use locally developped libpappsomspp" OFF)
option(PAPPSO_LOCAL_INST "Use /usr/local/lib installed libpappsomspp" OFF)

if(PAPPSO_LOCAL_DEV AND PAPPSO_LOCAL_INST)
    message(FATAL_ERROR "Cannot have both PAPPSO_LOCAL_DEV and PAPPSO_LOCAL_INST")
endif()

message(STATUS "PAPPSO_LOCAL_DEV: ${PAPPSO_LOCAL_DEV}")
message(STATUS "PAPPSO_LOCAL_INST: ${PAPPSO_LOCAL_INST}")

# ##############################################################################
# ##############################################################################
# Platform-specific CMake configuration
if(WIN32 OR _WIN32)

    if(MXE)

        # Run the following cmake command line: x86_64-w64-mingw32.shared-cmake
        # -DCMAKE_BUILD_TYPE=Release -DMXE=1 ../../development
        include(${CMAKE_TOOLCHAINS_PATH}/mxe-toolchain.cmake)

        # Set the name to the systemUname variable because in this situation that
        # name is not found, it it passed as a flag in the command line.
        set(SYSTEM_UNAME_S "mxe")

    elseif(WIN10UCRT64)
        include(${CMAKE_TOOLCHAINS_PATH}/win10-ucrt64-toolchain.cmake)
    endif()

elseif(UNIX)

    message("UNIX toolchain being selected")

    include(${CMAKE_TOOLCHAINS_PATH}/unix-toolchain-common.cmake)

endif()

message("")
message(STATUS "${BoldGreen}Starting configuration of ${CMAKE_PROJECT_NAME}${ColourReset}")
message("")
message(STATUS "${BoldYellow}The build toolchain is: ${SYSTEM_UNAME_S}${ColourReset}")
message("")

# ##############################################################################
# ##############################################################################
# Essential software configuration
message(STATUS "CMAKE_CURRENT_BINARY_DIR: " ${CMAKE_CURRENT_BINARY_DIR})

if(NOT CMAKE_BUILD_TYPE)
    set(CMAKE_BUILD_TYPE
        Release
        CACHE STRING "Type of build, options are: None, Debug, Release, RelWithDebInfo, MinSizeRel." FORCE
    )
endif(NOT CMAKE_BUILD_TYPE)

if(CMAKE_BUILD_TYPE MATCHES "Release")
    message(STATUS "Compiling in release mode.")
    add_definitions("-DQT_NO_DEBUG_OUTPUT")
endif()

if(CMAKE_BUILD_TYPE MATCHES "Debug")
    message(STATUS "Compiling in debug mode.")
    message(STATUS "Add definition -ggdb3 to format debug output for GDB.")
    add_definitions(-ggdb3)
endif()

if(CMAKE_BUILD_TYPE MATCHES "RelWithDebInfo")
    message(STATUS "Compiling in release with debug info mode.")
endif(CMAKE_BUILD_TYPE MATCHES "RelWithDebInfo")

message(STATUS "${BoldYellow}CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}.${ColourReset}")

option(PROFILING Off)
if(PROFILING)
    message(STATUS "${BoldYellow}Profiling is requested, adding -pg -g flags.${ColourReset}")
    add_definitions(-pg -g)
endif()

message(STATUS "${BoldYellow}Main CMAKE_BINARY_DIR: ${CMAKE_BINARY_DIR}${ColourReset}")
message(STATUS "${BoldYellow}CMAKE_CXX_COMPILER: ${CMAKE_CXX_COMPILER}${ColourReset}")

# ##############################################################################
# ##############################################################################
# BUILD OF THE LIBRARIES

message(STATUS "\n${BoldGreen}Adding subdirectory src for PROJECT: \
${CMAKE_PROJECT_NAME}${ColourReset}\n"
)
add_subdirectory(source)

# ##############################################################################
# ##############################################################################
# BUILD THE DOCUMENTATION (JavaScript reference and/or devdoc)
add_subdirectory(doc)

# ##############################################################################
# ##############################################################################
# BUILD OF THE TESTS
option(BUILD_TESTS Off)
option(CODE_COVERAGE "Collect coverage for tests " Off)

if(UNIX AND CODE_COVERAGE)
    set(BUILD_TESTS On)
endif()

if(UNIX AND BUILD_TESTS)

    if(CMAKE_COMPILER_IS_GNUCXX AND CODE_COVERAGE)
        set(CMAKE_BUILD_TYPE Debug)
        include(CodeCoverage)
        append_coverage_compiler_flags()
    endif()

    message(STATUS "\n${BoldGreen}Build the tests ${ColourReset}\n")
    message("Adding subdirectory tests for PROJECT: ${CMAKE_PROJECT_NAME}")

    add_subdirectory(tests)

endif()

# ##############################################################################
# ##############################################################################
# PROFILING
option(PROFILING Off)
if(PROFILING)
    message("Add profiling flag -pg")
    add_compile_options("-pg")
endif()

# ##############################################################################
# ##############################################################################
# Creation of the source archive
include(${CMAKE_UTILS_PATH}/targz-source-package-creation.cmake)

set(PARENT_DIR ${CMAKE_SOURCE_DIR}/..)
set(TARBALL_DIR ${PARENT_DIR}/tarballs)

add_custom_target(
    archive
    cpack
    -G
    TGZ
    --config
    CPackSourceConfig.cmake
    &&
    mv
    ${CMAKE_BINARY_DIR}/${ARCHIVE_FILE_NAME_EXT}
    ${TARBALL_DIR}
    &&
    ln
    -sf
    ${TARBALL_DIR}/${ARCHIVE_FILE_NAME_EXT}
    ${PARENT_DIR}/${DEBIAN_ORIG_FILE_NAME}
    &&
    ln
    -sf
    ${TARBALL_DIR}/${ARCHIVE_FILE_NAME_EXT}
    ${TARBALL_DIR}/${DEBIAN_ORIG_FILE_NAME}
    WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
    COMMENT "Creating .tar.gz"
    VERBATIM
)

# -----------------------------------------------------------#
# Summary
# -----------------------------------------------------------#
message("\n\nBegin feature summary")
message("---------------------\n")
feature_summary(FATAL_ON_MISSING_REQUIRED_PACKAGES WHAT ALL)
message("---------------------")
message("End feature summary\n\n")
