cmake_minimum_required(VERSION 3.20)

project(naval LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

set(USE_ADDRESS_SANITIZER OFF CACHE BOOL "Use AddressSanitizer (supported only with recent Clang and GCC)")
set(LLKA_DIR "" CACHE PATH "Path to libLLKA library")

option(DEOXYURIDINE_IS_STANDARD_BASE "Consider deoxyuridine a standard base" OFF)

if (UNIX)
    include(GNUInstallDirs)
else ()
    set(CMAKE_INSTALL_LIBDIR "lib")
    set(CMAKE_INSTALL_INCLUDEDIR "include")
    set(CMAKE_INSTALL_BINDIR "bin")
endif ()

include_directories(
    ${INCLUDE_DIRECTORIES}
    SYSTEM "${LLKA_DIR}/${CMAKE_INSTALL_INCLUDEDIR}"
)

link_directories(
    ${LINK_DIRECTORIES}
    "${LLKA_DIR}/${CMAKE_INSTALL_LIBDIR}"
)

set(LLKA_PLATFORM_DEFINITIONS "")
add_definitions("-D_USE_MATH_DEFINES")

if (DEOXYURIDINE_IS_STANDARD_BASE)
    add_definitions("-DDEOXYURIDINE_IS_STANDARD_BASE")
endif ()

if (UNIX)
    if (${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU" OR
        ${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang")
        add_compile_options(-Wall -Wextra -pedantic -fvisibility=hidden -msse2)
        if (CMAKE_BUILD_TYPE STREQUAL "Release")
            if (${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU" AND
                CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 9.1.0 OR
                CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL 9.1.0)
                add_compile_options(-flto)
            endif ()
        else ()
            add_compile_options(-g)
        endif ()

        if (USE_ADDRESS_SANITIZER)
            add_compile_options(-fno-omit-frame-pointer -fsanitize=address -fsanitize=undefined -fsanitize=leak -fstack-protector-strong)
            add_link_options(-fsanitize=address -fsanitize=undefined -fsanitize=leak)
        endif ()

        set(LLKA_PLATFORM_DEFINITIONS -DLLKA_COMPILER_GCC_LIKE)
        set(DEFAULT_SYMVER_LINK "-Wl,--default-symver")
    endif ()
elseif (WIN32)
    set(LLKA_PLATFORM_DEFINITIONS "${LLKA_PLATFORM_DEFINITIONS}" -DWIN32_LEAN_AND_MEAN -DNOMINMAX)

    if (MINGW OR MSYS)
        if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 7.0.0)
            message(FATAL_ERROR "MinGW 7.0.0 or newer is required to build naval")
        endif ()
        add_compile_options(-Wall -Wextra -pedantic -Wno-unused-function -fvisibility=hidden -msse2)

        if (USE_ADDRESS_SANITIZER)
            add_compile_options(-fno-omit-frame-pointer -fsanitize=address -fsanitize=undefined -fsanitize=leak -fstack-protector-strong)
            add_link_options(-fsanitize=address -fsanitize=undefined -fsanitize=leak)
        endif ()

        if (MINGW)
            set(LLKA_PLATFORM_DEFINITIONS -DLLKA_COMPILER_MINGW)
        else ()
            set(LLKA_PLATFORM_DEFINITIONS -DLLKA_COMPILER_MSYS)
        endif ()

        set(DEFAULT_SYMVER_LINK "-Wl,--default-symver")
    elseif (MSVC)
        set(CMAKE_CONFIGURATION_TYPES "Debug;Release;RelWithDebInfo;MinSizeRel")

        set(CMAKE_CXX_FLAGS_RELEASE "/GL")
        set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "/INCREMENTAL:NO /LTCG")
        set(CMAKE_STATIC_LINKER_FLAGS_RELEASE "/INCREMENTAL:NO /LTCG")

        set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "/GL")
        set(CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO "/debug /INCREMENTAL:NO /LTCG")
        set(CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO "/debug /INCREMENTAL:NO /LTCG")
	set(LLKA_PLATFORM_DEFINITIONS "${LLKA_PLATFORM_DEFINITIONS}" -DLLKA_COMPILER_MSVC -DLLKA_HAVE_SAD_LADY_COMPILER -DUNICODE -D_UNICODE)
        set(DEFAULT_SYMVER_LINK " ")
    else()
        message(FATAL_ERROR "Compiler not recognized or not supported")
    endif()
else ()
    message(FATAL_ERROR "Platform not recognized or not supported")
endif ()

set(
    naval_SRCS
    "src/main.cpp"
    "src/angles_report.cpp"
    "src/bonds_report.cpp"
    "src/geometry_report.cpp"
    "src/measure.cpp"
    "src/proscos_mapper.cpp"
    "src/proscos_reader.cpp"
    "src/proscos_report.cpp"
    "src/restraints_mapping.cpp"
    "src/restraints_reader.cpp"
    "src/validate.cpp"
    "src/validation_report.cpp"
)

add_executable(
    naval
    ${naval_SRCS}
)

target_compile_definitions(naval PRIVATE ${LLKA_PLATFORM_DEFINITIONS})

target_link_libraries(
    naval
    PRIVATE LLKA
)
