C++ linux打包运行方案(cmake)

文章目录

背景

使用C++编写的一个小项目,需要打包成ubuntu下的可执行文件,方便分发给其他ubuntu执行,因为docker镜像方案过于臃肿,所以需要把项目的动态库都打在软件包中,分发之后可以直接运行,而不需要再重复安装。

动态库

经过依赖精简和梳理,项目最终必须依赖的动态库包括:pcl, yaml, rosbag(用于读取rosbag包)

打包方案

第一步尝试将所有动态库转为静态库安装,发现 pcl 和 rosbag 间接依赖太多,只好暂时先将yaml库转为静态库,这里使用的方式是直接把yaml的源码包含进来。

动态库转静态库

这里把yaml的源码下载到 项目目录/thirdparty/yaml-cpp目录结构如下:

在CMakeLists.txt中, 相关改动如下:

cmake 复制代码
...
# 添加子目录编译 yaml-cpp 库
add_subdirectory(thirdparty/yaml-cpp)
...
target_include_directories(ExeFileName PUBLIC 
  ...
  ${CMAKE_SOURCE_DIR}/thirdparty/yaml-cpp/include
)
target_link_libraries(ExeFileName PUBLIC 
  ...
  yaml-cpp
  ...
)
...

动态库打到软件包中

这里用到了linuxdeploy-x86_64.AppImage工具,安装方式为:

shell 复制代码
wget https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage -O /usr/local/bin/linuxdeploy
chmod +x /usr/local/bin/linuxdeploy

我们以pcl库为例,实际依赖库链接方式保持不变,只是需要在CMakeLists.txt最后加上对应的用于linuxdeploy的内容即可:

cmake 复制代码
...
find_package(PCL REQUIRED COMPONENTS io)
...
target_include_directories(ExeFileName PUBLIC 
  ${PCL_INCLUDE_DIRS}
  ...
)

# 链接库
target_link_libraries(ExeFileName PUBLIC 
  ${PCL_LIBRARIES} 
  ...
)

# 设置安装路径为 AppDir 结构
install(TARGETS ExeFileName DESTINATION usr/bin)

# 设置 RPATH(确保运行时库加载正确)
set_target_properties(ExeFileName PROPERTIES
    INSTALL_RPATH "$ORIGIN/../lib"  # 相对路径指向 ../lib
    BUILD_WITH_INSTALL_RPATH TRUE
    INSTALL_RPATH_USE_LINK_PATH TRUE
)

# 修改原有的打包命令,确保在 Ubuntu 18.04 中兼容
add_custom_target(bundle_appimage_all_in_one
    COMMAND mkdir -p AppDir/usr/lib
    COMMAND linuxdeploy --appdir AppDir    
        -e $<TARGET_FILE:ExeFileName>        
        --output appimage     
        --plugin none             
        --executable $<TARGET_FILE:ExeFileName>  # 显式指定可执行文件
    WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
    DEPENDS ExeFileName
)

注意: 尽量在ubuntu低版本比如18.04上进行打包,以确保高版本ubuntu能向下兼容运行

在编译打包脚本中需要增加linuxdeploy指令进行打包:

shell 复制代码
linuxdeploy --appdir AppDir -e ./ExeFileName \
    --library /lib/x86_64-linux-gnu/libusb-1.0.so.0 \
    --library /lib/x86_64-linux-gnu/libexpat.so.1

因为在运行时发现还是报错,缺少依赖库,所以在linuxdeploy打包时把缺少的动态库显式指定出来。

运行

运行命令为:

bash 复制代码
LD_LIBRARY_PATH=./AppDir/usr/lib ./AppDir/usr/bin/ExeFileName ...

这里要强制带上LD_LIBRARY_PATH,这个问题有待解决,不过不影响使用。

相关推荐
昌原的儿子LEO13 分钟前
进程和线程(2)
linux·服务器·网络
IKUN家族27 分钟前
SpringBoot日志
java·开发语言
迷迭香yy29 分钟前
Python构建转融券多空识别系统从接口到因子的全流程 IG50免费开源股票数据API接口
开发语言·python·开源
格林威34 分钟前
C#图像快速剪切:使用OpenCvSharp和Halcon优化图像剪切和CPU占用
开发语言·人工智能·数码相机·计算机视觉·c#·视觉检测·工业相机
会飞的土拨鼠呀1 小时前
Linux 真实内存使用率的核心计算标准
linux·运维·服务器
知识分享小能手1 小时前
概理论与数理统计学习教程,从入门到精通,在数理统计中应用R软件(22)
开发语言·学习·r语言
乐观勇敢坚强的老彭1 小时前
C++信奥GESP四级的常见题型和解题模板速查表
开发语言·c++
denggun123451 小时前
信号量(DispatchSemaphore vs AsyncSemaphore)、swift协作式线程池 and python信号量
开发语言·python·swift
lisw051 小时前
计算与科学哲学(Philosophy of Computing and Science)
java·开发语言·人工智能
欧特克_Glodon1 小时前
OpenCV计算机视觉开发入门与实践<二十二>:图像平滑之线性滤波
c++·人工智能·opencv·计算机视觉