cmake_minimum_required(VERSION 3.16)
project(cyphal_hardware_interface LANGUAGES C CXX)

if(CMAKE_CXX_COMPILER_ID MATCHES "(GNU|Clang)")
  add_compile_options(-Wall -Wextra)
endif()

enable_language(C CXX)

# find dependencies
set(THIS_PACKAGE_INCLUDE_DEPENDS
  hardware_interface::hardware_interface
  hardware_interface::mock_components
  pluginlib::pluginlib
  rclcpp::rclcpp
  #rclcpp_lifecycle::rclcpp_lifecycle
)

# find dependencies
find_package(ament_cmake REQUIRED)
find_package(hardware_interface REQUIRED)
find_package(pluginlib REQUIRED)
find_package(rclcpp REQUIRED)
#find_package(rclcpp_lifecycle REQUIRED)


add_library(
  cyphal_hardware_interface
  SHARED
  hardware/cyphal_system.cpp
  hardware/socketcan.cpp
  lib/libcanard/libcanard/canard.c
  #hardware/canard.c
)

target_include_directories(cyphal_hardware_interface 
  PRIVATE 
  lib/libcanard/libcanard/
)

function(get_all_targets var)
    set(targets)
    get_all_targets_recursive(targets ${CMAKE_CURRENT_SOURCE_DIR})
    set(${var} ${targets} PARENT_SCOPE)
endfunction()

macro(get_all_targets_recursive targets dir)
    get_property(subdirectories DIRECTORY ${dir} PROPERTY SUBDIRECTORIES)
    foreach(subdir ${subdirectories})
        get_all_targets_recursive(${targets} ${subdir})
    endforeach()

    get_property(current_targets DIRECTORY ${dir} PROPERTY BUILDSYSTEM_TARGETS)
    list(APPEND ${targets} ${current_targets})
endmacro()

target_compile_features(cyphal_hardware_interface PUBLIC cxx_std_17)
target_include_directories(cyphal_hardware_interface PUBLIC
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/hardware/include>
$<INSTALL_INTERFACE:include/cyphal_hardware_interface>
${cyphal_INCLUDE_DIR}
)

target_link_libraries(cyphal_hardware_interface PUBLIC
  hardware_interface::hardware_interface
  hardware_interface::mock_components
  pluginlib::pluginlib
  rclcpp::rclcpp
  #rclcpp_lifecycle::rclcpp_lifecycyle
)

# Causes the visibility macros to use dllexport rather than dllimport,
# which is appropriate when building the dll but not consuming it.
target_compile_definitions(${PROJECT_NAME} PRIVATE "CYPHAL_HARDWARE_INTERFACE_BUILDING_DLL")

# Export hardware plugins
pluginlib_export_plugin_description_file(hardware_interface cyphal_hardware_interface.xml)

# INSTALL
install(
  DIRECTORY hardware/include/
  DESTINATION include/cyphal_hardware_interface
)
install(
  DIRECTORY description/launch description/ros2_control description/urdf
  DESTINATION share/cyphal_hardware_interface
)
install(
  DIRECTORY bringup/launch bringup/config
  DESTINATION share/cyphal_hardware_interface
)
install(TARGETS cyphal_hardware_interface
  EXPORT export_cyphal_hardware_interface
  ARCHIVE DESTINATION lib
  LIBRARY DESTINATION lib
  RUNTIME DESTINATION bin
)

if(BUILD_TESTING)
  find_package(ament_cmake_pytest REQUIRED)

  #ament_add_pytest_test(example_2_urdf_xacro test/test_urdf_xacro.py)
  #ament_add_pytest_test(view_example_2_launch test/test_view_robot_launch.py)
endif()

## EXPORTS
ament_export_targets(export_cyphal_hardware_interface HAS_LIBRARY_TARGET)
ament_export_dependencies(${THIS_PACKAGE_INCLUDE_DEPENDS})
ament_package()
