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

set(PROJECT libodsstream)
project(${PROJECT} CXX C)

set(LIBODSSTREAM_VERSION_MAJOR "0")
set(LIBODSSTREAM_VERSION_MINOR "9")
set(LIBODSSTREAM_VERSION_PATCH "16")
set(LIBODSSTREAM_LIB_NAME "libodsstream")
set(LIBODSSTREAM_VERSION "${LIBODSSTREAM_VERSION_MAJOR}.${LIBODSSTREAM_VERSION_MINOR}.${LIBODSSTREAM_VERSION_PATCH}")
set(LIBODSSTREAM_LIB_VERSION ${LIBODSSTREAM_VERSION})
set(LIBODSSTREAM_LIB_SOVERSION ${LIBODSSTREAM_VERSION_MAJOR})

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

include(GNUInstallDirs)

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

# 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)
#message("CMAKE_MODULE_PATH:" ${CMAKE_MODULE_PATH})

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

set(CMAKE_INCLUDE_CURRENT_DIR ON)

# 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)
# Instruct CMake to run moc automatically when needed.
set(CMAKE_AUTOMOC ON)

message("\n${BoldRed}Configuring build for project ${PROJECT}${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++20
set(CMAKE_CXX_STANDARD 20)
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)
#message(STATUS "${BoldGreen}Setting definition -pedantic.${ColourReset}")
#add_definitions(-pedantic)

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

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

#############################################################
#############################################################
# 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-$ENV{USER}.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(UNIX AND NOT APPLE)

    # Run the following cmake command line:
    # cmake -DCMAKE_BUILD_TYPE=Debug

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

elseif(WIN32 OR _WIN32)

    # Run the following cmake command line:
    # cmake -DCMAKE_BUILD_TYPE=Release ../development

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

endif()

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

#############################################################
###########################
# CREATE THE SOURCE PACKAGE
set(CPACK_CMAKE_GENERATOR "Unix Makefiles")
set(CPACK_GENERATOR "STGZ;TGZ;TZ")
set(CPACK_OUTPUT_CONFIG_FILE "./CPackConfig.cmake")
#set(CPACK_PACKAGE_DESCRIPTION_FILE ${LIBODSSTREAM_SOURCE_DIR}/COPYING)
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "library to read and write ODS files using streams")
set(CPACK_PACKAGE_EXECUTABLES "libodsstream")
set(CPACK_SOURCE_PACKAGE_FILE_NAME "libodsstream-${LIBODSSTREAM_VERSION}")
set(CPACK_SYSTEM_NAME "Linux-i686")
set(CPACK_PACKAGE_FILE_NAME "libodsstream-${LIBODSSTREAM_VERSION}-${CPACK_SYSTEM_NAME}")
set(CPACK_PACKAGE_INSTALL_DIRECTORY "libodsstream ${LIBODSSTREAM_VERSION}")
set(CPACK_PACKAGE_INSTALL_REGISTRY_KEY "libodsstream ${LIBODSSTREAM_VERSION}")
set(CPACK_PACKAGE_NAME "libodsstream")
set(CPACK_PACKAGE_VENDOR "PAPPSO")
set(CPACK_PACKAGE_VERSION ${LIBODSSTREAM_VERSION})
set(CPACK_RESOURCE_FILE_LICENSE ${CMAKE_SOURCE_DIR}/debian/copyright)
set(CPACK_RESOURCE_FILE_README ${CMAKE_SOURCE_DIR}/README)
set(CPACK_RESOURCE_FILE_WELCOME ${CMAKE_SOURCE_DIR}/README)
set(CPACK_SOURCE_GENERATOR "TGZ;TZ")
set(CPACK_SOURCE_OUTPUT_CONFIG_FILE "./CPackSourceConfig.cmake")
set(CPACK_SOURCE_STRIP_FILES "")
set(CPACK_SYSTEM_NAME "Linux-i686")
set(CPACK_TOPLEVEL_TAG "Linux-i686")
set(CPACK_SOURCE_PACKAGE_FILE_NAME "libodsstream-${LIBODSSTREAM_VERSION}")

set(CPACK_SOURCE_IGNORE_FILES
    ".cache"
    ".*\\\\.swp"
    ".*\\\\.swo"
    ".*\\\\.tar\\\\.gz"
    "moc_.*cxx"
    "\\\\.#.*"
    ".*\\\\.aux"
    ".*\\\\.bbl"
    ".*\\\\.blg"
    ".*\\\\.log"
    ".*\\\\.out"
    ".*\\\\.toc"
    "Session\\\\.vim"
    "/devel_archives/"
    "/doc\\\\/html/"
    "/doc\\\\/latex/"
    "install_manifest.txt"
    "CMakeCache.txt"
    "CPackConfig.cmake"
    "CPackSourceConfig.cmake"
    "/CMakeFiles/"
    "/_CPack_Packages/"
    "/Debug/"
    "/Release/"
    "/tests/"
    "/\\\\.externalToolBuilders/"
    "/\\\\.git/"
    "\\\\.gitattributes"
    "\\\\cache/"
    "development\\\\.kdev4"
    "/\\\\.kdev4/"
    "/\\\\.settings/"
    "\\\\.cdtbuild"
    "\\\\.cdtproject"
    "\\\\.project"
    "\\\\.cproject"
    "/win32/"
    "/win64/"
    "/build/"
    "/buildwin64/"
    "/cbuild/"
    "/wbuild/"
    "/bin/"
    "/buildmingw/"
    "test\\\\.ods"
    "buildwin32.cmd"
    "libodsstream.so"
    "OpenDocument-v1.0-os.pdf"
    "compile_commands.json"
)

set(CPACK_PACKAGE_EXECUTABLES "libodsstream" "libodsstream")

# for debian package :
set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Olivier Langella <olivier.langella@u-psud.fr>")
set(DEBIAN_PACKAGE_BUILDS_DEPENDS "Olivier Langella <olivier.langella@u-psud.fr>")

include(CPack)

add_subdirectory(src)

add_subdirectory(doc)

add_custom_target(
    targz
    cpack
    -G
    TGZ
    --config
    CPackSourceConfig.cmake
    &&
    tar
    xvfz
    libodsstream-${LIBODSSTREAM_VERSION}.tar.gz
    WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
    COMMENT "Creating .tar.gz"
    VERBATIM
)

add_custom_target(
    deb
    ln
    -s
    libodsstream-${LIBODSSTREAM_VERSION}.tar.gz
    libodsstream_${LIBODSSTREAM_VERSION}.orig.tar.gz
    &&
    cd
    libodsstream-${LIBODSSTREAM_VERSION}
    &&
    dpkg-buildpackage
    -B
    DEPENDS targz
    WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
    COMMENT "Creating Debian package"
    VERBATIM
)

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

add_custom_target(
    lintian
    lintian -IEi --pedantic ${changesdeb}
    DEPENDS deb
    WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
    COMMENT "lintian check"
    VERBATIM
)

if(MAKE_TEST)
    enable_testing()
    include(CTest)
    if(BUILD_TESTING)
        add_subdirectory(test)
    endif(BUILD_TESTING)
endif(MAKE_TEST)

message(STATUS CMAKE_MODULE_PATH: ${CMAKE_MODULE_PATH})

# Install cmake module
install(
    FILES ${CMAKE_UTILS_PATH}/modules/FindOdsStream.cmake
    DESTINATION lib${LIB_SUFFIX}/cmake/odsstream
)
# Install cmake config

# Older version
#configure_file (${CMAKE_UTILS_PATH}/modules/OdsStreamConfig.cmake.in ${CMAKE_SOURCE_DIR}/OdsStreamConfig.cmake)
#install(FILES ${CMAKE_SOURCE_DIR}/OdsStreamConfig.cmake DESTINATION lib${LIB_SUFFIX}/cmake/odsstream)

# More modern CMake version

install(
    EXPORT OdsStreamTargets
    FILE OdsStreamTargets.cmake
    NAMESPACE OdsStream::
    DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/odsstream
)

include(CMakePackageConfigHelpers)

configure_package_config_file(
    ${CMAKE_SOURCE_DIR}/CMakeStuff/modules/OdsStreamConfig.cmake.in "${CMAKE_CURRENT_BINARY_DIR}/OdsStreamConfig.cmake"
    INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/odsstream
)

install(
    FILES "${CMAKE_CURRENT_BINARY_DIR}/OdsStreamConfig.cmake"
    DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/odsstream
)

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