ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

I would not want to compile the ROS2 core using this, but I compile my own workspace of ROS2 nodes using this CMakeLists.txt file in my workspace root. It finds sub-projects automatically like colcon does. You will have to setup the CLion build and run environment variables created using the source <path-to>/install.bash workspace overlay scripts. See far below, I also created a bash script to print out all the env vars from a properly setup shell so I can then just copy/paste into CLion.

I also have CLion developing ROS nodes on an RPI remotely from my desktop linux using the remote-ssh toolchain. Just generate your env vars from the RPi instead of local system and this works great.

FYI I didnt write this CMakeLists.txt, so I don't deserve any credit for it. :)

cmake_minimum_required(VERSION 3.13)
project("MyROSProject")

# usually I put this in a separate file include("/opt/ros/_common/Colcon.cmake")
function(colcon_add_subdirectories)
  cmake_parse_arguments(PARSE_ARGV 0 "ARG" "" "BUILD_BASE;BASE_PATHS" "")

  message("search criteria: ${ARGV}")

  execute_process(COMMAND colcon list
        --paths-only
        --base-paths ${ARG_BASE_PATHS}
        --topological-order
        ${ARG_UNPARSED_ARGUMENTS}
        OUTPUT_VARIABLE paths)
  string(STRIP "${paths}" paths)
  string(REPLACE "\n" ";" paths "${paths}")

  MESSAGE("colcon shows paths ${paths}")

  foreach(path IN LISTS paths)
    message("...examining ${path}")
    # if(EXISTS "${path}/CMakeLists.txt")
    execute_process(COMMAND colcon info --paths "${path}" OUTPUT_VARIABLE package_info)
    if(NOT "${package_info}" MATCHES "type:[ \t]+(cmake|ros.ament_cmake|ros.cmake)")
      message("skipping non-cmake project")
    elseif(NOT "${package_info}" MATCHES "name:[ \t]+([^ \r\n\t]*)")
      message(WARNING "could not identify package at ${path}")
    else()
      set(name "${CMAKE_MATCH_1}")
      message("...adding package ${name} from path ${path}")
      MESSAGE("package info: ${package_info}")

      get_filename_component(BUILD_PATH "${name}" ABSOLUTE BASE_DIR "${ARG_BUILD_BASE}")

      add_subdirectory("${path}" "${BUILD_PATH}")
    endif()
  endforeach()
endfunction()

set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_LIST_DIR}/humanoid/cmake" CACHE STRING "Modules for CMake" FORCE)

colcon_add_subdirectories(
        BUILD_BASE "${PROJECT_SOURCE_DIR}/humanoid/build"
        BASE_PATHS "${PROJECT_SOURCE_DIR}/humanoid/lib/"
        --packages-select LynxmotionLSS
)

colcon_add_subdirectories(
    BUILD_BASE "${PROJECT_SOURCE_DIR}/humanoid/build"
    BASE_PATHS "${PROJECT_SOURCE_DIR}/humanoid/src/"
    --packages-select humanoid_model_msgs lss_joint_publisher humanoid_dynamic_model
)

You could just setup Workspace overlays, then run CLion bin, or modify your project to include the required env vars. Use this bash script for echo'ing the ROS2 related env vars needed in CLion:

 ros_env="AMENT_PREFIX_PATH CMAKE_PREFIX_PATH COLCON_PREFIX_PATH PKG_CONFIG_PATH PYTHONPATH LD_LIBRARY_PATH PATH ROS_DISTRO ROS_PYTHON_VERSION ROS_LOCALHOST_ONLY ROS_VERSION"
 for e in ${ros_env}; do
     echo "$e=${!e}"
 done

I would not want to compile the ROS2 core using this, but I compile my own workspace of ROS2 nodes using this CMakeLists.txt file in my workspace root. It finds sub-projects automatically like colcon does. You will have to setup the CLion build and run environment variables created using the source <path-to>/install.bash workspace overlay scripts. See far below, I also created a bash script to print out all the env vars from a properly setup shell so I can then just copy/paste into CLion.

I also have CLion developing ROS nodes on an RPI remotely from my desktop linux using the remote-ssh toolchain. Just generate your env vars from the RPi instead of local system and this works great.

FYI I didnt write this CMakeLists.txt, so I don't deserve any credit for it. :)

cmake_minimum_required(VERSION 3.13)
project("MyROSProject")

# usually I put this in a separate file include("/opt/ros/_common/Colcon.cmake")
function(colcon_add_subdirectories)
  cmake_parse_arguments(PARSE_ARGV 0 "ARG" "" "BUILD_BASE;BASE_PATHS" "")

  message("search criteria: ${ARGV}")

  execute_process(COMMAND colcon list
        --paths-only
        --base-paths ${ARG_BASE_PATHS}
        --topological-order
        ${ARG_UNPARSED_ARGUMENTS}
        OUTPUT_VARIABLE paths)
  string(STRIP "${paths}" paths)
  string(REPLACE "\n" ";" paths "${paths}")

  MESSAGE("colcon shows paths ${paths}")

  foreach(path IN LISTS paths)
    message("...examining ${path}")
    # if(EXISTS "${path}/CMakeLists.txt")
    execute_process(COMMAND colcon info --paths "${path}" OUTPUT_VARIABLE package_info)
    if(NOT "${package_info}" MATCHES "type:[ \t]+(cmake|ros.ament_cmake|ros.cmake)")
      message("skipping non-cmake project")
    elseif(NOT "${package_info}" MATCHES "name:[ \t]+([^ \r\n\t]*)")
      message(WARNING "could not identify package at ${path}")
    else()
      set(name "${CMAKE_MATCH_1}")
      message("...adding package ${name} from path ${path}")
      MESSAGE("package info: ${package_info}")

      get_filename_component(BUILD_PATH "${name}" ABSOLUTE BASE_DIR "${ARG_BUILD_BASE}")

      add_subdirectory("${path}" "${BUILD_PATH}")
    endif()
  endforeach()
endfunction()

set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_LIST_DIR}/humanoid/cmake" CACHE STRING "Modules for CMake" FORCE)

colcon_add_subdirectories(
        BUILD_BASE "${PROJECT_SOURCE_DIR}/humanoid/build"
        BASE_PATHS "${PROJECT_SOURCE_DIR}/humanoid/lib/"
        --packages-select LynxmotionLSS
)

colcon_add_subdirectories(
    BUILD_BASE "${PROJECT_SOURCE_DIR}/humanoid/build"
    BASE_PATHS "${PROJECT_SOURCE_DIR}/humanoid/src/"
    --packages-select humanoid_model_msgs lss_joint_publisher humanoid_dynamic_model
)

You could just setup Workspace overlays, then run CLion bin, or modify your project to include the required env vars. Use this bash script for echo'ing the ROS2 related env vars needed in CLion:

 ros_env="AMENT_PREFIX_PATH CMAKE_PREFIX_PATH COLCON_PREFIX_PATH PKG_CONFIG_PATH PYTHONPATH LD_LIBRARY_PATH PATH ROS_DISTRO ROS_PYTHON_VERSION ROS_LOCALHOST_ONLY ROS_VERSION"
 for e in ${ros_env}; do
     echo "$e=${!e}"
 done

These ENV settings must be pasted into 2 locations in CLion, once for building and then for each program executable runtime environment:

  • File | Settings... | Build, Execution, Deployment | CMake into the Environment editor dialog (now refresh CMake project)
  • Run | Edit Configurations... | <program> | Environment variables editor dialog