ROS1和ROS的CMakeList模板
一、ROS1(catkin)CMakeLists
① find_package()
find_package(catkin REQUIRED COMPONENTS
roscpp
mavros_msgs
geometry_msgs
tf
)
find_package(Eigen3 REQUIRED)
✔ 查找 ROS1 包
✔ 查找第三方库(Eigen)
②catkin_package + include_directories
catkin_package(
CATKIN_DEPENDS roscpp mavros_msgs geometry_msgs tf
INCLUDE_DIRS include
LIBRARIES mavros_controller
)
include_directories(
include
${catkin_INCLUDE_DIRS}
${EIGEN3_INCLUDE_DIRS}
)
✔ catkin_package:导出包信息给别人用
✔ include_directories:当前包自己需要的头文件
③ add_library + add_executable
add_library(${PROJECT_NAME}
src/mavros_controller.cpp
)
add_executable(controller_node
src/controller_node.cpp
)
✔ 一个生成库
✔ 一个生成节点可执行文件
④ install()
install(TARGETS controller_node
RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)
install(TARGETS ${PROJECT_NAME}
LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
)
install(DIRECTORY include/
DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}
)
✔ 安装可执行文件
✔ 安装库
✔ 安装头文件
二、ROS2(ament)CMakeLists
① find_package()
find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
find_package(mavros_msgs REQUIRED)
find_package(geometry_msgs REQUIRED)
find_package(Eigen3 REQUIRED)
✔ 必须放在最前
✔ ROS2 包依赖结构更清晰
② add_library + add_executable
add_library(${PROJECT_NAME}
src/mavros_controller.cpp
)
add_executable(controller_node
src/controller_node.cpp
)
✔ 与 ROS1 相同:一个库一个节点
✔ 顺序可以互换
③ target_link_libraries + ament_target_dependencies
(1) 链接库(你自己写的库)
target_link_libraries(controller_node
${PROJECT_NAME}
)
(2) 添加依赖包(类似 include + link)
ament_target_dependencies(controller_node
rclcpp
mavros_msgs
geometry_msgs
)
✔ “库依赖”与“包依赖”必须分离
✔ 这点是你最容易混淆和提问最多的内容:
ament_target_dependencies ≠ target_link_libraries
一个解决“包依赖”,一个解决“库链接”
④ install()
install(TARGETS
${PROJECT_NAME}
controller_node
DESTINATION lib/${PROJECT_NAME}
)
install(DIRECTORY include/
DESTINATION include
)
ament_package() # 必须最后
✔ 安装位置与 ROS1 不同
✔ ament_package() 一定要放在最后(你曾提问顺序是否可换)
三、踩坑记录
(1) 为什么 ROS2 有 target_link_libraries + ament_target_dependencies?
因为:
ament_target_dependencies: 负责 包依赖target_link_libraries: 负责 目标库链接(你自己的库)
两者解决不同层面的问题,不能互相取代
(2) ROS2 为什么不直接用 include_directories?
- 因为 target_include_directories 是现代 CMake 推荐写法
ament_target_dependencies会自动添加包的 include 路径- 只有你自己的
include/需要手动写:
target_include_directories(${PROJECT_NAME}
PUBLIC include
)
“为什么不能像 ROS1 那样写 include_directories?”
→ 因为 modern CMake 不推荐,且 TARGET 作用范围更明确。
(3) ROS2 的顺序能否随便写?
find_package()必须在最前- 作用于某个 target 的设置必须写在 target 之后
ament_package()必须最后
其他顺序基本可以随意。
四、总结
ROS1 :三找、两包、两编译、一安装
三找(find_package)
两包(catkin_package + include_directories)
两编译(add_library + add_executable)
一安装(install)
ROS2 :三找 → 两建 → 两绑 → 一安装
三找(find_package)
两建(add_library + add_executable)
两绑(target_link_libraries + ament_target_dependencies)
一安装(install + 最后 ament_package)
五、ROS1和ROS2的CMakelist模板:
目录结构:
mavros_controller/
├── CMakeLists.txt
├── include/mavros_controller/mavros_controller.h
└── src/
├── mavros_controller.cpp
└── controller_node.cpp
ROS1的CMakeLists.txt 模板
cmake_minimum_required(VERSION 3.0.2)
project(mavros_controller)
## ----------------------------------------
## 1. 编译选项
## ----------------------------------------
add_compile_options(-Wall -Wextra -Wpedantic -std=c++14)
## ----------------------------------------
## 2. 找依赖
## ----------------------------------------
find_package(catkin REQUIRED COMPONENTS
roscpp
mavros_msgs
geometry_msgs
tf
)
find_package(Eigen3 REQUIRED)
## ----------------------------------------
## 3. 打包导出
## ----------------------------------------
catkin_package(
INCLUDE_DIRS include
LIBRARIES mavros_controller
CATKIN_DEPENDS roscpp mavros_msgs geometry_msgs tf
)
## ----------------------------------------
## 4. 头文件目录
## ----------------------------------------
include_directories(
include
${catkin_INCLUDE_DIRS}
${EIGEN3_INCLUDE_DIRS}
)
## ----------------------------------------
## 5. 编译库
## ----------------------------------------
add_library(${PROJECT_NAME}
src/mavros_controller.cpp
)
## 链接库
target_link_libraries(${PROJECT_NAME}
${catkin_LIBRARIES}
)
## ----------------------------------------
## 6. 编译节点
## ----------------------------------------
add_executable(controller_node
src/controller_node.cpp
)
target_link_libraries(controller_node
${PROJECT_NAME}
${catkin_LIBRARIES}
)
## ----------------------------------------
## 7. 安装
## ----------------------------------------
install(TARGETS ${PROJECT_NAME} controller_node
RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
)
install(DIRECTORY include/
DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}
)
ROS2的CMakeLists.txt 模板
cmake_minimum_required(VERSION 3.8)
project(mavros_controller)
## ----------------------------------------
## 1. 编译选项
## ----------------------------------------
add_compile_options(-Wall -Wextra -Wpedantic -std=c++17)
## ----------------------------------------
## 2. 找依赖
## ----------------------------------------
find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
find_package(mavros_msgs REQUIRED)
find_package(geometry_msgs REQUIRED)
find_package(tf2 REQUIRED)
find_package(tf2_ros REQUIRED)
find_package(Eigen3 REQUIRED)
## ----------------------------------------
## 3. 建库
## ----------------------------------------
add_library(${PROJECT_NAME}
src/mavros_controller.cpp
)
## 头文件目录
target_include_directories(${PROJECT_NAME}
PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>
${EIGEN3_INCLUDE_DIRS}
)
## 绑定依赖
ament_target_dependencies(${PROJECT_NAME}
rclcpp
mavros_msgs
geometry_msgs
tf2
tf2_ros
)
## ----------------------------------------
## 4. 建节点
## ----------------------------------------
add_executable(controller_node
src/controller_node.cpp
)
target_include_directories(controller_node
PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
${EIGEN3_INCLUDE_DIRS}
)
## 绑定依赖
ament_target_dependencies(controller_node
rclcpp
mavros_msgs
geometry_msgs
tf2
tf2_ros
)
## 节点需要链接库
target_link_libraries(controller_node
${PROJECT_NAME}
)
## ----------------------------------------
## 5. 安装
## ----------------------------------------
install(TARGETS
${PROJECT_NAME}
controller_node
DESTINATION lib/${PROJECT_NAME}
)
install(
DIRECTORY include/
DESTINATION include
)
## ----------------------------------------
## 6. ament 收工
## ----------------------------------------
ament_package()
2080




被折叠的 条评论
为什么被折叠?



