目录
[2.1 创建 C++ 功能包](#2.1 创建 C++ 功能包)
[2.2 编写 C++ 节点源码](#2.2 编写 C++ 节点源码)
[2.3 修改 CMakeLists.txt](#2.3 修改 CMakeLists.txt)
[2.4 添加依赖声明](#2.4 添加依赖声明)
[2.5 编译与运行(这一步没必要,直接跳2.5,这里只是记录过程)](#2.5 编译与运行(这一步没必要,直接跳2.5,这里只是记录过程))
[2.6 直接使用 colcon 构建](#2.6 直接使用 colcon 构建)
[报错信息:No executable found](#报错信息:No executable found)
2.1 创建 C++ 功能包
在工作空间的 src 目录(或你存放包的目录)下,创建 ament_cmake 类型的 C++ 功能包:
ros2 pkg create --build-type ament_cmake --license Apache-2.0 demo_cpp_pkg
执行结果显示包创建成功,自动生成了以下结构:
demo_cpp_pkg/
├── CMakeLists.txt
├── include/
│ └── demo_cpp_pkg/
├── package.xml
└── src/
2.2 编写 C++ 节点源码
在 src/ 目录下创建节点源文件 cpp_node.cpp,内容如下:
#include "rclcpp/rclcpp.hpp"
int main(int argc, char **argv)
{
rclcpp::init(argc, argv);
auto node = std::make_shared<rclcpp::Node>("cpp_node");
RCLCPP_INFO(node->get_logger(), "你好 C++ 节点!");
rclcpp::spin(node);
rclcpp::shutdown();
return 0;
}
2.3 修改 CMakeLists.txt
原始的 CMakeLists.txt 模板 中,find_package(rclcpp REQUIRED) 通常在文件较上方。
我们需要做以下修改:
- 确保 find_package(rclcpp REQUIRED) 已存在(通常已自动生成)。
- 添加可执行文件声明。
- 使用 ament_target_dependencies 链接依赖(推荐方式,比手动 target_include_directories + target_link_libraries 更简洁)。
其实就是把普通版本的CMakeLists.txt这四行粘贴到这个功能包的CMakeLists.txt:


这里:
target_include_directories(cpp_node PUBLIC ${rclcpp_INCLUDE_DIRS})
#target_link_libraries(cpp_node ${rclcpp_LIBRARIES})
这两行等价于:
ament_target_dependencies(cpp_node rclcpp)
修改后的完整 CMakeLists.txt 如下(关键修改部分已标注):
cmake_minimum_required(VERSION 3.8)
project(demo_cpp_pkg)
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
add_compile_options(-Wall -Wextra -Wpedantic)
endif()
# find dependencies
find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED) # ← 查找 rclcpp
add_executable(cpp_node src/cpp_node.cpp) # ← 修改为你的源文件路径和目标名
# 使用 ament 推荐方式链接依赖(推荐)
ament_target_dependencies(cpp_node rclcpp)
# 以下手动方式也可以,但不推荐混用
# target_include_directories(cpp_node PUBLIC ${rclcpp_INCLUDE_DIRS})
# target_link_libraries(cpp_node ${rclcpp_LIBRARIES})
if(BUILD_TESTING)
find_package(ament_lint_auto REQUIRED)
set(ament_cmake_copyright_FOUND TRUE)
set(ament_cmake_cpplint_FOUND TRUE)
ament_lint_auto_find_test_dependencies()
endif()
ament_package()
修改要点总结:
- **add_executable(cpp_node src/cpp_node.cpp):**指定源文件路径和可执行文件名
- 使用 ament_target_dependencies(cpp_node rclcpp)(推荐)
- 保留了 find_package(rclcpp REQUIRED)
2.4 添加依赖声明
<depend>rclcpp</depend>

2.5 编译与运行(这一步没必要,直接跳2.5,这里只是记录过程)
# 1. 进入包目录的 build 文件夹(或直接在工作空间根目录使用 colcon)
cd demo_cpp_pkg
mkdir -p build && cd build
# 2. 配置(cmake)
cmake ..
# 3. 编译
make
# 4. 运行节点
./cpp_node
记得退出base环境,base(miniforge3 / conda)环境中运行 cmake,该环境缺少 ROS 2 所需的 catkin_pkg Python 模块。!!!!!

正确做法:
- 退出 conda base 环境(非常重要!)
conda deactivate
- 确保使用系统自带的 Python(ROS 2 Humble 默认使用 Python 3.10)
- 重新执行 cmake .. 和 make
经验教训:
- ROS 2 开发时,强烈建议不要在 conda/miniconda base 环境中编译,容易出现 Python 包冲突。
- 最好使用纯系统环境(source /opt/ros/humble/setup.bash 后)进行开发构建。
2.6 直接使用 colcon 构建
在当前目录,依次执行:
$ colcon build
$ source install/setup.bash
$ ros2 run demo_cpp_pkg cpp_node

报错信息:No executable found
同时使用 ros2 pkg executables demo_cpp_pkg(或直接 ros2 run)时,系统无法找到可执行文件 cpp_node。
问题原因分析
虽然我们已经在 CMakeLists.txt 中写了:
add_executable(cpp_node src/cpp_node.cpp)
ament_target_dependencies(cpp_node rclcpp)
但 没有安装(install)可执行文件 到正确的位置。
ROS 2 的 ros2 run 命令只会从 install/<package_name>/lib/<package_name>/ 目录下查找可执行文件。 如果 CMakeLists.txt 中缺少 install() 指令,colcon build 虽然能成功编译出 cpp_node,但不会将其复制到 install 目录下,导致 ros2 run 找不到可执行程序。
这是 ROS 2 ament_cmake 包开发中最常见的"能编译通过,但 ros2 run 找不到节点"的原因之一。
解决步骤
在 CMakeLists.txt 中添加 install() 指令(推荐写法):
# 在 ament_target_dependencies 之后,if(BUILD_TESTING) 之前添加
install(
TARGETS
cpp_node
DESTINATION lib/${PROJECT_NAME}
)
修改后的完整关键部分如下:
find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
add_executable(cpp_node src/cpp_node.cpp)
ament_target_dependencies(cpp_node rclcpp)
# ==================== 必须添加这一段 ====================
install(
TARGETS
cpp_node
DESTINATION lib/${PROJECT_NAME}
)
# =======================================================
if(BUILD_TESTING)
...
endif()
ament_package()
重新执行构建:
$ colcon build
$ source install/setup.bash
$ ros2 run demo_cpp_pkg cpp_node
