cmake_minimum_required(VERSION 3.20)

project(
  kalman
  VERSION 0.2.3
  DESCRIPTION "Very fast Kalman filters."
  LANGUAGES CXX
)

include(GNUInstallDirs)

option(KALMAN_BUILD_PYTHON "Build the nanobind Python extension" OFF)
option(KALMAN_BUILD_TESTS "Build smoke tests" OFF)

add_library(kalman src/kalman.cpp)
add_library(kalman::kalman ALIAS kalman)

target_compile_features(kalman PUBLIC cxx_std_23)
target_include_directories(
  kalman
  PUBLIC
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
    $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)

set_target_properties(
  kalman
  PROPERTIES
    EXPORT_NAME kalman
    POSITION_INDEPENDENT_CODE ON
    VERSION ${PROJECT_VERSION}
    SOVERSION ${PROJECT_VERSION_MAJOR}
)

if(KALMAN_BUILD_TESTS)
  enable_testing()
  add_executable(kalman_smoke_test tests/cpp/kalman_smoke_test.cpp)
  target_link_libraries(kalman_smoke_test PRIVATE kalman::kalman)
  add_test(NAME kalman_smoke_test COMMAND kalman_smoke_test)
endif()

if(KALMAN_BUILD_PYTHON)
  message(STATUS "fast-kalman is compiling its C++/nanobind extension from source. This can take a few minutes.")
  find_package(Python COMPONENTS Interpreter Development.Module REQUIRED)
  find_package(nanobind CONFIG REQUIRED)

  nanobind_add_module(_core src/python/bindings.cpp)
  target_link_libraries(_core PRIVATE kalman::kalman)
  target_compile_features(_core PRIVATE cxx_std_23)
  install(TARGETS _core LIBRARY DESTINATION kalman)
endif()

install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
install(
  TARGETS kalman
  EXPORT kalmanTargets
  ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
  LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
  RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)

install(
  EXPORT kalmanTargets
  NAMESPACE kalman::
  DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/kalman
)

include(CMakePackageConfigHelpers)
write_basic_package_version_file(
  "${CMAKE_CURRENT_BINARY_DIR}/kalmanConfigVersion.cmake"
  VERSION ${PROJECT_VERSION}
  COMPATIBILITY SameMajorVersion
)

configure_package_config_file(
  cmake/kalmanConfig.cmake.in
  "${CMAKE_CURRENT_BINARY_DIR}/kalmanConfig.cmake"
  INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/kalman
)

install(
  FILES
    "${CMAKE_CURRENT_BINARY_DIR}/kalmanConfig.cmake"
    "${CMAKE_CURRENT_BINARY_DIR}/kalmanConfigVersion.cmake"
  DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/kalman
)
