CMake之CPack

news/2024/11/24 6:49:25/

文章目录

  • 一、CPack
    • 1.用CPack打包成为deb包
    • 2.如何确定的Depends依赖包?
    • 3.如何确定编译Build-Depends?
    • 4.Cpakc打包RPM包
  • 二、deb的简单使用
  • 三、deb包相关文件说明
    • 1.control文件
    • 2.preinst文件
    • 3.postinst文件
    • 4.prerm文件
    • 5.postrm文件

一、CPack

CPack 是 CMake 2.4.2 之后的一个内置工具,用于创建软件的二进制包和源代码包。
CPack 在整个 CMake 工具链的位置。
在这里插入图片描述
CPack,则是CMake下的一个打包工具,其支持将软件打包成 .deb, .zip, .7z 等各种各样的软件包;

1.用CPack打包成为deb包

使用CPack其实很简单,核心只有两步:

  • 设定软件包的属性(例如:包名称,包类型,版本号,作者等信息)
  • 指定需要打包的文件(例如:可执行文件,静态库,动态库)
cmake_minimum_required(VERSION 3.10)# 设置项目名
project(CMakeTutorial VERSION 1.2)# 添加头文件搜索路径
include_directories(
${PROJECT_SOURCE_DIR}/inc
)# 生成库
add_library(PrinterChar STATIC src/printer_char.cpp)    # 静态库
add_library(PrinterInt SHARED src/printer_int.cpp)      # 动态库# 添加需要构建的可执行文件
#------方法对比 1.1 - 不用库的写法
# add_executable(LinkLibraryDemo link_library_demo.cpp src/printer_char.cpp src/printer_int.cpp)
#------方法对比 1.2 - 用库的写法
add_executable(LinkLibraryDemo demo/link_library_demo.cpp)
target_link_libraries(LinkLibraryDemo PRIVATE PrinterChar)   # 为目标添加静态库
target_link_libraries(LinkLibraryDemo PRIVATE PrinterInt)    # 为目标添加动态库##---------------- 以下为用CPack打包成deb包的内容 ----------------##
# 指定deb包的版本号
set(_VERSION_MAJOR 1)
set(_VERSION_MINOR 2)
set(_VERSION_PATCH 3)
set(CPACK_PACKAGE_VERSION_MAJOR "${_VERSION_MAJOR}")
set(CPACK_PACKAGE_VERSION_MINOR "${_VERSION_MINOR}")
set(CPACK_PACKAGE_VERSION_PATCH "${_VERSION_PATCH}")
# 指定CPack生成的是deb包(还可以是其他包如 <.7z> <.zip> 等)
set(CPACK_GENERATOR "DEB")
# 指定包名
set(CPACK_PACKAGE_NAME "mork_printer_package_demo")
# 指定程序名,就是程序安装后的名字
set(CPACK_DEBIAN_PACKAGE_NAME "mork_printer_project_demo")
# 指定运行的计算机架构
set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "amd64")
# 指定所需的依赖
# set(CPACK_DEBIAN_PACKAGE_DEPENDS "libgrpc++")
# 设置包作者的联系方式
set(CPACK_PACKAGE_CONTACT "supporter@gmail.com")
# 设置维护人
set(CPACK_DEBIAN_PACKAGE_MAINTAINER "members of support@gmail.cn")
# 指定需要安装的文件
INSTALL(TARGETS LinkLibraryDemo PrinterInt PrinterCharRUNTIME DESTINATION /tmp/cmake_demo#LIBRARY DESTINATION /tmp/cmake_demo    # 通常,编译器只会在 </usr/lib> 和 </lib> 中找头文件,如果#ARCHIVE DESTINATION /tmp/cmake_demo    # 将库文件放在其他目录,可能会引起找不到库文件错误)include(CPack)
#include <iostream>
#include <string>int Add(int t1, int t2)
{int result = t1 + t2;std::cout << t1 << " + " << t2 << " is: " << result << std::endl;return result;
}int main()
{int ret_add;ret_add = Add(1, 2);std::cout << "Hello, this is my first cmake sample "  << ret_add << std::endl;return 0;
}
cmake_minimum_required (VERSION 3.0.0)project (cmake_test VERSION 0.0.4)set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)add_executable(demo main.cpp)# package program
message(STATUS "CPack Configuration added.")include(InstallRequiredSystemLibraries)set(CPACK_PACKAGE_NAME ${PROJECT_NAME})set(CPACK_PACKAGE_VERSION ${PROJECT_VERSION})
set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA"${CMAKE_CURRENT_SOURCE_DIR}/prerm;${CMAKE_CURRENT_SOURCE_DIR}/postrm")
set(CPACK_PACKAGE_DIRECTORY ${CMAKE_BINARY_DIR})
set(CPACK_SOURCE_IGNORE_FILES build)set(CPACK_PACKAGE_CONTACT "xxx@163.com")
set(CPACK_PACKAGE_DESCRIPTION "cpack test program")# set(CPACK_SET_DESTDIR ON)
# # 设置安装到的目录路径
# set(CMAKE_INSTALL_BINDIR "/home/raymond/install")install(TARGETS demoRUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})# according to CMake, CPack must be included LAST
# after all settings have been set
include(CPack)

在上面的CMakeLists.txt中,最重要的是INSTALL这个指令,上面的INSTALL指令所表达的意思是,需要将LinkLibraryDemo, PrinterInt, PrinterChar 这3个文件打包,其中可执行文件放在/tmp/cmake_demo,这个目录中,静态库和动态库文件则放在默认目录中。

如果你不赋值CPACK_DEBIAN_PACKAGE_DEPENDS这个变量,则在debian/control文件中,没有Depends这一行,虽然在你自己的机器上不影响打包构建。但是将deb包提供给他人安装后,可能无法运行。如果添加这一行,则可以在安装时就检查依赖是否满足。

include(InstallRequiredSystemLibraries):这个命令是CMake教程中建议使用的,该命令将包括当前平台项目所需的任何运行时库。
CPACK_PACKAGE_NAME: 包的名称,默认使用项目名称
CPACK_PACKAGE_VERSION : 包的版本,默认使用项目版本
CPACK_PACKAGE_DIRECTORY :cpack要打包的目录,如果没有设置,默认使用编译目录
CPACK_SOURCE_IGNORE_FILES :打包源代码时要排除的目录,默认情况下会将整个工程的目录都打包进源代码,但有些不属于代码的部分或者不想打包的部分可以通过这个变量排除,比如这里的build目录
CPACK_PACKAGE_CONTACT :程序的维护者信息,这是在打包成DEB文件时必须的一个变量
CPACK_PACKAGE_DESCRIPTION : 描述包的信息
install()命令 :描述了包内的文件安装的位置,如可执行文件和共享库等,这里只设置了一个demo的可执行文件。
include(CPack) : 所有的cpack命令需以这个结尾

编译

cmake -B build 
cmake --build build --target package(cmake --build build --target help) 打包install()的内容
cmake --build build --target package_source,打包源码

不用Cmake:Ubuntu Deb 安装包的内容可以 参考

更多例子请参考:

  • cmake菜谱

2.如何确定的Depends依赖包?

使用ldd查看可执行软件链接的动态库。

 ldd xweather | grep [Qq]tlibQt5Widgets.so.5 => /lib/x86_64-linux-gnu/libQt5Widgets.so.5 (0x00007ff241739000)                libQt5Gui.so.5 => /lib/x86_64-linux-gnu/libQt5Gui.so.5 (0x00007ff2411ae000)                        libQt5Network.so.5 => /lib/x86_64-linux-gnu/libQt5Network.so.5 (0x00007ff24100d000)                libQt5Core.so.5 => /lib/x86_64-linux-gnu/libQt5Core.so.5 (0x00007ff240b12000)需要确定这些动态库都在哪些软件包里。
$ dpkg -S libQt5Widgets.so.5 
libqt5widgets5:amd64: /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5.11
libqt5widgets5:amd64: /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
libqt5widgets5:amd64: /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5.11.3通过上面的步骤,我们就可以得到libQt5Widgets.so.5这个动态库在libqt5widgets5这个包中
将这些软件包名赋值给CPACK_DEBIAN_PACKAGE_DEPENDS即可。
SET(CPACK_DEBIAN_PACKAGE_DEPENDS "libqt5core5a, libqt5widgets5, libqt5network5, libqt5gui5")

3.如何确定编译Build-Depends?

The devscripts package provides a collection of scripts which may be of use to Debian developers and others wishing to build Debian packages.

sudo apt-get install devscripts

要找出编译你的软件所需的软件包可以使用这个命令

$ dpkg-depcheck -d your_build_exec_binary
Packages needed:fonts-lohit-deva

另一种方法可以执行

$ objdump -p your_build_exec_binary | grep NEEDEDNEEDED               libQt5Widgets.so.5

通过上述两个办法获取到动态库后,执行下面的命令,获取开发包。

$ dpkg -S libQt5Network | grep dev
qtbase5-dev:amd64: /usr/lib/x86_64-linux-gnu/libQt5Network.so

填入到Build-Depends中即可。

4.Cpakc打包RPM包

参考:

  • CPack 入门指南

二、deb的简单使用

查看一下这个deb软件包的信息和内容:

查看控制文件内容
dpkg-deb -I <deb包文件>查看打包的内容
dpkg -c <deb包文件>sudo dpkg -i <deb包文件>	# 安装deb包
sudo dpkg -l			# 显示已经安装的包
sudo dpkg -P <包名称>	# 卸载指定的软件包dpkg-deb -R X.deb. X 解压包
dpkg-deb -X X.deb X 解压包#安装(解包并配置) 
dpkg -i|--install <.deb file name>
#dpkg -i mydeb-1.deb#强制安装
dpkg --force-depends -i mydeb-1.deb#解包:该命令仅对 “mydeb-1.deb”进行解包操作,不会执行包配置工作
dpkg --unpack mydeb-1.deb#卸载:删除包,但保留配置文件
dpkg -r|--remove <package> 
# dpkg -r my-deb 
#该命令删除包,且删除配置文件
dpkg -P|--purge my-deb         #查看deb包是否安装/deb包的信息 
dpkg -s|--status <package>
# dpkg -s my-deb#查看deb包文件内容 
dpkg -c mydeb-1.deb#查看当前目录某个deb包的信息
dpkg --info mydeb-1.deb#解压deb中所要安装的文件
#第一个参数为所要解压的deb包,第二个参数为将deb包解压到指定的目录
dpkg -x  mydeb-1.deb mydeb-1#解压deb包中DEBIAN目录下的文件(至少包含control文件)
dpkg -e mydeb-1.deb mydeb-1/DEBIAN#列出与该包关联的文件 dpkg -L|--listfiles <package>
dpkg -L my-deb #配置软件包 
dpkg --configure <package>
# dpkg --configure my-deb#解压deb包中DEBIAN目录下的文件(至少包含control文件)
dpkg -e mydeb-1.deb mydeb-1/DEBIAN#列出与该包关联的文件 dpkg -L|--listfiles <package>
dpkg -L my-deb #配置软件包 
dpkg --configure <package>
# dpkg --configure my-deb

三、deb包相关文件说明

1.control文件

control 文件字段解析
字段 用途 例子/其他
Package 程序名称 中间不能有空格
Version 软件版本
Description 程序说明
Section 软件类别 utils, net, mail, text, x11
Priority 软件对于系统的重要程度 required, standard, optional, extra等;
Essential 是否是系统最基本的软件包 yes/no,若为yes,则不允许卸载(除非强制性卸载)
Architecture 软件所支持的平台架构 i386, amd64, m68k, sparc, alpha, powerpc等
Source 软件包的源代码名称
Depends 软件所依赖的其他软件包和库文件 若依赖多个软件包和库文件,采用逗号隔开
Pre-Depends 软件安装前必须安装、配置依赖性的软件包和库文件 常用于必须的预运行脚本需求
Recommends 推荐安装的其他软件包和库文件
Suggests 建议安装的其他软件包和库文件

2.preinst文件

在Deb包文件解包之前(即软件安装前),将会运行该脚本。可以停止作用于待升级软件包的服务,直到软件包安装或升级完成

3.postinst文件

负责完成安装包时的配置工作。如新安装或升级的软件重启服务

#软件安装完后,执行该Shell脚本,一般用来配置软件执行环境,必须以“#!/bin/sh”为首行#!/bin/sh
echo "my deb" > /root/mydeb.log#!/bin/sh
if [ "$1" = "configure" ]; then
/Applications/MobileLog.app/MobileLog -install
/bin/launchctl load -wF /System/Library/LaunchDaemons/com.iXtension.MobileLogDaemon.plist 
fi

4.prerm文件

该脚本负责停止与软件包相关联的daemon服务。它在删除软件包关联文件之前执行

#!/bin/sh
if [[ $1 == remove ]]; then
/Applications/MobileLog.app/MobileLog -uninstall
/bin/launchctl unload -wF /System/Library/LaunchDaemons/com.iXtension.MobileLogDaemon.plist 
fi

5.postrm文件

#软件卸载后,执行该Shell脚本,一般作为清理收尾工作,必须以“#!/bin/sh”为首行#!/bin/sh
rm -rf /root/mydeb.log

参考:

  • 11.1 生成源代码和二进制包
  • CPACK:我想这个deb安装执行后bash脚本,但它不工作
  • CPack DEB Generator
  • cmake CPack 打包指定目录
  • CPACK_SOURCE_IGNORE_FILES
  • CMake教程(三)- 将工程使用CPack工具打包成为一个deb包
  • 构建deb包前如何获取软件的依赖包
  • 【全网独家】手把手教你制作一个Ubuntu Deb 安装包
  • 用CMake打包deb包流程完整版(带字段解析)

http://www.ppmy.cn/news/773101.html

相关文章

小米移动的坑 170号段的坑

1 qq不能绑定手机号 2 学信网不能用改手机号

墨水屏可视化超高频电子标签技术优势与应用解决方案

随着全球智能制造进度的推进以及物流智能化管理水平的升级&#xff0c;行业亟需一种既能实现RFID批量读取、又能替代纸质标签在循环作业、供应链管理以及实现动态条码标签显示的产品。在此种行业需求背景下&#xff0c;基于墨水屏显示技术的VT系列可视化超高频标签呼之而出。 …

10.2寸三色电子墨水屏桌牌_双面屏

GIBIT双面 10.2寸墨水屏电子桌牌&#xff0c;以“电子纸&#xff0b;物联网”为核心技术&#xff0c;使用电子墨水屏作为展示屏幕&#xff0c;超级节能技术&#xff0c;超强续航能力&#xff0c;无需充电&#xff0c;不受场地和网络限制&#xff0c;支持蓝牙通讯&#xff0c;离…

低成本 汉朔 墨水屏 msp430g2553主控 改造完整案例

低成本 汉朔 2.13寸墨水屏 msp430g2553主控 改造完整案例 无需额外开发版 首先是原料购买 我们需要用到串口烧录器&#xff0c;CH340G或者CP2102&#xff1b; 注意&#xff1a;如果购买的话尽量买有DTR,RTS引脚&#xff0c;有些烧录板他是没有引出这些管脚的&#xff0c;在后…

Mycat【什么是Mycat、Mycat与其他中间件区别、Mycat应用场景、核心概念详解、Mycat原理】(一)-全面详解(学习总结---从入门到深化)

目录 Mycat概述_什么是Mycat Mycat概述_Mycat与其他中间件区别 Mycat概述_Mycat应用场景 Mycat概念_核心概念详解 Mycat概述_Mycat原理 Mycat部署安装_MySQL主从复制概述 Mycat概述_什么是Mycat 什么是Mycat Mycat是数据库中间件&#xff0c;所谓中间件数据库中间件是连…

C语言void指针(void*)

Void指针&#xff08;void *&#xff09;是一种通用指针类型&#xff0c;可以用来存储任何类型的指针&#xff0c;但不能直接解引用。 在C语言中&#xff0c;void指针可以用来实现对类型不确定的数据的操作&#xff0c;或者用作函数的参数和返回类型&#xff0c;以便于处理不同…

vue props设置默认值的基本方式

vue官方文档解释&#xff1a;为该 prop 指定一个默认值。如果该 prop 没有被传入&#xff0c;则换做用这个值。对象或数组的默认值必须从一个工厂函数返回。 默认值为字符串 props:{fieldString:{type:String,default: } }默认值为数值 props:{fieldNumber:{type:Number,defaul…

颜色代码对照表

各颜色代码: 1 白色 #FFFFFF 2 红色 #FF0000 3 绿色 #00FF00 4 蓝色 #0000FF 5 牡丹红 #FF00FF 6 青色 #00FFFF 7 黄色 #FFFF00 8 黑色 #000000 9 海蓝 #70DB93 10 巧克力色 #5C3317 11 蓝紫色 #9F…