小鱼 ROS 2 新书上线!点击链接查看, 新书配套视频点击链接查看。
提问前必看的发帖注意事项—— 提问前必看!不符合要求的问题拒绝回答!!
社区使用指南—如何添加标签修改密码
如何将第三方库封装成ros2包并提供给其他包用
-
最近需要对几个节点用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
-
你遇到的错误是因为在 CMake 配置文件中,你试图安装一个名为
profiler
的目标,但是这个目标并没有在 CMake 文件中被正确定义或找到。在你的情况中,你通过add_library
声明了一个 IMPORTED 的库,但可能在某些情况下,LIB_PATH
变量没有正确设置或者路径解析不正确。首先,确保
LIB_PATH
变量正确地指向了包含.so
文件的目录。由于你的CMakeLists.txt
文件中没有直接检查或验证LIB_PATH
的值,这可能是一个问题。其次,你应该在尝试安装库之前确保profiler
目标已经正确设置。以下是一些修改建议:
-
确保
LIB_PATH
正确设置:你可以添加一些打印语句来检查LIB_PATH
的值。 -
使用条件来检查
LIB_PATH
下的文件是否存在:这可以帮助避免在文件不存在时尝试设置目标。 -
确保安装命令在目标设置之后:安装命令应该在目标
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
文件确实存在于该目录中。
以上为生成回答,仅供参考~
-
-
@naoketeng 看看build下有没有生成:profiler
-
此回复已被删除! -
用折中方案解决了
既然so无法导出,就干脆只导出头文件
以下是修改完的cmakecmake_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 )
-
@naoketeng 写个pkg-config把,然后用cmake的pkg-config模块去找
-
@naoketeng 另一个办法就是直接把https://github.com/gperftools/gperftools打包成deb。我看这个项目用的autotools,打包deb应该比较方便。