#############################################################
#############################################################
# CMake configuration
cmake_minimum_required(VERSION 3.18.4)

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

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

# Include the system's uname that fills in SYSTEM_UNAME_S.
# Sets WIN32 if SYSTEM_UNAME_S is "^.*MING64.*"
# Note that WIN32 is set even on 64 bits systems.
include(${CMAKE_UTILS_PATH}/systemUname.cmake)

# Include the various colors we want to use in the output
include(${CMAKE_UTILS_PATH}/outputColors.cmake)

# Compute the extended version number using git describe
include(${CMAKE_UTILS_PATH}/extended-version.cmake)

message("GIT_RECORD_IDENTIFIER: ${GIT_RECORD_IDENTIFIER}")

project(
    MineXpert3
    VERSION 11.6.3
    DESCRIPTION "A program to visualize and explore mass spectrometric data"
    HOMEPAGE_URL "http://wwww.msxpertsuite.org/minexpert3"
)

set(LOWCASE_PROJECT_NAME minexpert3)
set(LOWCASE_PROJECT_NAME_NO_VER minexpert)

set(TARGET ${PROJECT_NAME})

# 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

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

#############################################################
#############################################################
# Installation prefix (these lines before include(GNUInstallDirs))
if(NOT CMAKE_INSTALL_PREFIX)
    set(CMAKE_INSTALL_PREFIX /usr/local)
endif()

include(GNUInstallDirs)

message(STATUS: CMAKE_CXX_LIBRARY_ARCHITECTURE is: ${CMAKE_CXX_LIBRARY_ARCHITECTURE})

set(HOME_DEVEL_DIR $ENV{HOME}/devel)

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

# This include must come before all the others
# It must include the config-generated config.h file
# before the others.
include_directories(${CMAKE_BINARY_DIR})

# And now the source directory contains the .h|.hpp files for its .cpp files.
include_directories(${CMAKE_SOURCE_DIR})

# For the config.h file.
set(CMAKE_INCLUDE_CURRENT_DIR ON)

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
# youcompleteme (vim plugin) and 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_SOURCE_DIR}/compile_commands.json
    )
endif()

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

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

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

if(WARN_AS_ERROR)
    message(STATUS "Setting definition -Werror.")
    add_definitions(-Werror)
endif()

message("CMAKE_SOURCE_DIR: ${CMAKE_SOURCE_DIR}")

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}")

option(XPERTMASS_LOCAL_DEV "Use locally developped libXpertMass" OFF)
option(XPERTMASS_LOCAL_INST "Use /usr/local/lib installed libXpertMass" OFF)

if(XPERTMASS_LOCAL_DEV AND XPERTMASS_LOCAL_INST)
    message(FATAL_ERROR "Cannot have both XPERTMASS_LOCAL_DEV and XPERTMASS_LOCAL_INST")
endif()

message(STATUS "XPERTMASS_LOCAL_DEV: ${XPERTMASS_LOCAL_DEV}")
message(STATUS "XPERTMASS_LOCAL_INST: ${XPERTMASS_LOCAL_INST}")

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

#############################################################
#############################################################
# 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()

# Define this as On if JavaScript/Qml bindings are to be exported.
# See src/CMakeLists.txt
# See #cmakedefine in CMakeStuff/config.h.cmake.in
# Need to #inlude "config.h" for the defined value to be visible.
# option(JS_QML "Generate the JavaScript/Qml bindings plugin lib" Off)

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()

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

if(PROFILE)
    message(STATUS "${BoldYellow}Profiling is requested, adding -pg flag.${ColourReset}")
    add_definitions(-pg)
endif()

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

# It is essential to run these config steps before delving into the minexpert
# directory, because at that moment they will need what are
# going to prepare right now.
configure_file(${CMAKE_SOURCE_DIR}/CMakeStuff/splashscreen.svg.in ${CMAKE_SOURCE_DIR}/images/svg/splashscreen.svg @ONLY)

# Make the conversion of the svg file into a png, but only on GNU/Linux
if(UNIX)
    execute_process(
        COMMAND rsvg-convert -f png -o ${CMAKE_SOURCE_DIR}/images/splashscreen.png
                ${CMAKE_SOURCE_DIR}/images/svg/splashscreen.svg
    )
endif()

#############################################################
######################
# BUILD OF THE PROGRAM

message(STATUS "Adding subdirectory src for TARGET: ${TARGET}")
add_subdirectory(src)

#############################################################
######################
# BUILD OF THE PLUGINS
option(BUILD_PLUGINS "Build the plugins" OFF)
if(BUILD_PLUGINS)
    message(STATUS "Building the plugins")
    add_subdirectory(plugins)
else()
    message(STATUS "Not building the plugins")
endif()

#############################################################
################################
# BUILD OF THE DOC / USER MANUAL
option(BUILD_USER_MANUAL "Build the user manual, on UNIX only." OFF)
message(STATUS "Adding subdirectory doc for project: ${TARGET}")
add_subdirectory(doc)

# Use all the configured paths to create the config.h file.
# The config file is binary directory-specific !!!
configure_file(${CMAKE_UTILS_PATH}/config.h.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/src/config.h @ONLY)

####################################################
# Installation directories depending on the platform
####################################################

# See the CMakeStuff/toolchains platform-specific files.
message(STATUS "CMAKE_INSTALL_PREFIX: ${CMAKE_INSTALL_PREFIX}")
message(STATUS "PROJECT_INSTALL_BIN_DIR: ${PROJECT_INSTALL_BIN_DIR}")
message(STATUS "PROJECT_INSTALL_LIB_DIR: ${PROJECT_INSTALL_LIB_DIR}")
message(STATUS "PROJECT_INSTALL_LIB_QML_DIR: ${PROJECT_INSTALL_LIB_QML_DIR}")
message(STATUS "PROJECT_INSTALL_DATA_DIR: ${PROJECT_INSTALL_DATA_DIR}")
message(STATUS "PROJECT_INSTALL_DOC_DIR: ${PROJECT_INSTALL_DOC_DIR}")

#############################################################
###########################
# CREATE THE SOURCE PACKAGE
include(${CMAKE_UTILS_PATH}/targz-source-package-creation.cmake)

add_custom_target(
    archive
    cpack
    -G
    TGZ
    --config
    CPackSourceConfig.cmake
    &&
    mv
    ${CMAKE_BINARY_DIR}/${LOWCASE_PROJECT_NAME}-${PROJECT_VERSION}.tar.gz
    ${CMAKE_SOURCE_DIR}/../tarballs
    &&
    ln
    -sf
    ${CMAKE_SOURCE_DIR}/../tarballs/${LOWCASE_PROJECT_NAME}-${PROJECT_VERSION}.tar.gz
    ${CMAKE_SOURCE_DIR}/../${LOWCASE_PROJECT_NAME}_${PROJECT_VERSION}.orig.tar.gz
    &&
    ln
    -sf
    ${CMAKE_SOURCE_DIR}/../tarballs/${LOWCASE_PROJECT_NAME}-${PROJECT_VERSION}.tar.gz
    ${CMAKE_SOURCE_DIR}/../tarballs/${LOWCASE_PROJECT_NAME}_${PROJECT_VERSION}.orig.tar.gz
    WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
    COMMENT "Creating .tar.gz"
    VERBATIM
)

#############################################################
# summary
message("")
message(STATUS "${BoldRed}~~~~~~~~~~~~~~~~~~~~~~~~ SUMMARY ~~~~~~~~~~~~~~~~~~~~~~~~${ColourReset}")
message(STATUS "${BoldRed}   General configuration of the ${CMAKE_PROJECT_NAME} project ${ColourReset}")
message("")

message(STATUS "${BoldYellow}System is detected by CMake as ${SYSTEM_UNAME_S}${ColourReset}")
message(STATUS "${BoldYellow}CMAKE_CXX_COMPILER: ${CMAKE_CXX_COMPILER}${ColourReset}")
message(STATUS "${BoldYellow}CMAKE_CXX_STANDARD: ${CMAKE_CXX_STANDARD}${ColourReset}")

message("")

message(STATUS "${BoldYellow}CMAKE_INSTALL_PREFIX: ${CMAKE_INSTALL_PREFIX}${ColourReset}")
message(STATUS "${BoldYellow}TARGET: ${TARGET}${ColourReset}")
message(STATUS "${BoldYellow}Installation BIN directory: ${PROJECT_INSTALL_BIN_DIR}${ColourReset}")
message(STATUS "${BoldYellow}Installation LIB directory: ${PROJECT_INSTALL_LIB_DIR}${ColourReset}")
message(STATUS "${BoldYellow}Installation LIB QML directory: ${PROJECT_INSTALL_LIB_QML_DIR}${ColourReset}")
message(STATUS "${BoldYellow}Installation DATA directory: ${PROJECT_INSTALL_DATA_DIR}${ColourReset}")
message(STATUS "${BoldYellow}Installation DOC directory: ${PROJECT_INSTALL_DOC_DIR}${ColourReset}")

if(PROFILING)
    message(STATUS "${BoldYellow}Profiling is requested (-DPROFILING=1)${ColourReset}")
else()
    message(STATUS "${BoldYellow}Profiling is NOT requested (-DPROFILING=0)${ColourReset}")
endif()

if(WARNASERR)
    message(STATUS "${BoldYellow}Warnings ARE treated as errors (-DWARNASERR=1)${ColourReset}")
else()
    message(STATUS "${BoldYellow}Warnings NOT treated as errors (-DWARNASERR=0)${ColourReset}")
endif()

if(CMAKE_BUILD_TYPE STREQUAL "Debug")
    message(STATUS "${BoldYellow}Debug support IS requested.${ColourReset}")
else()
    message(STATUS "${BoldYellow}Debug support NOT requested.${ColourReset}")
endif()

message("")
message(
    STATUS
        "${BoldYellow}The typical cmake invocation on Debian GNU/Linux would be: cmake -DCMAKE_BUILD_TYPE=Debug -DBUILD_USER_MANUAL=1 ../../development${ColourReset}"
)
message(
    STATUS
        "${BoldYellow}The typical cmake invocation on win10-mingw64 would be: cmake -DCMAKE_BUILD_TYPE=Release  ../../development${ColourReset}"
)
message(
    STATUS
        "${BoldYellow}The typical cmake invocation on MXE would be: x86_64-w64-mingw32.shared-cmake -DCMAKE_BUILD_TYPE=Release -DMXE=1 ../../development${ColourReset}"
)
message("")

if(LOCAL_DEV OR PAPPSO_DEV)
    message("")
    message("${BoldGreen}USING LOCAL DEVELOPMENT CONFIG FOR PAPPSOMSPP libraries")
    message("")
endif()

if(LOCAL_DEV OR XPERTMASS_DEV)
    message("")
    message("${BoldGreen}USING LOCAL DEVELOPMENT CONFIG FOR XPERTMASS libraries")
    message("")
endif()

message("")
message(STATUS "${BoldRed}~~~~~~~~~~~~~~~~~~~~~~~~ SUMMARY ~~~~~~~~~~~~~~~~~~~~~~~~${ColourReset}")
message("")
