You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ROS2包中如何正确包含HPP与CPP文件?解决未定义引用错误

问题解决:ROS2包中undefined reference错误处理

问题场景

我正在开发一个ROS2包,src目录下的I2C_driver.cpp需要引用同目录下的SerialPort.hpp和SerialPort.cpp。不包含该文件时colcon build可正常执行,但一旦包含后就出现**undefined reference to '引入的命名空间'**错误。

当前CMakeLists.txt代码

cmake_minimum_required(VERSION 3.5)
project(rover2-1_ros)

# Default to C99
if(NOT CMAKE_C_STANDARD)
  set(CMAKE_C_STANDARD 99)
endif()

# Default to C++14
if(NOT CMAKE_CXX_STANDARD)
  set(CMAKE_CXX_STANDARD 14)
endif()

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)
# uncomment the following section in order to fill in
# further dependencies manually.
# find_package(<dependency> REQUIRED)


if(BUILD_TESTING)
  find_package(ament_lint_auto REQUIRED)
  find_package(rclcpp REQUIRED)
  find_package(std_msgs REQUIRED)
  find_package(sensor_msgs REQUIRED)
  add_executable(gamepad src/joystick_rover_control.cpp)
  add_executable(i2c_driver src/I2C_driver.cpp)
  ament_target_dependencies(gamepad rclcpp std_msgs sensor_msgs)
  ament_target_dependencies(i2c_driver rclcpp std_msgs sensor_msgs)

  ament_lint_auto_find_test_dependencies()
endif()


install(DIRECTORY launch
 DESTINATION share/${PROJECT_NAME}
)

install(TARGETS
  gamepad
  i2c_driver
  DESTINATION lib/${PROJECT_NAME})


ament_package()

错误原因

核心问题有两个:

  1. 仅在I2C_driver.cpp中包含了SerialPort.hpp头文件,但未将SerialPort.cpp的实现代码编译进i2c_driver可执行文件,导致链接器找不到对应函数/命名空间的定义。
  2. 依赖包的find_package被放在了BUILD_TESTING条件块内,正常编译(非测试模式)时不会加载这些依赖,可能引发额外编译问题。

修改后的CMakeLists.txt

cmake_minimum_required(VERSION 3.5)
project(rover2-1_ros)

# Default to C99
if(NOT CMAKE_C_STANDARD)
  set(CMAKE_C_STANDARD 99)
endif()

# Default to C++14
if(NOT CMAKE_CXX_STANDARD)
  set(CMAKE_CXX_STANDARD 14)
endif()

if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
  add_compile_options(-Wall -Wextra -Wpedantic)
endif()

# find dependencies - 移到BUILD_TESTING外,确保正常编译时加载
find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
find_package(std_msgs REQUIRED)
find_package(sensor_msgs REQUIRED)

# 编译可执行文件 - 添加SerialPort.cpp到i2c_driver的源文件列表
add_executable(gamepad src/joystick_rover_control.cpp)
add_executable(i2c_driver src/I2C_driver.cpp src/SerialPort.cpp)

ament_target_dependencies(gamepad rclcpp std_msgs sensor_msgs)
ament_target_dependencies(i2c_driver rclcpp std_msgs sensor_msgs)

if(BUILD_TESTING)
  find_package(ament_lint_auto REQUIRED)
  ament_lint_auto_find_test_dependencies()
endif()

install(DIRECTORY launch
 DESTINATION share/${PROJECT_NAME}
)

install(TARGETS
  gamepad
  i2c_driver
  DESTINATION lib/${PROJECT_NAME})

ament_package()

关键修改点

  • 将rclcpp、std_msgs等依赖的find_package移到BUILD_TESTING条件块外部,确保正常编译流程能加载这些依赖。
  • 在add_executable(i2c_driver ...)中添加src/SerialPort.cpp,让编译器将该文件的代码编译并链接到i2c_driver可执行文件中。

内容的提问来源于stack exchange,提问作者Martin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 18:50:21