Skip to content

Instantly share code, notes, and snippets.

@Meltwin
Created March 21, 2023 19:56
Show Gist options
  • Save Meltwin/db07302ffff53cad63185b10e69692f1 to your computer and use it in GitHub Desktop.
Save Meltwin/db07302ffff53cad63185b10e69692f1 to your computer and use it in GitHub Desktop.
Complete template for CMakeLists for ROS1 / ROS2 packages
cmake_minimum_required(VERSION 3.5)
project(template_prj VERSION 0.0.1)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_BUILD_TYPE Release)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
add_compile_options(-Wall -Wextra -Wpedantic -std=c++17)
endif()
find_package(ament_cmake_auto REQUIRED)
ament_auto_find_build_dependencies()
# =================================================================
# ROS 1
# =================================================================
#find ROS 1 packages we depend on
set(ROS1_ROOT "/opt/ros/noetic")
set(ROS1_LIBS roscpp rosconsole roscpp_serialization rostime xmlrpcpp)
# if libraries in ROS1_ROOT, explicitely give their location
if(EXISTS ${ROS1_ROOT})
foreach(ROS1_LIB ${ROS1_LIBS})
add_library(${ROS1_LIB} UNKNOWN IMPORTED)
set_property(TARGET ${ROS1_LIB} PROPERTY IMPORTED_LOCATION "${ROS1_ROOT}/lib/lib${ROS1_LIB}.so")
endforeach()
endif()
# =================================================================
# LEGACY CODE (FOXY, GALACTIC COMPATIBILITY)
# =================================================================
if("$ENV{ROS_DISTRO}" STREQUAL "galactic" OR "$ENV{ROS_DISTRO}" STREQUAL "foxy")
set(LEGACY_IDL TRUE)
add_compile_definitions(LEGACY_IDL)
else()
set(LEGACY_IDL FALSE)
endif()
# =================================================================
# INTERFACE
# =================================================================
file(GLOB msg_files RELATIVE "${CMAKE_CURRENT_LIST_DIR}"
"${CMAKE_CURRENT_LIST_DIR}/msg/*.msg"
"${CMAKE_CURRENT_LIST_DIR}/srv/*.srv"
"${CMAKE_CURRENT_LIST_DIR}/action/*.action"
)
set(dependencies
...)
rosidl_generate_interfaces(${PROJECT_NAME}
${msg_files}
DEPENDENCIES ${dependencies})
ament_export_dependencies(rosidl_default_runtime)
if(NOT ${LEGACY_IDL})
rosidl_get_typesupport_target(cpp_typesupport_target "${PROJECT_NAME}" "rosidl_typesupport_cpp")
endif()
macro(add_message node_name)
if(${LEGACY_IDL})
rosidl_target_interfaces(${node_name} "${PROJECT_NAME}" "rosidl_typesupport_cpp")
else()
target_link_libraries(${node_name} "${cpp_typesupport_target}")
endif()
endmacro()
# =================================================================
# QT 5 UI Generator
# =================================================================
find_package(Qt5 COMPONENTS Core Widgets WebKit WebKitWidgets REQUIRED)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOUIC_SEARCH_PATHS resource/ui)
set(CMAKE_CXX_FLAGS_COVERAGE "${CMAKE_CXX_FLAGS_RELEASE} -fprofile-arcs -ftest-coverage")
set_target_properties(Qt5::Core PROPERTIES MAP_IMPORTED_CONFIG_COVERAGE "RELEASE")
# Excluding files rosidl files from autouic generation
file(GLOB_RECURSE exclude_file
# You may have to exclude other dirs here
"${CMAKE_CURRENT_BINARY_DIR}/ros*/*.[hc]"
"${CMAKE_CURRENT_BINARY_DIR}/ros*/*.[hc]pp"
)
foreach(X IN LISTS exclude_file)
set_property(SOURCE ${X} PROPERTY SKIP_AUTOUIC ON)
endforeach()
# =================================================================
# EIGEN3
# =================================================================
find_package(Eigen3 REQUIRED)
include_directories(${EIGEN3_INCLUDE_DIRS})
add_definitions(${EIGEN3_DEFINITIONS})
# =================================================================
# OUTPUT
# =================================================================
ament_auto_add_executable(template_exec
... cpp files
)
target_include_directories(template_exec PRIVATE include ${ROS1_ROOT}/include)
target_link_libraries(template_exec ${ROS1_LIBS} Qt5::Core Qt5::Widgets Qt5::WebKit Qt5::WebKitWidgets)
add_message(template_exec)
# =================================================================
# EXPORT OTHERS
# =================================================================
install(DIRECTORY
resource/launch
DESTINATION share/${PROJECT_NAME})
ament_auto_package()
@Meltwin
Copy link
Author

Meltwin commented Mar 21, 2023

Introduction

This CMakeLists is a template to fill with your own package configuration.
It is focused for C++ programming and so implement Eigen3 and Qt5 widgets features.

Legacy support & interface

Older version of ROS2 (i.e. Foxy and Galactic) have some slight differences from Humble ROS2. It can happen when you are using actions or in message generation.
To respond to this issue, a preprocessor constant has been added (LEGACY_IDL) and it is also present in the CMakeLists. Thus, you can use it as indicated below:

// In .cpp / .hpp

// Some code before

#ifdef LEGACY_IDL
   // Put the code for Foxy and Galactic
#else
   // Put the code for Humble+
#endif

// Some code after
# In the CMakeLists.txt

if(${LEGACY_IDL})
    # Insert your clause here
endif()

Moreover, to simplify interface integration in the CMakeLists, a macro has also been added (add_message). You can use it after declaring your executable or you library as in the example below:

ament_auto_add_executable(template_exec
    ... cpp files
)
target_include_directories(template_exec PRIVATE include)
add_message(template_exec)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment