CMake之CPack

news2024/9/23 6:38:02

文章目录

  • 一、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 PrinterChar
        RUNTIME 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 demo
        RUNTIME 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]t
        libQt5Widgets.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 NEEDED
  NEEDED               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.coloradmin.cn/o/728433.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot 集成 EasyExcel 3.x 实现 Excel 导出

目录 EasyExcel官方文档 EasyExcel是什么&#xff1f; EasyExcel注解 springboot集成EasyExcel 简单入门导出 &#xff1a; 实体类 自定义转换类 测试一下 复杂表头一对多导出 &#xff1a; 自定义注解 定义实体类 自定义单元格合并策略 测试一下 EasyExcel官方文档 …

The Sandbox 展示泰国 2023 年元宇宙生态系统

The Sandbox 举办了 2023 年泰国合作伙伴日活动&#xff0c;宣布创建泰国元宇宙生态系统&#xff0c;并对泰国创客社区的巨大合作和发展表示认可。 The Sandbox 联合创始人兼首席运营官 Sebastien BORGET 说&#xff1a;“我们很高兴见证 The Sandbox 泰国生态系统的发展&#…

第七章 网络安全【计算机网络】

第七章 网络安全【计算机网络】 前言推荐第7章 网络安全7.1网络安全问题概述7.1.1计算机网络面临的安全性威胁7.1.2安全的计算机网络7.1.3数据加密模型 7.2两类密码体制7.2.1对称密钥密码体制7.2.2公钥密码体制 7.3鉴别7.3.1报文鉴别7.3.2实体鉴别 7.4密钥分配7.4.1 对称密钥的…

银行软开能干到退休吗?

大家好&#xff0c;我是熊哥。 21世纪了好像不躺平对不起自己&#xff1f;很多读者都关心哪些企业适合躺平&#xff0c;做程序员是不是在银行可以舒舒服服干一辈子&#xff1f;银行招软开&#xff08;软件开发&#xff09;有哪些要求&#xff1f; 现在就来详细讲一讲。 擦亮…

数据结构--二叉树的线索化

数据结构–二叉树的线索化 用土办法找到中序前驱 typedef struct BiTNode {ElemType data; //数据域struct BiTNode *lchild, *rchild; //左、右孩子指针struct BiTnode *parent; //父节点指针 }BiTNode, *BiTree;BiTNode *p; // p指向目标结点 BiTNode *pre NULL; //指向当前…

用Postman和jmeter做接口测试有什么区别吗?

目录 1.创建接口用例集&#xff08;没区别&#xff09; 2.步骤的实现&#xff08;有区别&#xff09; 3数据用例的实现 4断言的实现 5执行 6其他 总结&#xff1a; 1.创建接口用例集&#xff08;没区别&#xff09; Postman是Collections&#xff0c;Jmeter是线程组&am…

web安全php基础_php之string对象详解

PHP 字符串 字符串变量用于包含有字符的值。 在创建字符串之后&#xff0c;我们就可以对它进行操作了。您可以直接在函数中使用字符串&#xff0c;或者把它存储在变量中。 在下面的实例中&#xff0c;我们创建一个名为 txt 的字符串变量&#xff0c;并赋值为 “Hello world!…

MySQL数据库:数据库管理系统与安装MySQL数据库

目录 一、理论 1.数据库管理系统 2.关系型数据库 3.数据库 4.MySQL数据库 5.MySQL部署 二、实验 1.yum安装MySQL 2.配置MySQL数据库的Tab补全 三、问题 1.数据库登录报错 2.数据库密码复杂度报错 四、总结 一、理论 1.数据库管理系统 &#xff08;1&#xff09…

深入浅出fromCharCode和charCodeAt

先来看一个简单的输入输出 console.log(String.fromCharCode(30328)); //癸console.log(癸.charCodeAt()) //30328来回答一个问题&#xff0c;30328是什么&#xff1f; ascii? unicode? utf-8? utf-16? 来让我们看看fromCharCode 在MDN上面的解释 UTF-16代码单元序列…

【数据分析 - 基础入门之NumPy③】日常难题解决

知识目录 前言一、启动Jupyter Notebook报错没有这样的目录结语# 往期文章&相关导读 前言 本篇文章用于整理在学习 NumPy 过程中遇到的错误&#xff0c;以此做个记录&#xff0c;希望能帮助到大家&#xff0c;让大家少走弯路。 一、启动Jupyter Notebook报错没有这样的目…

改动最小,最简洁的 tomcat catalina.out日志切割(按天)

tomcat日志切割 环境:实现步骤具体操作 环境: 系统: linux操作系统 centOStomcat 8.5* 实现步骤 安装cronolog工具修改tomcat中的bin目录下的 catalina.sh 文件配置重启tomcat 具体操作 安装cronolog 工具输入命令: yum install cronolog 中间 停顿 填个 y 同意修改配置…

什么是cookies,session,token(面试必问)

目录 前言 http无状态 cookies cookie的格式显示 cookie存在问题 利用cookies可以做什么 session session的格式显示 session存在的问题 利用session可以做什么 token token的格式显示 token存在的问题 利用token可以做什么 总结 前言 一般在面试的时候&#xf…

内网隧道代理技术(九)之应用层代理技术介绍

应用层代理技术介绍 前面我们介绍了相关的一些概念和隧道的技术,主要还是停留在单个端口的隧道 1、反弹shell2、端口转发3、端口映射这些都是利用端口建立隧道,但是并不能满足我们日常生活中的要求 加入我们需要对网络中的机器进行扫描,我们就不能使用端口转发或者端口映射…

【计算机视觉 | 目标检测 | 图像分割】arxiv 计算机视觉关于目标检测和图像分割的学术速递(7 月 7 日论文合集)

文章目录 一、检测相关(5篇)1.1 Contextual Affinity Distillation for Image Anomaly Detection1.2 Noise-to-Norm Reconstruction for Industrial Anomaly Detection and Localization1.3 MMNet: Multi-Collaboration and Multi-Supervision Network for Sequential Deepfake…

postman接口测试之postman常用的快捷键

作为一名IT程序猿&#xff0c;不懂一些工具的快捷方式&#xff0c;应该会被鄙视的吧。收集了一些Postman的快捷方式&#xff0c;大家一起动手操作~ 简单操作 操作mac系统windows系统 打开新标签 ⌘TCtrl T关闭标签⌘WCtrl W强制关闭标签Cmd Alt WCtrl Alt W切换到下一个…

【JavaEE】前后端综合项目-博客系统(上)

【JavaEE】前后端综合项目-博客系统&#xff08;上&#xff09; 文章目录 【JavaEE】前后端综合项目-博客系统&#xff08;上&#xff09;1. 创建项目2. 数据库设计3. 数据库操作的封装3.1 DataSource&#xff08;单例&#xff09;3.1 连接操作3.2 关闭操作3.3 创建实体类3.4 封…

“AI无界·智链全球”!壹沓科技2023世界人工智能大会论坛成功举办,构建数智供应链新范式

“AI无界智链全球”论坛成功举办 构建数智供应链新范式 7月6日&#xff0c;由世界人工智能大会组委会办公室指导&#xff0c;壹沓科技主办&#xff0c;上海交通大学安泰经济与管理学院、上海现代服务业联合会物流与供应链专委会、中国航务周刊协办的“AI无界智链全球”高端论坛…

前端vue入门(纯代码)23_多组件共享

我不喜欢去银行&#xff0c;就好像太监不喜欢去妓院一样&#xff0c;有些东西你没有&#xff0c;去了也是难受。 【24.Vuex中的多组件状态共享】 页面展示&#xff1a; vuex数据共享完整代码&#xff1a; App.vue和main.js&#xff1a;就不展示了。 store/index.js //该文…

Verilog学习笔记1:D触发器

代码1&#xff1a; timescale 1ns/10psmodule d_trigger(d,clk,q);input d; input clk; output q;assign q~d;endmodule//testbench module d_trigger_tb; reg clk; reg d; wire q;d_trigger d_trigger(.d(d),.clk(clk),.q(q));initial begind<0;clk<0;#1000 $stop;end…

异步电路后端实现流程(cdc signOff 后端做什么)

目录 1.一种后端异步电路的signOff流程 2.cdc maxDelay的原因及relax 2.1为什么要做maxDelay检查 2.2 如果有不同名字的clk 原本是同步时钟域 该怎么办 2.3 如果有异步电路不能满足0.7倍的fastclk maxDelay检查该怎么办&#xff1f; 1.一种后端异步电路的signOff流程 同步…