一文读懂Ubuntu18.04下deb包发布

deb包介绍

  • DEB是Debian软件包格式的文件扩展名,跟Debian的命名一样,DEB也是因Debra Murdock而得名,她是Debian创始人Ian Murdock的太太.

  • Debian包是Unixar的标准归档,将包文件信息以及包内容,经过gzip和tar打包而成。处理这些包的经典程序是dpkg,经常是通过Debian的apt-get来运作。通过Alien工具,可以将deb包转换成rpm、tar.gz格式。deb包在Linux操作系统中类似于windows中的软件包(msi),几乎不需要什么复杂的编译即可通过鼠标点击安装使用。此外,deb广泛应用于越狱后iOS软件及MeeGo(含Maemo软件)中.

  • deb 格式是 Debian 系统(包含 Debian 和 Ubuntu )专属安装包格式,配合 APT 软件管理系统,成为了当前在 Linux 下非常流行的一种安装包。进入 2.x 时代之后有 Cydia 作者 Jay Freeman(saurik) 移植到 iPhone 平台上,一起的还有 APT 软件管理系统.

安装所需依赖

sudo apt-get install build-essential debhelper make autoconf automake dpkg-dev fakeroot pbuilder gnupg

deb包的文件结构

  • deb软件包里面的结构(打包前):它具有DEBIAN和软件具体安装目录(如etc, usr, opt, tmp, boot等)

  • deb包(打包后)本身由三个部分组成

组成详细
数据包(data.tar.gz) 包含实际安装的程序数据,文件名为“data.tar.XXX”
安装信息及控制包(control.tar.gz) 包含deb的安装说明,标识,脚本等,文件名为“control.tar.xz”
二进制数据 包含文件头等信息,需要特殊软件才能查看
|----DEBIAN
|-------control
|-------postinst(postinstallation)
|-------postrm(postremove)
|-------preinst(preinstallation)
|-------prerm(preremove)
|-------copyright(版权)
|-------changlog(修订记录)
|-------conffiles
|----etc
|----usr
|----opt
|----tmp
|----boot
等等,根据需求自行定义(可参考系统文件)

control文件

  • control:这个文件主要描述软件包的名称(Package),版本(Version),Installed-Size(大小),Maintainer(打包人和联系方式)以及描述(Description)等,是deb包必须具备的描述性文件,以便于软件的安装管理和索引。

字段用途例子/其他
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 建议安装的其他软件包和库文件  
命名定义
  • inst是install(安装)的缩写

  • pre是表示XX之前的前缀

  • post是表示XX之后的前缀

  • rm是remove(移除)的缩写

  • 以下为脚本文件,没有.sh后缀,并且权限等级为775(chmod 775 脚本文件名)

preinst文件

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

postinst文件

  • 负责完成安装包时的配置工作。如新安装或升级的软件重启服务。软件安装完后,执行该Shell脚本,一般用来配置软件执行环境,以“#!/bin/bash”为首行。

例:postinst

#!/bin/bash
sudo cp /opt/pmtd/pd_conf/pdlib.conf /etc/ld.so.conf.d
sudo ldconfig

prerm 文件

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

postrm文件

  • 负责修改软件包链接或文件关联,或删除由它创建的文件。软件卸载后,执行该Shell脚本,一般作为清理收尾工作,以“#!/bin/bash”为首行

例:postrm

#!/bin/bash
sudo rm -rf /etc/ld.so.conf.d/pdlib.conf
sudo ldconfig

changlog文件

  • changelog提供版本修改信息,帮助下载软件包的人了解软件包中是否有他们需要知道的信息,决定着生成的deb包的版本号。格式如下:

package (version) distribution(s); urgency=urgency
[optional blank line(s), stripped]
* change details
more change details
[blank line(s), included in output of dpkg-parsechangelog]
* even more change details
[optional blank line(s), stripped]
-- maintainer name [two spaces] date

dpkg(打包工具)详解

  • “dpkg ”是“Debian Packager ”的简写。为 “Debian” 专门开发的套件管理系统,方便软件的安装、更新及移除。所有源自“Debian”的“Linux ”发行版都使用 “dpkg”,例如 “Ubuntu”、“Knoppix ”等。

  • dpkg是Debian软件包管理器的基础,它被伊恩·默多克创建于1993年。dpkg与RPM十分相似,同样被用于安装、卸载和供给.deb软件包相关的信息。

  • dpkg本身是一个底层的工具。上层的工具,如APT,被用于从远程获取软件包以及处理复杂的软件包关系。 “dpkg”是“Debian Package”的简写。

dpkg命令参数介绍

打包为deb包

sudo dpkg -b   mydeb   mydeb-1.0.0_amd64.deb     
# 第一个参数为将要打包的目录名, # 第二个参数为生成包的名称。
#包名:mydeb,版本号:1.0.0,软件支持的平台架构:amd64

安装deb包

sudo dpkg -i  mydeb-1.0.0_amd64.deb  
deb包安装完后,自动执行postinst脚本

卸载deb包

sudo dpkg -r   mydeb
deb包卸载完成后,自动执行postrm脚本

其他deb操作

查看deb包是否安装:
# sudo dpkg -s mydeb
# 这里要卸载的包名为control文件Package字段所定义的 my-deb

查看deb包文件内容:
#sudo dpkg -c mydeb-1.0.0_amd64.deb

查看当前目录某个deb包的信息:
# sudo dpkg --info mydeb-1.0.0_amd64.deb

解压deb包中所要安装的文件
#sudo dpkg -x mydeb-1.0.0_amd64.deb mydeb-1
# 第一个参数为所要解压的deb包,这里为 mydeb-1.0.0_amd64.deb # 第二个参数为将deb包解压到指定的目录,这里为 mydeb-1

解压deb包中DEBIAN目录下的文件(至少包含control文件)
# sudo dpkg -e mydeb-1.0.0_amd64.deb mydeb-1.0.0/DEBIAN
# 第一个参数为所要解压的deb包,# 这里为 mydeb-1.0.0_amd64.deb # 第二个参数为将deb包解压到指定的目录, # 这里为 mydeb-1.0.0/DEBIAN

制作deb文件系统流程

准备好可执行的二进制文件,这个二进制文件要可执行,提前要考虑兼容性,如果程序有目录要完整的一个程序目录。

新建软件文件夹 PerceptionModule

新建一个名为DEBIAN文件夹 此文件夹内存放控制信息

在DEBIAN里新建一个文本文档, 名为control, 编码为utf-8, 内容如下所示:

Package: PerceptionModule
Version: 1.0.1
Architecture: amd64
Section: utils
Priority: optional
Maintainer:xxxx
Homepage: http://xxxxxxx.org.cn
Description: Gale debug

然后我们创建对应的二进制包安装完成后的路径信息放置在DEBIAN的同级目录下,也就是把当前的目录当成根(“/”)目录,制作完成后安装时,当前目录下除了DEBIAN目录的其他目录都会被默认安装到系统的“/”目录下。

deb文件目录结构

以下是完整的deb包目录结构,仅供参考,可根据自己的需求进行设计。

├── PerceptionModule
│   ├── DEBIAN
│   │   ├── control
│   │   ├── postinst
│   │   └── postrm
│   ├── opt
│   │   └── pmtd
│   │   ├── config
│   │   │   ├── connection.ini
│   │   │   └── driver_config.yaml
│   │   ├── logs
│   │   │   ├── bag_information.log
│   │   │   ├── image_information.log
│   │   │   └── pmtd_udp_driver.log
│   │   ├── pd_bin
│   │   │   ├── desktop
│   │   │   │   ├── PerceptionModule.desktop
│   │   │   │   └── pmtd.png
│   │   │   ├── pack.sh
│   │   │   ├── pdlib
│   │   │   │   ├── 依赖库
│   │   │   ├── pmtd_ui_base
│   │   │   └── pmtd_ui_base.sh
│   │   └── pd_conf
│   │   └── pdlib.conf
│   └── usr
│   └── share
│   ├── applications
│   │   └── PerceptionModule.desktop
│   └── icons
│   └── pmtd.png

步骤流程

1.构建文件

新建文件PerceptionModule,以及下级目录DEBIAN、opt、usr等,根据需求自行构建
可参考上诉文件结构,由于本实例程序依赖自身库、配置文件、日志等,构建了相应的config 、logs、pdlib目录。

2.依赖库构建

编写pack.sh脚本(PerceptionModule/opt/pd_bin/pack.sh),并且将可执行文件移动至该目录下,为该脚本赋予权限并运行,运行pack.sh脚本之后,可执行文件依赖的动态库会全部复制到目录/PerceptionModule/opt/pmtd/pd_bin/pdlib下。

例:pack.sh

#!/bin/sh  
exe="pmtd_ui_base"
des="/home/tsj/PmtdSetup/PerceptionModule/opt/pmtd/pd_bin/pdlib"
deplist=$(ldd $exe | awk '{if (match($3,"/")){ printf("%s "),$3 } }')
cp $deplist $des

脚本内容可按照需要自行修改。

3.创建文件及脚本

  • control

Package: PerceptionModule
Version: 1.0.1
Architecture: amd64
Section: utils
Priority: optional
Maintainer: Fiee
Description: Gale debug
  • postinst

#!/bin/bash
sudo cp /opt/pmtd/pd_conf/pdlib.conf /etc/ld.so.conf.d
sudo ldconfig
  • postrm

#!/bin/bash
sudo rm -rf /etc/ld.so.conf.d/pdlib.conf
sudo ldconfig

4.日志和配置文件

本次实例程序依赖于配置文件以及输出日志,创建相应的config和logs夹进行存放,可根据需求进行选择,可以注意到config和logs的目录如下:

│   ├── opt
│   │   └── pmtd
│   │   ├── config
│   │   │   ├── connection.ini
│   │   │   └── driver_config.yaml
│   │   ├── logs
│   │   │   ├── bag_information.log
│   │   │   ├── image_information.log
│   │   │   └── pmtd_udp_driver.log

在安装deb包后,会将上述相应的文件也移动至系统的/opt目录下,可以根据绝对路径去操作配置文件和日志文件(本人总结的方式,根据相对路径调用时,需要根据可执行程序运行的路径改变而进行相应的改变),如果有更好的方式当然最好了。

5.图标发布

在PerceptionModule/usr目录下创建以下文件结构

└── share
├── applications
│   └── PerceptionModule.desktop
└── icons
└── pmtd.png

其中最为重要的文件为PerceptionModule.desktop,内容如下:

[Desktop Entry]
Name=Perception_Module
Comment=perception module tool
Exec=/opt/pmtd/pd_bin/pmtd_ui_base
Icon=/usr/share/icons/pmtd.png
Terminal=false
Type=Application
X-Ubuntu-Touch=true
Categories=Development

以上内容均可根据自身情况进行更改,其中Exec=/opt/pmtd/pd_bin/pmtd_ui_base为可执行程序名,也可为程序启动脚本,个人建议用可执行程序名(减少一步调用)

deb安装时会将PerceptionModule.desktop移动至系统的/usr/share/applications目录下,因此会在安装完后后显示图标,点击即可运行。

以上为整个deb包的文件结构和一些比较重要的文件,不局限于上述提到的文件和目录,可以参考teamviewer的deb包结构(本人参考的),以及其他软件包等等。

6.打包为deb包发布

sudo dpkg -b PerceptionModule/ PerceptionModule_1.0.0_amd64.deb

7.安装deb包

sudo dpkg -i PerceptionModule_1.0.0_amd64.deb

8.删除deb包

sudo dpkg -r PerceptionModule

其他操作deb包的命令可以查看上述dpke(打包工具)详解章节。

deb包动态库依赖

打包deb包和安装deb包的过程,只要细心基本不会出问题,最为关键的是deb包内可执行程序动态库的调用,是去默认路径调用系统的库还是指定路径调用自己ldd(可查询用法)依赖的动态库。

动态库的搜索

  • 在配置文件/etc/ld.so.conf中指定动态库搜索路径(需要添加其它库文件的路径,在文件的最后添加具体的路径即可 [ 如:/usr/local/lib ],添加后保存退出,然后在命令行ldconfig

  • 通过环境变量LD_LIBRARY_PATH指定动态库搜索路径(当通过该环境变量指定多个动态库搜索路径时,路径之间用冒号":"分隔)

  • 在编译目标代码时指定该程序的动态库搜索路径(还可以在编译目标代码时指定程序的动态库搜索路径。 这是通过gcc 的参数"-Wl,-rpath,"指定,当指定多个动态库搜索路径时,路径之间用冒号":"分隔)

  • 默认的动态库搜索路径/lib

  • 默认的动态库搜索路径/usr/lib

搜索的先后顺序是:
  • 编译目标代码时指定的动态库搜索路径;

  • 环境变量LD_LIBRARY_PATH指定的动态库搜索路径;

  • 配置文件/etc/ld.so.conf中指定的动态库搜索路径;

  • 默认的动态库搜索路径/lib;

  • 默认的动态库搜索路径/usr/lib。

动态依赖库路径设置

  • 在配置文件/etc/ld.so.conf中指定动态库搜索路径,具体操作:需要添加其它库文件的路径,在文件的最后添加具体的路径即可 [ 如:/usr/local/lib ],添加后保存退出,然后在命令行ldconfig。

sudo echo "/usr/local/lib" >> /etc/ld.so.conf
sudo ldconfig
  • 其他相似的方法:在/etc/ld.so.conf.d目录下编写一个自己的xxx.conf,xxx.conf编写自己库依赖的路径,添加后保存退出,然后在命令行ldconfig,原理一样,只是将其分离到一个独立的xxx.conf中,不需要是,可直接删除,个人更推荐该方式。

总结

  • 需要关注deb包的文件结构,并且理解安装deb包后,打包的文件去处。

  • DEBIAN相应的脚本编写,可以很好的安装deb包后完成相应运行环境的配置以及卸载包后环境的清理。

  • dpkg打包过程中,文件名编写格式和文件权限的设置(需注意)

  • deb包动态依赖库调用的路径设置,是调用默认路径调用系统的动态库还是调用自己deb包中打包好的动态依赖库很关键,不然容易找不到需要依赖的库。

参考链接

 

 

posted @ 2022-09-02 13:12  joren  阅读(7)  评论(0)    收藏  举报