鱼香ROS社区
    • 版块
    • 最新
    • 未解决
    • 已解决
    • 群组
    • 注册
    • 登录
    紧急通知:禁止一切关于政治&VPN翻墙等话题,发现相关帖子会立马删除封号
    提问前必看的发帖注意事项: 社区问答规则(小鱼个人)更新 | 高质量帖子发布指南

    如何将第三方库封装成ros2包并提供给其他包用

    已定时 已固定 已锁定 已移动
    ROS 2相关问题
    ros2 第三方库 工程实践
    4
    7
    364
    正在加载更多帖子
    • 从旧到新
    • 从新到旧
    • 最多赞同
    回复
    • 在新帖中回复
    登录后回复
    此主题已被删除。只有拥有主题管理权限的用户可以查看。
    • naoketengN
      naoketeng
      最后由 编辑

      最近需要对几个节点用gperftools分析性能,网上没有找到gperftools_ros包,只能手动编译,然后用target_link_libraries指定库。
      部署的平台也有amd64和arm64之分,经常倒腾来倒腾去。
      就想着自己封装成ros2通用包,其他包需要时,改一下依赖就行

      ros2_gperftools目录结构

      .
      ├── CMakeLists.txt
      ├── include
      │   └── gperftools
      │       ├── heap-checker.h
      │       ├── heap-profiler.h
      │       ├── malloc_extension_c.h
      │       ├── malloc_extension.h
      │       ├── malloc_hook_c.h
      │       ├── malloc_hook.h
      │       ├── nallocx.h
      │       ├── profiler.h
      │       ├── stacktrace.h
      │       └── tcmalloc.h.in
      ├── libamd64
      │   ├── libprofiler.so -> libprofiler.so.5.11.5
      │   ├── libprofiler.so.5.11.5
      │   ├── libtcmalloc.so -> libtcmalloc.so.9.16.5
      │   └── libtcmalloc.so.9.16.5
      ├── libarm
      └── package.xml
      
      4 directories, 16 files
      

      下面是我写的CMakeLists.txt

      cmake_minimum_required(VERSION 3.8)
      project(ros2_gperftools)
      
      if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
        add_compile_options(-Wall -Wextra -Wpedantic)
      endif()
      
      # 检测CMake是否设置为交叉编译
      if(${CMAKE_CROSSCOMPILING})
        message(STATUS "The system is aarch64.")
        set(LIB_PATH libarm)
      else()
        message(STATUS "The system is amd64.")
        set(LIB_PATH libamd64)
      endif()
      
      
      # find dependencies
      find_package(ament_cmake REQUIRED)
      
      add_library(profiler SHARED IMPORTED)
      set_target_properties(profiler PROPERTIES IMPORTED_LOCATION ${LIB_PATH}/libprofiler.so)
      
      install(DIRECTORY include/
      	DESTINATION include
      )
      
      install(TARGETS profiler
      	LIBRARY DESTINATION lib
      )
      
      ament_export_include_directories(include)
      ament_export_targets(profiler HAS_LIBRARY_TARGET)
      ament_package()
      
      

      编译一直报错😵 😵,看着感觉也没写错哇,目标也指定了

      Starting >>> ros2_gperftools
      --- stderr: ros2_gperftools                         
      CMake Error at CMakeLists.txt:28 (install):
        install TARGETS given target "profiler" which does not exist.
      
      
      gmake: *** [Makefile:226:cmake_check_build_system] 错误 1
      ---
      Failed   <<< ros2_gperftools [0.19s, exited with code 2]
                                      
      Summary: 0 packages finished [0.40s]
        1 package failed: ros2_gperftools
        1 package had stderr output: ros2_gperftools
      
      小鱼小 ganyuanzhenG 2 条回复 最后回复 回复 引用 0
      • 小伊小
        机器人小伊
        最后由 编辑

        你遇到的错误是因为在 CMake 配置文件中,你试图安装一个名为 profiler 的目标,但是这个目标并没有在 CMake 文件中被正确定义或找到。在你的情况中,你通过 add_library 声明了一个 IMPORTED 的库,但可能在某些情况下,LIB_PATH 变量没有正确设置或者路径解析不正确。

        首先,确保 LIB_PATH 变量正确地指向了包含 .so 文件的目录。由于你的 CMakeLists.txt 文件中没有直接检查或验证 LIB_PATH 的值,这可能是一个问题。其次,你应该在尝试安装库之前确保 profiler 目标已经正确设置。

        以下是一些修改建议:

        1. 确保 LIB_PATH 正确设置:你可以添加一些打印语句来检查 LIB_PATH 的值。

        2. 使用条件来检查 LIB_PATH 下的文件是否存在:这可以帮助避免在文件不存在时尝试设置目标。

        3. 确保安装命令在目标设置之后:安装命令应该在目标 profiler 被正确定义之后执行。

        这里是一个修改后的 CMakeLists.txt 示例:

        cmake_minimum_required(VERSION 3.8)
        project(ros2_gperftools)
        
        if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
          add_compile_options(-Wall -Wextra -Wpedantic)
        endif()
        
        # 检测系统架构并设置库路径
        if(DEFINED ENV{ROS_ARCHITECTURE} AND ENV{ROS_ARCHITECTURE} STREQUAL "aarch64")
          message(STATUS "The system is aarch64.")
          set(LIB_PATH libarm)
        elseif(DEFINED ENV{ROS_ARCHITECTURE} AND ENV{ROS_ARCHITECTURE} STREQUAL "amd64")
          message(STATUS "The system is amd64.")
          set(LIB_PATH libamd64)
        else()
          message(FATAL_ERROR "Unsupported architecture")
        endif()
        
        # 检查库文件是否存在
        if(NOT EXISTS ${LIB_PATH}/libprofiler.so)
          message(FATAL_ERROR "libprofiler.so not found in ${LIB_PATH}")
        endif()
        
        # find dependencies
        find_package(ament_cmake REQUIRED)
        
        # 导入库
        add_library(profiler SHARED IMPORTED)
        set_target_properties(profiler PROPERTIES IMPORTED_LOCATION ${LIB_PATH}/libprofiler.so)
        
        # 安装头文件和库
        install(DIRECTORY include/
                DESTINATION include
        )
        
        install(TARGETS profiler
                LIBRARY DESTINATION lib
        )
        
        ament_export_include_directories(include)
        ament_export_targets(profiler HAS_LIBRARY_TARGET)
        ament_package()
        

        注意几个改动:

        • 使用 ENV{ROS_ARCHITECTURE} 来检查环境变量中的架构,这是 ROS 2 中常用的方式。
        • 添加了检查 libprofiler.so 文件是否存在的逻辑。
        • 确保 install(TARGETS ...) 在 add_library 之后。

        这些修改应该能帮助你解决编译问题。如果问题仍然存在,请检查 LIB_PATH 变量的值是否确实指向了正确的目录,并且 .so 文件确实存在于该目录中。


        以上为生成回答,仅供参考~

        我是小伊,已接入ChatGpt,所有回复,仅供参考~

        1 条回复 最后回复 回复 引用 0
        • 小鱼小
          小鱼 技术大佬 @naoketeng
          最后由 编辑

          @naoketeng 看看build下有没有生成:profiler

          新书配套视频:https://www.bilibili.com/video/BV1GW42197Ck/

          naoketengN 1 条回复 最后回复 回复 引用 0
          • naoketengN
            naoketeng @小鱼
            最后由 编辑

            此回复已被删除!
            1 条回复 最后回复 回复 引用 0
            • naoketengN
              naoketeng
              最后由 编辑

              用折中方案解决了
              既然so无法导出,就干脆只导出头文件
              以下是修改完的cmake

              cmake_minimum_required(VERSION 3.8)
              project(ros2_gperftools)
              
              if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
                add_compile_options(-Wall -Wextra -Wpedantic)
              endif()
              
              # 检测CMake是否设置为交叉编译
              if(${CMAKE_CROSSCOMPILING})
                message(STATUS "The system is aarch64.")
                set(LIB_PATH libarm)
              else()
                message(STATUS "The system is amd64.")
                set(LIB_PATH libamd64)
              endif()
              
              
              # find dependencies
              find_package(ament_cmake REQUIRED)
              
              install(DIRECTORY include/
              	DESTINATION include
              )
              
              install(DIRECTORY ${LIB_PATH}/
              	DESTINATION lib
              )
              
              ament_export_include_directories(include)
              ament_package()
              

              其他包需要依赖ros2_gperftools时
              xml

              <depend>ros2_gperftools</depend>
              

              CMakeLists.txt

              find_package(ros2_gperftools REQUIRED)
              
              target_link_libraries( ${PROJECT_NAME} PUBLIC
              	${CMAKE_INSTALL_PREFIX}/lib/libprofiler.so
              )
              
              ament_target_dependencies(${PROJECT_NAME} PUBLIC
              	ros2_gperftools
              )
              
              ganyuanzhenG 1 条回复 最后回复 回复 引用 0
              • ganyuanzhenG
                Elysia 技术大佬 @naoketeng
                最后由 编辑

                @naoketeng 写个pkg-config把,然后用cmake的pkg-config模块去找

                我难道就没有一段英勇,美好而又虚幻的过去……幸运地写在金叶片上?

                1 条回复 最后回复 回复 引用 0
                • ganyuanzhenG
                  Elysia 技术大佬 @naoketeng
                  最后由 编辑

                  @naoketeng 另一个办法就是直接把https://github.com/gperftools/gperftools打包成deb。我看这个项目用的autotools,打包deb应该比较方便。

                  我难道就没有一段英勇,美好而又虚幻的过去……幸运地写在金叶片上?

                  1 条回复 最后回复 回复 引用 0
                  • 第一个帖子
                    最后一个帖子
                  皖ICP备16016415号-7
                  Powered by NodeBB | 鱼香ROS