ROS1、ROS2如何把预编译好的二进制文件封装成功能包?

开发板推荐:天空星STM32F407VET6开发板

超高性价比 STM32主控 | 超高主频 | 一板兼容百芯 | 比赛神器 | 沉金彩色丝印

当我们编译一个第三方功能包的时候,会通过cmake指令,将源码编译好,并通过make install安装到系统目录下。

如果希望预编译好的二进制文件,封装成一个ros的功能包,该怎么做呢?

本文要求你掌握Cmake和ROS1、ROS2的基础,涉及到的细节操作这里不做介绍,只介绍核心操作步骤。

第一步,先找到编译好的二进制文件和头文件

假如我们的库名叫xxx,那么make install后,头文件会放在/usr/local/include/xxx/下;而.so则会放在/usr/local/lib/下,例如/usr/local/lib/libxxx.so。

第二步,创建ros功能包(以ROS2为例)

ros2 pkg create xxx --build-type ament_cmake

第三步,将第一步找到的头文件和.so文件,挪到你创建的功能包下

此处自行操作。可以把头文件的内容放到功能包的include目录下,相关的lib文件,放到libamd64 或 libarm64 目录下。

第四步,修改CmakeLists(核心):

cmake_minimum_required(VERSION 3.8)
project(xxx)

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

find_package(ament_cmake REQUIRED)

if(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64")
    set(LIB_PATH "libarm64")  # ARM架构
else()
    set(LIB_PATH "libamd64")  # x86_64架构
endif()
# 收集所有动态库文件(包括带版本号的文件)
file(GLOB LIBRARY_FILES "${CMAKE_CURRENT_SOURCE_DIR}/${LIB_PATH}/*.so*")


# 过滤掉符号链接,只保留真实文件
set(REAL_LIBS "")
foreach(file IN LISTS LIBRARY_FILES)
    if(NOT IS_SYMLINK ${file})
        list(APPEND REAL_LIBS ${file})
    endif()
endforeach()

# 为每个真实库文件创建 IMPORTED 目标
set(ALL_IMPORTED_LIBS "")
foreach(lib_file IN LISTS REAL_LIBS)
    get_filename_component(lib_name ${lib_file} NAME)
    
    # 生成唯一的目标名称(例如:libxxx.so.3.7 → xxx_so_3_7)
    string(REGEX REPLACE "^lib" "" base_name ${lib_name})  # 移除前缀 "lib"
    string(REGEX REPLACE "[.]" "_" target_name ${base_name})  # 替换 "." 为 "_"
    
    # 创建 IMPORTED 目标
    add_library(${target_name} SHARED IMPORTED)
    set_target_properties(${target_name} PROPERTIES
        IMPORTED_LOCATION ${lib_file}  # 指向真实文件路径
    )
    
    # 将目标名称加入列表,用于后续导出
    list(APPEND ALL_IMPORTED_LIBS ${target_name})
endforeach()

# 安装头文件和库文件
install(DIRECTORY include/ DESTINATION include)
install(FILES ${REAL_LIBS} DESTINATION lib)  # 安装真实文件而非符号链接

ament_export_include_directories(include)
ament_export_libraries(${ALL_IMPORTED_LIBS})  # 导出所有 IMPORTED 目标





if(BUILD_TESTING)
  find_package(ament_lint_auto REQUIRED)
  # the following line skips the linter which checks for copyrights
  # comment the line when a copyright and license is added to all source files
  set(ament_cmake_copyright_FOUND TRUE)
  # the following line skips cpplint (only works in a git repo)
  # comment the line when this package is in a git repo and when
  # a copyright and license is added to all source files
  set(ament_cmake_cpplint_FOUND TRUE)
  ament_lint_auto_find_test_dependencies()
endif()

ament_package()

这里有两点核心:

1.通过for指令,反复使用add_library 和 set_target_propeties,把你文件夹下的二进制文件打成一个library。

2.通过ament_export相关指令,导出这些内容,使得其他功能包可以正常使用。当然,如果你用的是ROS1的caktin编译系统,则换成catkin_package系列指令:

catkin_package(
  INCLUDE_DIRS include
  LIBRARIES my_library
)

开发板推荐:天空星STM32F407VET6开发板

超高性价比 STM32主控 | 超高主频 | 一板兼容百芯 | 比赛神器 | 沉金彩色丝印

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值