ROS2 C++导入三方动态、静态库及apt等下载库
前言
博主在开发ROS2项目时,经常需要引入各种第三方C++库,但在全网搜索后发现,针对ROS2环境下的中文教程要么过于零散,要么不够完整。本文将从零开始,详细记录ROS2项目中如何正确导入和使用第三方C++库的全过程。
本文主要讲解ROS2建立C++包时如何导入三方库文件(.so .a),及自定义的C++程序。1234567
正文
CMakeLists.txt修改
此处以珞石Rokae驱动为例:
$ tree ./
./
├── CMakeLists.txt
├── include
│ └── ros2_rokae_driver
│ ├── base.h
│ ├── data_types.h
│ ├── exception.h
│ ├── model.h
│ ├── motion_control_rt.h
│ ├── planner.h
│ ├── robot.h
│ └── utility.h
├── package.xml
├── resources
│ └── lib
│ ├── libxCoreSDK.a
│ ├── libxCoreSDK.nomodel.so.0.3.4
│ ├── libxCoreSDK.so.0.3.4
│ └── libxMateModel.a
└── src
├── print_helper.hpp
└── sdk_example.cpp
5 directories, 16 files
外部依赖库为libxCoreSDK
及libxMateModel
系列。
编辑CMakeLists.txt
,原版如下:
cmake_minimum_required(VERSION 3.8)
project(ros2_rokae_driver)
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
add_compile_options(-Wall -Wextra -Wpedantic)
endif()
#-------------------------------------------------------------------------------
## Compile options
# Using static/shared libraries option
option(XCORE_LINK_SHARED_LIBS "Example executables link shared library" OFF)
# Compile option: whether using xMateModel library, supports Linux x86_64 and Windows 64bit
option(XCORE_USE_XMATE_MODEL "The library of kinematics and dynamics calculation for cobot" OFF)
# set environment
set(XCORE_SDK_VERSION 0.3.4)
set(XCORE_LINK_SHARED_LIBS ON)
set(XCORE_USE_XMATE_MODEL ON)
# find dependencies
find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
find_package(Eigen3 REQUIRED)
# include
include_directories(${EIGEN3_INCLUDE_DIR})
include_directories(include)
# Add shared/static libraries
add_library(xCoreSDK_lib SHARED IMPORTED GLOBAL)
add_library(xCoreSDK_static STATIC IMPORTED GLOBAL)
add_library(xmatemodel_lib STATIC IMPORTED)
if(XCORE_USE_XMATE_MODEL)
set_target_properties(xCoreSDK_lib PROPERTIES
INTERFACE_LINK_LIBRARIES xmatemodel_lib)
else()
set(SHARED_LIB_SUFFIX ".nomodel")
endif()
set_target_properties(xmatemodel_lib PROPERTIES
IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/resources/lib/libxMateModel.a
)
set_target_properties(xCoreSDK_lib PROPERTIES
IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/resources/lib/libxCoreSDK${SHARED_LIB_SUFFIX}.so.${XCORE_SDK_VERSION}
)
set_target_properties(xCoreSDK_static PROPERTIES
IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/resources/lib/libxCoreSDK.a
INTERFACE_LINK_LIBRARIES xmatemodel_lib
)
if(XCORE_LINK_SHARED_LIBS)
add_library(Rokae::Rokae ALIAS xCoreSDK_lib)
else()
add_library(Rokae::Rokae ALIAS xCoreSDK_static)
endif()
# compile
add_executable(sdk_example src/sdk_example.cpp src/print_helper.hpp)
target_include_directories(sdk_example PUBLIC
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>
)
message(STATUS "Linking libraries...")
target_link_libraries(sdk_example Rokae::Rokae Eigen3::Eigen)
# # add dependencies
# ament_target_dependencies(sdk_example
# rclcpp
# )
# export
ament_export_targets(export_${PROJECT_NAME} HAS_LIBRARY_TARGET)
# install
message(STATUS "Installing libraries...")
install(
TARGETS sdk_example
EXPORT export_${PROJECT_NAME}
# LIBRARY DESTINATION lib
# ARCHIVE DESTINATION lib
RUNTIME DESTINATION lib/${PROJECT_NAME}
INCLUDES DESTINATION include
)
install(DIRECTORY include/ros2_rokae_driver
DESTINATION include
)
install(DIRECTORY resources/lib/
DESTINATION lib/
)
ament_package()
编辑CMakeLists.txt
,简化版如下:
cmake_minimum_required(VERSION 3.8)
project(ros2_rokae_driver)
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)
find_package(Eigen3 REQUIRED) # 导入可以使用find_package找到的库,都可用这种方法
# include
include_directories(${EIGEN3_INCLUDE_DIR}) # 导入可以使用find_package找到的库,添加include都可用这种方法
include_directories(include)
# Add shared/static libraries
add_library(xCoreSDK_lib SHARED IMPORTED GLOBAL) # 导入已经生成的库
set_target_properties(xCoreSDK_lib PROPERTIES
IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/resources/lib/libxCoreSDK.nomodel.so.${XCORE_SDK_VERSION}
) # 设置library在硬盘上的位置(编译前)
add_library(Rokae::Rokae ALIAS xCoreSDK_lib) # 设置library的别名,方便应用
# compile
add_executable(sdk_example src/sdk_example.cpp src/print_helper.hpp)
target_include_directories(sdk_example PUBLIC
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>
)
message(STATUS "Linking libraries...")
target_link_libraries(sdk_example Rokae::Rokae Eigen3::Eigen) # 链接依赖库,这里可以看到Rokae和Eigen3都有导入
# # add dependencies
# 如果所有库均是find_package找到的,用下边这句替代target_include_directories和target_link_libraries
# ament_target_dependencies(sdk_example
# rclcpp
# )
# export
ament_export_targets(export_${PROJECT_NAME} HAS_LIBRARY_TARGET) # 重要!!! 设置导入库属性
# install
message(STATUS "Installing libraries...")
# 重要!!! 通过这一句配置可执行文件安装路径及配置$LD_LIBRARY_PATH
install(
TARGETS sdk_example
EXPORT export_${PROJECT_NAME}
# LIBRARY DESTINATION lib
# ARCHIVE DESTINATION lib
RUNTIME DESTINATION lib/${PROJECT_NAME}
INCLUDES DESTINATION include
)
install(DIRECTORY include/ros2_rokae_driver # 重要!!!安装包含路径
DESTINATION include
)
install(DIRECTORY resources/lib/ # 重要!!!安装动态库
DESTINATION lib/
)
ament_package()
package.xml修改
<?xml version="1.0"?>
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="3">
<name>ros2_rokae_driver</name>
<version>0.0.0</version>
<description>TODO: Package description</description>
<maintainer email="lilinxin75@gmail.com">Bing Lee</maintainer>
<url type="website">https://blog.youkuaiyun.com/Bing_Lee</url>
<license>GPL-2.0</license>
<buildtool_depend>ament_cmake</buildtool_depend>
<exec_depend>rclcpp</exec_depend>
<exec_depend>Eigen3</exec_depend>
<test_depend>ament_lint_auto</test_depend>
<test_depend>ament_lint_common</test_depend>
<export>
<build_type>ament_cmake</build_type>
</export>
</package>
编译后文件结构
$ tree -L 3
.
├── include
│ └── ros2_rokae_driver
│ ├── base.h
│ ├── data_types.h
│ ├── exception.h
│ ├── model.h
│ ├── motion_control_rt.h
│ ├── planner.h
│ ├── robot.h
│ └── utility.h
├── lib
│ ├── libxCoreSDK.a
│ ├── libxCoreSDK.nomodel.so.0.3.4
│ ├── libxCoreSDK.so.0.3.4
│ ├── libxMateModel.a
│ └── ros2_rokae_driver
│ └── sdk_example
└── share
├── ament_index
│ └── resource_index
├── colcon-core
│ └── packages
└── ros2_rokae_driver
├── cmake
├── environment
├── hook
├── local_setup.bash
├── local_setup.dsv
├── local_setup.sh
├── local_setup.zsh
├── package.bash
├── package.dsv
├── package.ps1
├── package.sh
├── package.xml
└── package.zsh
13 directories, 23 files
执行软件
$ . install/setup.bash
$ ros2 run ros2_rokae_driver sdk_example
总结
这里还有两篇文章89写的比较全面,虽然博主测试后没有没有复现,但是提供了后续修改的思路。
参考
Proper use of ament_export_targets · Issue #317 · Proper use of ament_export_targets ↩︎
CMake系列讲解(进阶篇)2.1 进阶命令CMake-install()_cmake install-优快云博客 ↩︎
Creating C++ Libraries (for ament_cmake) — ROS2 Tutorial May 23, 2025 documentation ↩︎
【cmake】CMakeList添加库|添加头文件|添加路径|add_executable、add_library、target_link_libraries|添加编译选项|宏开关_cmakelists 引用头文件-优快云博客 ↩︎