打包基操
在顶层 CMakeList的末尾加上 cpack模块,
我的测试代码是linux的lvgl代码,用了ffmpeg等外部动态库
bash
# ---------------------- 1. 基础包信息(必填)----------------------
set(CPACK_PACKAGE_NAME "lvglsim") # 安装包名称(如 deb/rpm 包名)
set(CPACK_PACKAGE_VERSION "1.0.0") # 版本号(格式:主.次.修订)
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "LVGL Simulator with Serial/Video Support") # 包简介
set(CPACK_PACKAGE_CONTACT "your_email@example.com") # 维护者邮箱(可选)
set(CPACK_PACKAGE_INSTALL_DIRECTORY "lvglsim") # 安装根目录(默认 /usr/local,可改)
bash
# ---------------------- 2. 安装路径配置(可选,默认 /usr/local)----------------------
# 若需自定义安装路径(如 /opt/lvglsim),设置以下变量:
# set(CMAKE_INSTALL_PREFIX "/opt/lvglsim") # 全局安装前缀,会影响所有 install 目标
bash
#包含一个模块,该模块会自动检测并安装目标系统上所需的系统库。
#这通常用于确保在生成的安装包中包含所有必要的动态链接库(DLL 或 SO 文件),以便在目标系统上运行应用程序。
include(InstallRequiredSystemLibraries)
#设置CPack变量,指定安装包包含的许可证
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/License.txt")
#CPack变量,指定安装包的主要版本号
set(CPACK_PACKAGE_VERSION_MAJOR "${Tutorial_VERSION_MAJOR}")
#CPack变量,指定安装包的次要版本号
set(CPACK_PACKAGE_VERSION_MINOR "${Tutorial_VERSION_MINOR}")
#指定生成的安装包格式
set(CPACK_GENERATOR "TGZ")
#指定生成的源码包格式
set(CPACK_SOURCE_GENERATOR "TGZ")
#包含CPack模块,启用CPack功能
include(CPack)
bash
# ---------------------- 4. 安装目标确认(已在原 CMake 配置,无需修改)----------------------
# 安装源为lvglsim
# 安装类型为RUNTIME可执行程序
# 安装目的地为 bin目录
install(TARGETS lvglsim
RUNTIME DESTINATION bin # 可执行文件安装到 <安装前缀>/bin(如 /usr/local/bin)
)
然后我看 LVGL提供的原版cmakeList.txt里面已经有了
bash
#安装 lvgl_linux 相关头文件
install(DIRECTORY src/lib/ #指定要安装的源目录,/指目录下的文件,而非目录本身
DESTINATION include/lvgl #目标安装目录,
#默认路径:
# ${CMAKE_INSTALL_PREFIX}/include/lvgl
#(CMAKE_INSTALL_PREFIX 默认是 /usr/local),
# 即最终安装到 /usr/local/include/lvgl
FILES_MATCHING # 开启文件筛选模式,只安装符合后续 PATTERN 规则的文件
PATTERN "backends*" EXCLUDE # 排除所有以 backends 开头的文件 / 目录
PATTERN "*.h") # 仅保留后缀为 .h 的头文件
bash
install(TARGETS lvgl_linux # 指定要安装的目标:
# lvgl_linux 是之前通过 add_library(lvgl_linux STATIC ...)
# 定义的静态库目标(STATIC 表示静态库)。
ARCHIVE DESTINATION lib #指定要安装目标的的安装路径:
#- ARCHIVE:是 CMake 中 "静态库" 的专用类型(对应 .a 文件,Windows 下是 .lib)。
#- DESTINATION lib:目标目录是 ${CMAKE_INSTALL_PREFIX}/lib,默认即 /usr/local/lib。
#- 最终安装的文件是:/usr/local/lib/liblvgl_linux.a(静态库文件名默认是 lib+目标名+.a)。
)


CMAKE官方其实有打包的例程。
下面是我自己在LVGL的CMakeList.txt末尾额外添加的代码
bash
# ---------------------- 1. 基础包信息(必填)----------------------
set(CPACK_PACKAGE_NAME "lvglsim") # 安装包名称(如 deb/rpm 包名)
set(CPACK_PACKAGE_VERSION "1.0.0") # 版本号(格式:主.次.修订)
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "LVGL Simulator with Serial/Video Support") # 包简介
set(CPACK_PACKAGE_CONTACT "18967107546@163.com") # 维护者邮箱(可选)
set(CPACK_PACKAGE_INSTALL_DIRECTORY "lvglsim") # 安装根目录(默认 /usr/local,可改)
#包含一个模块,该模块会自动检测并安装目标系统上所需的系统库。
#这通常用于确保在生成的安装包中包含所有必要的动态链接库(DLL 或 SO 文件),以便在目标系统上运行应用程序。
include(InstallRequiredSystemLibraries) #此处主要是对.tar.gz格式有用,
#设置CPack变量,指定安装包包含的许可证
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE")
#CPack变量,指定安装包的主要版本号
# set(CPACK_PACKAGE_VERSION_MAJOR "${Tutorial_VERSION_MAJOR}") 由于前面通过set明确指定了版本号,因此此处多余.
#CPack变量,指定安装包的次要版本号
# set(CPACK_PACKAGE_VERSION_MINOR "${Tutorial_VERSION_MINOR}")
#指定生成的安装包格式
# set(CPACK_GENERATOR "TGZ")
#指定生成的源码包格式
#set(CPACK_SOURCE_GENERATOR "TGZ")
#包含CPack模块,启用CPack功能
# ---------------------- 2. 安装路径配置(可选,默认 /usr/local)----------------------
# 若需自定义安装路径(如 /opt/lvglsim),设置以下变量:
# set(CMAKE_INSTALL_PREFIX "/opt/lvglsim") # 全局安装前缀,会影响所有 install 目标
# ---------------------- 3. 打包格式(已配置 TGZ,可扩展)----------------------
# 除了默认 TGZ,可添加 DEB(Debian/Ubuntu)、RPM(CentOS/Fedora)格式:
if(CMAKE_SYSTEM_NAME MATCHES "Linux")
#将DEB追加赋给 CPACK_GENERATOR
list(APPEND CPACK_GENERATOR "DEB")# 同时生成"DEB" "RPM" "TGZ"3种格式,可扩展,我这里只用了DEB
# DEB 包额外配置(依赖自动检测)
set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON) # 自动检测 DEB 包依赖的动态库(关键)
set(CPACK_DEBIAN_PACKAGE_SECTION "utils") # DEB 包分类(如 utils、libs)
# RPM 包额外配置
# set(CPACK_RPM_PACKAGE_REQUIRES "ffmpeg, SDL2, libevdev") # 手动指定 RPM 依赖(可选)
endif()
include(CPack) #启用CPack
# 安装可执行文件
install(TARGETS lvglsim
RUNTIME DESTINATION bin
)
打包成不同格式的包管理能力不同


打包指令
bash
cd build # 进入构建目录
cmake .. # 重新加载 CMakeLists.txt(关键,确保 CPack 配置生效)
bash
make package # 执行打包(依赖 make 编译完成,会自动调用 CPack)

打包图片
如果是png之类的格式,其实就是通过Install(DIRECTORY xxx )
这种格式,指定安装DEB包的时候,图片复制到纯净系统的什么路径下。
可以在cmakeList的末尾添加:
bash
# 设置安装图片资源的路径
set(IMAGE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src/ImageSrc/Logo)
install(DIRECTORY ${IMAGE_DIR}/
DESTINATION share/${CPACK_PACKAGE_NAME}/images
FILES_MATCHING PATTERN "*.c") # 根据实际图片文件类型调整
代码中动态读取安装路径
cpp
# 定义图片安装路径变量,供代码使用
set(APP_IMAGE_PATH "/usr/share/${CPACK_PACKAGE_NAME}/images" CACHE PATH "Path to installed images")
target_compile_definitions(lvglsim PRIVATE APP_IMAGE_PATH="${APP_IMAGE_PATH}")
bash
// 示例:获取图片路径
const char *image_path = APP_IMAGE_PATH "/BT.c"; // 根据实际图片文件名调整
然后项目中创建build文件夹,进入该文件夹
cmake .. 执行 cmakelist,
cmakelist是 cmake的配置文件,这里的..是包含cmakelist文件所在项目的根目录,是告诉cmake去该目录下找cmakelist执行。生成build目录下的构建文件。(通常cmakelist中会用execute指定要生成的可执行文件)

由于我的测试项目是lvgl,png直接转换成了.c,而.c文件作为源文件处于 cmakelist的编译链中,所以其实不需要这一步。
Cmake关于链接外部库的方式
pkg-config工具查找
还是以LVGL for linux为例子,
下面是通过 pkg-config查找ffmpeg所有必须库的例子,我是直接放在 cmakelist的末尾,
execute(lvglsim xxx) 之后,否则会说lvglsim未定义
bash
# 1. 查找 pkg-config(系统已支持,无需额外安装)
find_package(PkgConfig REQUIRED)
# 2. 通过 pkg-config 查找 FFmpeg 所有必需库(与终端输出的库对应)
pkg_check_modules(FFMPEG REQUIRED
libavcodec # 对应 -lavcodec(avcodec_send_packet 等函数)
libavformat # 对应 -lavformat(avformat_open_input 等函数)
libswscale # 对应 -lswscale(sws_getContext/sws_scale 等函数)
libavdevice # 对应 -lavdevice(设备输入相关,若用到需保留)
libavutil # 对应 -lavutil(av_packet_unref/av_frame_free 等函数)
)
# 4. 为 lvglsim 添加 FFmpeg 头文件目录(确保编译时能找到 avcodec.h 等)
target_include_directories(lvglsim PRIVATE ${FFMPEG_INCLUDE_DIRS})
#上面PRIVATE制定了依赖的作用域,不加就是默认public,所有和lvglsim相关的依赖都会继承该依赖
target_link_libraries(lvglsim ${FFMPEG_LDFLAGS})
原生依赖查找方式

bash
# 设置 FFmpeg 头文件目录
set(FFMPEG_INCLUDE_DIR /usr/include/aarch64-linux-gnu)
include_directories(${FFMPEG_INCLUDE_DIR})
# 设置 FFmpeg 库文件目录
set(FFMPEG_LIBRARY_DIR /usr/lib/aarch64-linux-gnu)
link_directories(${FFMPEG_LIBRARY_DIR})
# 手动查找每个库
find_library(AVCODEC_LIB avcodec HINTS ${FFMPEG_LIBRARY_DIR})
find_library(AVFORMAT_LIB avformat HINTS ${FFMPEG_LIBRARY_DIR})
find_library(SWSCALE_LIB swscale HINTS ${FFMPEG_LIBRARY_DIR})
find_library(AVDEVICE_LIB avdevice HINTS ${FFMPEG_LIBRARY_DIR})
find_library(AVUTIL_LIB avutil HINTS ${FFMPEG_LIBRARY_DIR})
# 检查是否找到所有库
if(NOT AVCODEC_LIB OR NOT AVFORMAT_LIB OR NOT SWSCALE_LIB OR NOT AVDEVICE_LIB OR NOT AVUTIL_LIB)
message(FATAL_ERROR "❌ FFmpeg libraries not found!")
else()
message(STATUS "✅ Found FFmpeg libraries")
endif()
# 链接到你的可执行程序
target_link_libraries(lvglsim PRIVATE
${AVCODEC_LIB}
${AVFORMAT_LIB}
${SWSCALE_LIB}
${AVDEVICE_LIB}
${AVUTIL_LIB}
)