# ------------------------------------------------------------------------------
#        Multi primitive-to-primitive (MP2P) ICP C++ library
#
# Copyright (C) 2018-2020, Jose Luis Blanco-Claraco, contributors (AUTHORS.md)
# All rights reserved.
# Released under BSD 3-Clause License. See COPYING.
# ------------------------------------------------------------------------------

# Minimum CMake version: deprecated if <3.5 (as of Apr 2024)
cmake_minimum_required(VERSION 3.22...3.31)  # Ubuntu 22.04+

if("$ENV{ROS_VERSION}" STREQUAL "2")
  set(DETECTED_ROS2 TRUE)
elseif("$ENV{ROS_VERSION}" STREQUAL "1")
  set(DETECTED_ROS1 TRUE)
endif()

if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
  set(default_build_type "Release")
  message(STATUS "Setting build type to '${default_build_type}' as none was specified.")
  set(CMAKE_BUILD_TYPE "${default_build_type}" CACHE STRING "Choose the type of build." FORCE)
endif()
# Set the possible values of build type for cmake-gui
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo" "SanitizeAddress" "SanitizeThread" "Coverage")

# Set flags for the "Coverage" build type. This is robust for use with colcon.
set(CMAKE_CXX_FLAGS_COVERAGE "-g -O0 --coverage -fprofile-update=atomic" CACHE STRING "Flags for C++ coverage build")
set(CMAKE_C_FLAGS_COVERAGE "-g -O0 --coverage -fprofile-update=atomic" CACHE STRING "Flags for C coverage build")
set(CMAKE_EXE_LINKER_FLAGS_COVERAGE "--coverage" CACHE STRING "Linker flags for coverage build")
set(CMAKE_SHARED_LINKER_FLAGS_COVERAGE "--coverage" CACHE STRING "Linker flags for coverage build")

# Tell CMake we'll use C++ for use in its tests/flags
project(mp2p_icp_core LANGUAGES CXX)

# GCC < 12 with LTO (enabled by default in Debian/Ubuntu package builds) may
# wrongly devirtualize calls on MRPT classes whose virtual methods live in
# the MRPT shared libraries into __builtin_unreachable(), silently removing
# code. Disable LTO for such compilers.
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 12)
  add_compile_options(-fno-lto)
endif()

# This package builds as a plain "cmake" build_type under colcon (not
# ament_cmake or catkin), but colcon still passes these catkin-only
# variables when invoked with --symlink-install. Consume them here to
# silence the "Manually-specified variables were not used" CMake warning.
set(_mp2p_icp_ignored_vars "${CATKIN_INSTALL_INTO_PREFIX_ROOT}" "${CATKIN_SYMLINK_INSTALL}")
unset(_mp2p_icp_ignored_vars)

# MOLA CMake scripts: "mola_xxx()"
# NOTE: standalone (non-colcon) builds are not supported; mola_common is
# expected to be provided by the ROS/colcon workspace, same as every other
# sibling MOLAorg package.
find_package(mola_common REQUIRED)

# 3rd party:
add_subdirectory(3rdparty)

# find dependencies:
# NOTE: "gui" is intentionally NOT requested here so this package (and
# everything that depends on it) has no GUI/display dependency. mrpt::mrpt_viz,
# mrpt::mrpt_system and mrpt::mrpt_expr remain available transitively via
# maps->obs and tfest->poses->bayes->config.
find_package(mrpt_containers REQUIRED)
find_package(mrpt_tfest REQUIRED)
find_package(mrpt_maps REQUIRED)
find_package(mrpt_topography REQUIRED)
# MRPT 3.x no longer re-exports Eigen transitively from mrpt_math/mrpt_poses;
# code including <Eigen/...> directly needs this itself.
find_package(Eigen3 REQUIRED NO_MODULE)
find_package(Threads REQUIRED)
find_package(TBB) # optional

if(TBB_FOUND)
  option(MP2PICP_USE_TBB "If found TBB, this option controls whether to use it or not" ON)
endif()

find_package(mola_imu_preintegration) # Used for advanced deskew methods in FilterDeskew
if (NOT mola_imu_preintegration_FOUND)
  message(WARNING "mola_imu_preintegration not found: advanced deskew will not be available")
endif()

#----
# Extract version from package.xml
# Example line:" <version>0.3.2</version>"
file(READ package.xml contentPackageXML)
string(REGEX MATCH "<version>([0-9\.]*)</version>" _ ${contentPackageXML})
set(MP2P_ICP_VERSION ${CMAKE_MATCH_1})
message(STATUS "MP2P_ICP version: ${MP2P_ICP_VERSION} (detected in package.xml)")
string(REGEX MATCH "^([0-9]+)\\.([0-9]+)\\.([0-9]+)" _ ${MP2P_ICP_VERSION})
set(MP2P_ICP_MAJOR_VERSION ${CMAKE_MATCH_1})
set(MP2P_ICP_MINOR_VERSION ${CMAKE_MATCH_2})
set(MP2P_ICP_PATCH_VERSION ${CMAKE_MATCH_3})
#----


# -----------------------
# define library targets:
# -----------------------

# Helper parameter source library:
add_subdirectory(mp2p_icp_common)

# Metric map container library:
add_subdirectory(mp2p_icp_map)

# Main mp2p_icp library:
add_subdirectory(mp2p_icp)

# Basic filters library:
add_subdirectory(mp2p_icp_filters)

# -----------------------
# define tests:
# -----------------------
option(MP2PICP_BUILD_TESTING "Build unit tests" ON)
if(MP2PICP_BUILD_TESTING)
  enable_testing()
  add_subdirectory(tests)
endif()

# -----------------------
# define apps:
# -----------------------
option(MP2PICP_BUILD_APPLICATIONS "Build mp2p_icp applications" ON)
if(MP2PICP_BUILD_APPLICATIONS)
  add_subdirectory(apps)
endif()

if(DETECTED_ROS1)
  # Find catkin macros and libraries
  # if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz)
  # is used, also find other catkin packages
  find_package(catkin
    REQUIRED
    #COMPONENTS
    #roscpp tf2 dynamic_reconfigure std_msgs nav_msgs sensor_msgs visualization_msgs
    #tf2_geometry_msgs
  )

  catkin_package(
  #CATKIN_DEPENDS tf2 tf2_geometry_msgs
  #  INCLUDE_DIRS include
  #  LIBRARIES mrpt_localization
  #  DEPENDS mrpt
  )
endif()