cmake_minimum_required(VERSION 3.12)

# CMake script for PAPPSOms++ library
# Authors: Olivier Langella & Filippo Rusconi
# Created: 03/03/2015
# Rework: April 2020 (Coronavirus confinement)

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

project(libpappsomspp)

set(PAPPSOMSPP_VERSION_MAJOR "0")
set(PAPPSOMSPP_VERSION_MINOR "11")
set(PAPPSOMSPP_VERSION_PATCH "0")
set(PAPPSOMSPP_VERSION "${PAPPSOMSPP_VERSION_MAJOR}.${PAPPSOMSPP_VERSION_MINOR}.${PAPPSOMSPP_VERSION_PATCH}")
set(MASSCHROQ_VERSION "3.0.1")

# Command to enable debug and tests
# cmake -DCMAKE_BUILD_TYPE=Debug  -DMAKE_TESTS=1 -DUSEPAPPSOTREE=0 ..

message(STATUS "${BoldYellow}CMAKE_LIBRARY_ARCHITECTURE: ${CMAKE_LIBRARY_ARCHITECTURE}${ColourReset}")

# 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)
endif()
include(GNUInstallDirs)

message(STATUS "Set CMAKE_INSTALL_PREFIX to ${CMAKE_INSTALL_PREFIX}")
message(STATUS "Install directory prefix: ${CMAKE_INSTALL_PREFIX}")
message(STATUS "CMAKE_INSTALL_FULL_LIBDIR: ${CMAKE_INSTALL_FULL_LIBDIR}")
message(STATUS "CMAKE_INSTALL_FULL_INCLUDEDIR: ${CMAKE_INSTALL_FULL_INCLUDEDIR}")

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

configure_file(${CMAKE_UTILS_PATH}/version.cmake.in ${CMAKE_BINARY_DIR}/version.txt)

# We need a variable that is not modified by CMake because we'll need to access
# that specific directory later
set(LOCAL_CMAKE_MODULE_PATH ${CMAKE_UTILS_PATH}/modules)
message("CMakeLists.txt - LOCAL_CMAKE_MODULE_PATH:" ${LOCAL_CMAKE_MODULE_PATH})

# Now add our local path to the general path list.
set(CMAKE_MODULE_PATH ${LOCAL_CMAKE_MODULE_PATH} ${CMAKE_MODULE_PATH})

# Include the system's uname that fills in SYSTEM_UNAME_S.
# Sets WIN64 if SYSTEM_UNAME_S is "^.*MING64.*"
include(${CMAKE_UTILS_PATH}/systemUname.cmake)

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

set(CMAKE_COLOR_MAKEFILE ON)
set(CMAKE_VERBOSE_MAKEFILE ON)

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

# This export will allow using the flags to be used by
# youcompleteme (vim plugin).
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 "${BoldGreen}CMAKE_CXX_COMPILER: ${CMAKE_CXX_COMPILER}${ColourReset}")

#############################################################
# We do not want warnings for unknown pragmas:
message(STATUS "Setting definition -Wno-unknown-pragmas.${ColourReset}")
add_definitions(-Wno-unknown-pragmas)
# Enable warnings and possibly treat them as errors
message(STATUS "${BoldGreen}Setting definition -Wall.${ColourReset}")
add_definitions(-Wall)
message(STATUS "${BoldGreen}Setting definition -Wextra.${ColourReset}")
add_definitions(-Wextra)

if(WARN_AS_ERROR)
    message(STATUS "${BoldYellow}Setting definition -Werror.${ColourReset}")
    add_definitions(-Werror)
endif()

message(STATUS "${BoldYellow}CMAKE_SOURCE_DIR: ${CMAKE_SOURCE_DIR}${ColourReset}")

option(MXE "Use the cross-compiling environment MXE" OFF)
option(WIN10MINGW64 "Use the Msys64/ucrt64 compiling environment" OFF)

#############################################################
#############################################################
# Platform-specific CMake configuration
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(MXEOLIVIER)

    include(${CMAKE_TOOLCHAINS_PATH}/mxe-toolchain-olivier.cmake)
    set(SYSTEM_UNAME_S "mxe")

elseif(UNIX AND NOT APPLE)
    # Run the following cmake command line:
    # cmake -DBUILD_USER_MANUAL=1 -DCMAKE_BUILD_TYPE=Debug

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

elseif(WIN32 OR _WIN32)

    if(WIN10MINGW64)
        include(${CMAKE_TOOLCHAINS_PATH}/win10-mingw64-toolchain.cmake)
    endif()

endif()

message("")
message(STATUS "${BoldGreen}Starting configuration of ${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})

# Gee, do not set that to default!
# set(MAKE_TESTS 1)

option(MAKE_TESTS Off)

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 with MAKE_TESTS: ${MAKE_TESTS}.")
    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}")

# PWIZLITE
if(NOT PwizLite_FOUND)
    message(STATUS "PwizLite not yet found. Searching for it.")
    find_package(PwizLite REQUIRED)
endif()
message(STATUS "PwizLite_INCLUDE_DIRS: ${PwizLite_INCLUDE_DIRS}")
message(STATUS "PwizLite_LIBRARIES: ${PwizLite_LIBRARIES}")

# BOOST
if(NOT Boost_FOUND)
    message(STATUS "Boost not yet found. Searching for it.")
    find_package(
        Boost
        COMPONENTS iostreams thread filesystem chrono
        REQUIRED
    )
endif()
message(STATUS "Boost_LIBRARIES found ${Boost_LIB_VERSION}")
message(STATUS "Boost_INCLUDES: ${Boost_INCLUDE_DIRS}")
message(STATUS "Boost_LIB_DIRS: ${Boost_LIBRARY_DIRS}")

# QCustomPlotQt6
if(QCustomPlotQt6_FOUND)

else(QCustomPlotQt6_FOUND)
    set(QCustomPlotQt6_DIR ${CMAKE_MODULE_PATH})
    find_package(QCustomPlotQt6 REQUIRED)
endif(QCustomPlotQt6_FOUND)

message(STATUS "CMakeLists.txt - CMAKE_MODULE_PATH: ${CMAKE_MODULE_PATH}")

if(Zstd_FOUND)

else(Zstd_FOUND)
    set(Zstd_DIR ${CMAKE_MODULE_PATH})
    find_package(Zstd REQUIRED)
endif(Zstd_FOUND)

if(SQLite3_FOUND)

else(SQLite3_FOUND)
    set(SQLite3_DIR ${CMAKE_MODULE_PATH})
    find_package(SQLite3 REQUIRED)
endif(SQLite3_FOUND)

if(NOT USEPAPPSOTREE)
    set(USEPAPPSOTREE 0)
endif(NOT USEPAPPSOTREE)

# Subdirectories
#generate Doxyfile even if doxygen is not configured
configure_file(${CMAKE_SOURCE_DIR}/doc/Doxyfile.in ${CMAKE_BINARY_DIR}/doc/Doxyfile @ONLY)
message(STATUS "Adding subdirectory doc for ${PROJECT_NAME}")
add_subdirectory(doc)

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

# Doxygen
if(UNIX AND NOT APPLE)
    find_package(Doxygen)

    if(DOXYGEN_FOUND)

        add_custom_target(
            apidoc
            cp Doxyfile ${CMAKE_BINARY_DIR}/Doxyfile-build
            COMMAND echo "OUTPUT_DIRECTORY=${CMAKE_BINARY_DIR}" >> ${CMAKE_BINARY_DIR}/Doxyfile-build
            COMMAND ${DOXYGEN_EXECUTABLE} ${CMAKE_BINARY_DIR}/Doxyfile-build
            WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
        )

        add_custom_target(
            apidoc-stable
            cp Doxyfile ${CMAKE_BINARY_DIR}/Doxyfile-stable
            COMMAND echo "OUTPUT_DIRECTORY=${CMAKE_BINARY_DIR}" >> ${CMAKE_BINARY_DIR}/Doxyfile-stable
            COMMAND echo "HTML_HEADER=header.html" >> ${CMAKE_BINARY_DIR}/Doxyfile-stable
            COMMAND ${DOXYGEN_EXECUTABLE} ${CMAKE_BINARY_DIR}/Doxyfile-stable
            WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
        )

    endif(DOXYGEN_FOUND)

endif(UNIX AND NOT APPLE)

#############################################################
###########################
# 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}/${CMAKE_PROJECT_NAME}-${PAPPSOMSPP_VERSION}.tar.gz
    ${CMAKE_SOURCE_DIR}/../tarballs
    &&
    ln
    -sf
    ${CMAKE_SOURCE_DIR}/../tarballs/${CMAKE_PROJECT_NAME}-${PAPPSOMSPP_VERSION}.tar.gz
    ${CMAKE_SOURCE_DIR}/../${CMAKE_PROJECT_NAME}_${PAPPSOMSPP_VERSION}.orig.tar.gz
    &&
    ln
    -sf
    ${CMAKE_SOURCE_DIR}/../tarballs/${CMAKE_PROJECT_NAME}-${PAPPSOMSPP_VERSION}.tar.gz
    ${CMAKE_SOURCE_DIR}/../tarballs/${CMAKE_PROJECT_NAME}_${PAPPSOMSPP_VERSION}.orig.tar.gz
    WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
    COMMENT "Creating .tar.gz"
    VERBATIM
)

# Packager
set(CPACK_PACKAGE_NAME "libpappsomspp")
set(CPACK_PACKAGE_VENDOR "PAPPSO Development Team")
set(CPACK_PACKAGE_VERSION "${PAPPSOMSPP_VERSION}")
set(CPACK_PACKAGE_VERSION_MAJOR "${PAPPSOMSPP_VERSION_MAJOR}")
set(CPACK_PACKAGE_VERSION_MINOR "${PAPPSOMSPP_VERSION_MINOR}")
set(CPACK_PACKAGE_VERSION_PATCH "${PAPPSOMSPP_VERSION_PATCH}")
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "The PAPPSO C++ library for mass spectrometry")
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/COPYING")
set(CPACK_RESOURCE_FILE_AUTHORS "${CMAKE_SOURCE_DIR}/AUTHORS")
set(CPACK_RESOURCE_FILE_INSTALL "${CMAKE_SOURCE_DIR}/INSTALL")
set(CPACK_SOURCE_GENERATOR "TGZ")
set(CPACK_SOURCE_IGNORE_FILES
    \\\\.git/
    "CMakeFiles"
    "Makefile"
    "_CPack_Packages"
    "CMakeCache.txt"
    ".*\\\\.gz"
    ".*\\\\.deb"
    ".*\\\\.rpm"
    ".*\\\\.dmg"
    ".*\\\\..*\\\\.swp"
    "src/\\\\..*"
    "src/libbpp*"
    "debian/tmp"
    "debian/libbpp.*/"
    "debian/libbpp.*\\\\.so.*"
    "debian/libbpp.*\\\\.a"
    "debian/libbpp.*\\\\.substvars"
    "debian/libbpp.*\\\\.debhelper"
    "debian/debhelper\\\\.log"
    "html"
    "Core.tag"
    "Testing"
    "build/"
    "wbuild/"
    "buildwin64/"
    "build-stamp"
    "install_manifest.txt"
    "DartConfiguration.tcl"
    ${CPACK_SOURCE_IGNORE_FILES}
    ".cache"
    "Session.vim"
    "compile_commands.json"
    ".kdev4"
    "*.kdev4"
)

#dch -Dstretch "message"
#cmake ..
#make deb
# scp libpappsomspp* proteus.ideev.universite-paris-saclay.fr:/var/www/apt/incoming
# reprepro -Vb /var/www/apt processincoming default
# apt-get remove libpappsomspp*
#
#  debuild -S -sa
# dput -f olivier-langella *changes

#dpkg-deb -x libpappsomspp-qt4_0.0.4-1_amd64.deb libpappsomspp-qt4_0.0.4-1
#dpkg-gensymbols -v0 -plibpappsomspp-qt4 -Plibpappsomspp-qt4_0.0.4-1 -Osymbols
#cp symbols ../debian/libpappsomspp-qt4.symbols

#dpkg-deb -x libpappsomspp-qt5_0.0.4-1_amd64.deb libpappsomspp-qt5_0.0.4-1
#dpkg-gensymbols -v0 -plibpappsomspp-qt5 -Plibpappsomspp-qt5_0.0.4-1 -Osymbols
#cp symbols ../debian/libpappsomspp-qt5.symbols

if(MACOS)
    set(CPACK_GENERATOR "Bundle")
endif()

set(CPACK_SOURCE_PACKAGE_FILE_NAME
    "${CMAKE_PROJECT_NAME}-${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}"
)
set(CPACK_DEBSOURCE_PACKAGE_FILE_NAME
    "lib${CMAKE_PROJECT_NAME}_${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}.orig"
)
include(CPack)

if(UNIX)
    #This creates deb packages:

    add_custom_target(
        targz
        cpack
        -G
        TGZ
        --config
        CPackSourceConfig.cmake
        &&
        tar
        xvfz
        libpappsomspp-${PAPPSOMSPP_VERSION}.tar.gz
        &&
        cp
        -r
        ${CMAKE_SOURCE_DIR}/debian
        libpappsomspp-${PAPPSOMSPP_VERSION}
        WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
        COMMENT "Creating .tar.gz"
        VERBATIM
    )

    add_custom_target(
        deb
        ln
        -s
        libpappsomspp-${PAPPSOMSPP_VERSION}.tar.gz
        libpappsomspp_${PAPPSOMSPP_VERSION}.orig.tar.gz
        &&
        cd
        libpappsomspp-${PAPPSOMSPP_VERSION}
        &&
        dpkg-buildpackage
        -sa
        DEPENDS targz
        WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
        COMMENT "Creating Debian package"
        VERBATIM
    )

    add_custom_target(
        debsrc
        ln
        -s
        libpappsomspp-${PAPPSOMSPP_VERSION}.tar.gz
        libpappsomspp_${PAPPSOMSPP_VERSION}.orig.tar.gz
        &&
        cd
        libpappsomspp-${PAPPSOMSPP_VERSION}
        &&
        debuild
        -S
        -sa
        DEPENDS targz
        WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
        COMMENT "Creating Debian source package"
        VERBATIM
    )

    file(GLOB changesdebs "${CMAKE_BINARY_DIR}/pappsomspp_*.dsc")

    foreach(libfile ${changesdebs})
        set(changesdeb "${libfile}")
    endforeach(libfile)

    message("changes debian file : ${changesdeb}")
    #lintian -IEi --pedantic tandem-mass_2013.06.15-1_amd64.changes
    add_custom_target(
        lintian
        lintian -IEi --pedantic ${changesdeb}
        DEPENDS deb
        WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
        COMMENT "lintian check"
        VERBATIM
    )

    #dpkg-deb -x libpappsomspp-qt4_0.0.4-1_amd64.deb libpappsomspp-qt4_0.0.4-1
    #dpkg-gensymbols -v0 -plibpappsomspp-qt4 -Plibpappsomspp-qt4_0.0.4-1 -Osymbols
    #cp symbols ../debian/libpappsomspp-qt4.symbols

    #dpkg-deb -x libpappsomspp-qt5_0.0.4-1_amd64.deb libpappsomspp-qt5_0.0.4-1
    #dpkg-gensymbols -v0 -plibpappsomspp-qt5 -Plibpappsomspp-qt5_0.0.4-1 -Osymbols
    #cp symbols ../debian/libpappsomspp-qt5.symbols

endif(UNIX)

if(MAKE_TESTS)

    message("MAKE_TESTS was set to ${MAKE_TESTS}")

    enable_testing()

    include(CTest)

    if(BUILD_TESTING)

        message("BUILD_TESTING was set to ${BUILD_TESTING}")

        add_subdirectory(tests)

    endif(BUILD_TESTING)

endif(MAKE_TESTS)
