2026 ROS 2 Lyrical 踩坑实录(一):编译与依赖——rosdep、现代 CMake 与 CMake 4.x

系列: 2026 ROS 2 Lyrical 踩坑实录

环境: Ubuntu 26.04 / WSL2、ROS 2 Lyrical Luth、CMake 4.x

关键词: ROS 2、Lyrical、rosdep、ament_cmake、CMake 4、colcon

前言

把旧版 ROS 2 教程迁移到 Lyrical 时,最容易让人困惑的不是 C++ 代码,而是构建工具链。

本文只整理三个已经实际遇到的高频问题:

  1. pkg_resources is deprecated 到底是不是安装失败;
  2. Unknown CMake command "ament_target_dependencies" 如何修复;
  3. CMake 4.x 为什么拒绝构建旧依赖,以及怎样临时兼容。

文章最后还会给出一套重新编译前的检查顺序,避免在 build/install/ 和环境变量之间反复绕圈。


一、rosdep 出现 pkg_resources 警告

执行:

bash 复制代码
rosdep install --from-paths src --ignore-src -r -y --rosdistro lyrical

可能看到:

text 复制代码
/usr/bin/rosdep:6: DeprecationWarning: pkg_resources is deprecated as an API
  from pkg_resources import load_entry_point
#All required rosdeps installed successfully

这是不是错误?

不是。

判断命令是否成功,应该看最后的执行结果:

text 复制代码
#All required rosdeps installed successfully

这说明 rosdep 已经完成依赖解析。前面的内容只是 rosdep 启动脚本调用旧 Python API 产生的弃用警告,不会导致后面的 C++ 功能包编译失败。

不要为了消除一条警告而直接使用 sudo pip 升级系统的 setuptools。这可能覆盖 Ubuntu 由 APT 管理的 Python 软件包,反而导致 rosdep、colcon 或其他系统工具发生依赖冲突。


二、Unknown CMake command "ament_target_dependencies"

1. 完整症状

text 复制代码
CMake Error at CMakeLists.txt:17 (ament_target_dependencies):
  Unknown CMake command "ament_target_dependencies".

很多旧教程仍然使用:

cmake 复制代码
add_executable(server src/add_two_ints_server.cpp)
ament_target_dependencies(server rclcpp example_interfaces)

在本文的 Lyrical 环境中,find_package(ament_cmake REQUIRED) 没有自动提供这个旧宏,因此 CMake 在配置阶段直接退出。

2. 改用现代 CMake Targets

服务端修改为:

cmake 复制代码
add_executable(server src/add_two_ints_server.cpp)
target_link_libraries(server PRIVATE
  rclcpp::rclcpp
  ${example_interfaces_TARGETS}
)

客户端同样修改:

cmake 复制代码
add_executable(client src/add_two_ints_client.cpp)
target_link_libraries(client PRIVATE
  rclcpp::rclcpp
  ${example_interfaces_TARGETS}
)

这里:

  • rclcpp::rclcpprclcpp 导出的现代 CMake Target;
  • ${example_interfaces_TARGETS} 包含消息和服务接口所需的生成目标;
  • PRIVATE 表示这些依赖只用于构建当前可执行文件。

3. 完整 CMakeLists.txt

cmake 复制代码
cmake_minimum_required(VERSION 3.8)
project(lyrical_service_demo)

if(NOT CMAKE_CXX_STANDARD)
  set(CMAKE_CXX_STANDARD 17)
endif()

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

find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
find_package(example_interfaces REQUIRED)

add_executable(server src/add_two_ints_server.cpp)
target_link_libraries(server PRIVATE
  rclcpp::rclcpp
  ${example_interfaces_TARGETS}
)

add_executable(client src/add_two_ints_client.cpp)
target_link_libraries(client PRIVATE
  rclcpp::rclcpp
  ${example_interfaces_TARGETS}
)

install(TARGETS
  server
  client
  DESTINATION lib/${PROJECT_NAME}
)

ament_package()

4. 修改后清理 CMake 缓存

bash 复制代码
cd ~/ros2_lyrical_ws

colcon build \
  --symlink-install \
  --packages-select lyrical_service_demo \
  --cmake-clean-cache

--cmake-clean-cache 会让目标包重新执行 CMake 配置,不需要直接删除整个工作空间。


三、CMake 4.x 拒绝构建旧项目

1. 典型错误

text 复制代码
Compatibility with CMake < 3.5 has been removed from CMake.

Ubuntu 26.04 使用 CMake 4.x。CMake 4.0 开始移除了对 3.5 以前策略版本的兼容。如果旧项目仍然写着:

cmake 复制代码
cmake_minimum_required(VERSION 2.8)

新版本 CMake 就可能拒绝继续配置。

2. 临时兼容方案

如果这是暂时无法修改的第三方依赖,可以在本次构建中设置最低策略版本:

bash 复制代码
cd ~/ros2_lyrical_ws

CMAKE_POLICY_VERSION_MINIMUM=3.5 \
colcon build --cmake-clean-cache

也可以传给当前工作空间的 CMake:

bash 复制代码
colcon build \
  --cmake-clean-cache \
  --cmake-args -DCMAKE_POLICY_VERSION_MINIMUM=3.5

环境变量会继续传递给构建过程中启动的子进程,因此在 Vendor Package 使用子 CMake 工程时通常更实用。

3. 这不是永久解决方案

它只是让 CMake 暂时按照不低于 3.5 的策略尝试配置。更好的长期方案是:

  1. 优先升级到支持 CMake 4.x 的依赖版本;
  2. 如果项目由自己维护,更新 cmake_minimum_required()
  3. 将兼容性修复提交给上游;
  4. 修改后重新运行测试,确认没有受到策略变化影响。

四、安装路径与 source 路径不一致

构建成功后,如果 ros2 launch 仍然找不到包,要检查安装路径。

例如构建时使用:

bash 复制代码
colcon build --install-base /opt/nav2

但终端加载的是:

bash 复制代码
source ~/nav2_ws/install/setup.bash

这两个目录不是同一个安装空间。应该加载实际安装目录:

bash 复制代码
source /opt/nav2/setup.bash

确认 ROS 2 当前找到的是哪个包:

bash 复制代码
ros2 pkg prefix <package_name>

如果修改了安装位置,还应检查 .bashrc 是否仍在加载旧工作空间,避免 Overlay 与 Underlay 混用。


五、推荐的编译排错顺序

bash 复制代码
# 1. 加载基础环境
source /opt/ros/lyrical/setup.bash

# 2. 确认发行版
echo $ROS_DISTRO

# 3. 安装依赖
rosdep install --from-paths src --ignore-src -r -y --rosdistro lyrical

# 4. 只编译目标包并刷新缓存
colcon build \
  --symlink-install \
  --packages-select lyrical_service_demo \
  --cmake-clean-cache

# 5. 加载本次构建结果
source install/setup.bash

# 6. 检查包和可执行文件
ros2 pkg prefix lyrical_service_demo
ros2 pkg executables lyrical_service_demo

一次只改变一个条件,比同时修改依赖、环境变量和 CMake 文件更容易找到真正的根因。


六、总结

这次排错最重要的经验可以压缩成四句话:

  1. DeprecationWarning 不等于执行失败,要看最终结果;
  2. Lyrical 新项目优先使用现代 CMake Targets;
  3. CMake 4.x 不再兼容低于 3.5 的旧策略版本;
  4. 构建目录、安装目录和 source 路径必须一致。

参考资料

  1. CMake:CMAKE_POLICY_VERSION_MINIMUM
    cmake.org/cmake/help/...
  2. CMake:cmake_minimum_required
    cmake.org/cmake/help/...
  3. ament_cmake:Modern CMake Targets 讨论
    github.com/ament/ament...
相关推荐
Murphy_lx1 小时前
1124. 表现良好的最长时间段
c++·算法
aramae1 小时前
模拟实现strstr函数(C语言)
c语言·开发语言·算法
liliangcsdn2 小时前
因子权重矩阵处理-滞回缓冲带+降频稳定化动态重选
开发语言·python·算法
敲代码的嘎仔2 小时前
自己设计了一个兑换码算法:自增ID + Base32转码 + 按位加权签名 + 异或混淆,面试被追问细节时终于不用慌了
java·数据库·mysql·算法·微服务·面试·职场和发展
云析赢指标公式网43 小时前
文华WH6布林轨道均线强弱共振指标公式
前端·算法
luj_17683 小时前
一线一区一变破解人盯人防守密码
开发语言·网络·c++·经验分享·算法
Wang's Blog4 小时前
Java框架快速入门: Spring Security+OAuth2之字段验证与自定义验证注解实战
java·算法·spring
带多刺的玫瑰4 小时前
Leecode#29刷题之两数相除
java·python·算法
smj2302_796826524 小时前
解决leetcode第4017题数组中的峰值II
python·算法·leetcode