##==============================================================================
##  ROTGEN - Runtime Overlay for Eigen
##  Copyright : CODE RECKONS
##  SPDX-License-Identifier: BSL-1.0
##==============================================================================
cmake_minimum_required(VERSION 3.22)
enable_testing()

##==============================================================================
## Setup project
##==============================================================================
set(ROTGEN_MAJOR_VERSION 0)
set(ROTGEN_MINOR_VERSION 0)
set(ROTGEN_PATCH_VERSION 1)
set(ROTGEN_VERSION ${ROTGEN_MAJOR_VERSION}.${ROTGEN_MINOR_VERSION}.${ROTGEN_PATCH_VERSION})

set(PROJECT_VERSION   ${ROTGEN_VERSION})
project(ROTGEN VERSION ${PROJECT_VERSION} DESCRIPTION "Runtime Overlay for Eigen" LANGUAGES CXX)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${ROTGEN_SOURCE_DIR}/cmake )

##==============================================================================
## Prevent in-source build
##==============================================================================
if (${PROJECT_SOURCE_DIR} STREQUAL ${PROJECT_BINARY_DIR})
  message(FATAL_ERROR "[${PROJECT_NAME}]: In-source build is not supported")
endif()

##==============================================================================
## Handle options
##==============================================================================
option(ROTGEN_FORCE_DYNAMIC                 "Force dynamic configuration for rotgen"  OFF)
option(ROTGEN_ENABLE_EXPRESSION_TEMPLATES    "Enable expression templates"            OFF)
set(ROTGEN_MAX_SIZE "" CACHE STRING "Max matrix number of elements for rotgen (integer)")

include(${ROTGEN_SOURCE_DIR}/cmake/options.cmake)
handle_option(ROTGEN_COMPILE_DEFS)

##==============================================================================
## Sources & Public Headers lists
##==============================================================================
if(ROTGEN_FORCE_DYNAMIC)
  set ( SOURCES
        src/map/impl.cpp
        src/matrix/impl.cpp
        src/quaternion/impl.cpp
        src/block/impl.cpp
        src/svd/impl.cpp
        src/info.cpp
        src/format.cpp
      )
else()
  set ( SOURCES
        src/info.cpp
      )
endif()

##==============================================================================
## Setup the library's dependencies
##==============================================================================
find_package (Eigen3 3.4 REQUIRED NO_MODULE)

##==============================================================================
## Setup the library's build
##==============================================================================
if(NOT MSVC)
  set(CMAKE_CXX_VISIBILITY_PRESET hidden)
endif()

add_library(rotgen SHARED ${SOURCES})

set_target_properties(rotgen PROPERTIES VERSION       ${PROJECT_VERSION})
set_target_properties(rotgen PROPERTIES SOVERSION     ${PROJECT_VERSION_MAJOR})

target_compile_options(rotgen PUBLIC -std=c++20 -Werror -Wall -Wextra -Wshadow -Wunused-variable)

if(CMAKE_CXX_COMPILER_ID STREQUAL GNU)
  target_compile_options(rotgen PUBLIC -Wno-array-bounds)
endif()

target_compile_definitions(rotgen PUBLIC ${ROTGEN_COMPILE_DEFS})
add_library(rotgen::rotgen ALIAS rotgen)

target_include_directories(rotgen PUBLIC
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
    $<INSTALL_INTERFACE:include>
)

target_link_libraries (rotgen PRIVATE Eigen3::Eigen)

##==============================================================================
## Setup the library's installation target
##==============================================================================
include(${ROTGEN_SOURCE_DIR}/cmake/config/rotgen-install.cmake)

##==============================================================================
## Setup the library's Tests
##==============================================================================
add_subdirectory(test)
