![448a801c350594ef06a21ca474b1c080.png](https://i-blog.csdnimg.cn/blog_migrate/bedaa311baa7252e829620221aa0435f.jpeg)
# 文件结构
data # 待打包的文件夹
├── DEBIAN # 这里放着各种安装包的描述、配置文件,还有安装前后执行的脚本等
│ ├── control
│ ├── copyright
│ └── postinst
├── opt # 安装目录下的相对内容
├── etc # 安装目录下的相对内容
└── usr # 安装目录下的相对内容
# 打包
在data的上一级目录执行
dpkg-deb -Z xz -z 9 --build ./data test.deb
这个命令会在当前目录生成一个 test.deb 就是打包好的安装包
# 多线程打包
在上述命令上多添加一个参数:`--compress-program=pixz`
dpkg-deb --compress-program=pixz -Z xz -z 9 --build ./data test.deb
- pixz是一个多线程xz压缩工具, 需要提前安装`sudo apt-get install pixz`
# dpkg-deb
当然,默认的dpkg-deb是没有上面那个参数的,这个dpkg-deb是我修改源码后重新编译的版本。如果你也有多线程打包的需求,可以使用这样两个方案:
- 下载使用我的dpkg-deb:https://download.csdn.net/download/Three_dog/12027997
- 下载dpkg源码,修改代码内容。编译生成dpkg-deb使用。
方案二中,如何下载编译dpkg请参见:
https://blog.csdn.net/Three_dog/article/details/103418141blog.csdn.net下载后修改的内容不多,我懒得一个一个文件改动写那么详细了,这里直接贴个diff,有需要的小伙伴对照着看下应该知道该改哪里。
diff --git a/dpkg-deb/build.c b/dpkg-deb/build.c
# 实现原理
打包dpkg-deb的时候,压缩过程它使用的是内置的算法,这个算法是单线程的,无法发挥多核CPU的优势。
而这个改动,给dpkg-deb加了一个参数。这个参数可以指定一个应用程序,在打包进行到压缩步骤的时候,调用这个指定的程序进行压缩。当然,这个程序打包的类型,必须和`-Z `指定的类型一致。
我这里使用的是压缩率最高的xz格式,这里指定的外部程序叫做pixz, 这个程序默认会使用最大线程数进行全量压缩,通过这种办法曲线救国,实现了dpkg-deb的多线程打包。
一些多线程的压缩工具pigz/pbzip2/pxz/pixz等等都可以在这里使用以提高效率。
# 参考链接
这个方案当然也不是我拍脑袋想出来的,还是下载了一个外国人针对旧版本的diff,对着现在的代码改的,他原文也提到了这种方案最好打打平时的构建包和测试包,如果发布的话,最好还是老老实实用原版的dpkg-deb。
链接1:Any way to multithread dpkg-deb
链接2:Debian Bug report logs
有能力的小伙伴可以看看这俩链接,着实给我打开了新世界的大门。
另外,网上说的什么`fpm` `debuild` `dpkg-buildpackage` 说这个支持多线程打包, 然而这些全都是对dpkg-deb和rpm的封装,最后还是调用这些工具实现。多线程仅仅在编译阶段是多线程,对于打包可以说卵用没有。
# rpm
deb的这个方案大概折腾了一礼拜。而rpm的方案,折腾了两个礼拜结论是不可行。。。。
rpm的代码耦合性比较大,没有办法指定第三方的压缩工具压缩,底层依赖的cpio的算法进行压缩,外部工具插不上手。
虽然官方在后续版本,也说实现了多线程打包的功能:
https://github.com/rpm-software-management/rpm/issues/211
在4.14版本之后的代码里应该就已经带上了,ubuntu源里默认安装的是4.12版本。我下载了最新的源码编译安装后仍然不可行。
最终在github上也得到了rpm项目维护者的确认,这个暂时。。。无法实现。
how to use the multi-threaded mode for packaging rpm? · Issue #970 · rpm-software-management/rpm
更新一下rpm的解决方案,当时得出无法实现的结论后,同事的大佬找到了另一个issuse,让我看看这个人说的方法能搞不:Does not the rpmbuild command execute (de)compression of files in parallel? · Issue #113 · rpm-software-management/rpm
![f6ab61b50fecad0aa0263452bab294d3.png](https://i-blog.csdnimg.cn/blog_migrate/c1f65385637766389c558626eef12496.jpeg)
我看了一下,还真能搞。大概意思就是,如果你的本机xz版本是5.2以上的话,可以在执行rpmbuild命令时指定`binary_payload`为`w9T12.xzdio`这样的方式,这样它就会使用新版xz的多线程压缩进行打包。
所以首先:编译安装新版xz,ubuntu16.04自带的是5.1版本的。
cd xz-5.2.4
./autogen.sh
./configure
make
sudo make install
报错我没记录,大家遇到啥自行解决一下,都不复杂。
但是替换了xz之后并没有生效,还需要把rpm重新编译一下。编译的时候,必须指定链接新的`liblzma.so`的库,这样打包出来的rpm才能多线程压缩。修改rpm源码里的`autogen.sh`成这样:
#!/bin/sh
编译安装后,现在的`rpmbuild`就支持多线程压缩了。编译命令要记得指定`w9T12.xzdio`,w后面是压缩等级,0到9,9最高,T后面是最大线程数,最好和CPU线程数一致,xz是压缩类型,这里必须是xz,`lzdio`也就是lzma还是只能单线程。
我在实践过程中仍然有小问题:
在我使用w9T12的时候,CPU最高占用只有600%,也就是用了6个线程。可我的CPU最高支持12个。
一开始我以为是它获取CPU核数错了,但是后来发现不是。当我使用w6T12的时候,CPU占用可以达到1200%,w7T12最高1000%,w8T12最高800% 。
经过调查发现这个限制是因为xz,在xz多线程压缩的时候,会预先给文件进行分块,分成几部分,每一部分一个线程,而压缩等级为9的时候,我的原文件只被分成了6个部分,因此最多只有6个线程同时工作。
xz的文件分块,和源文件的大小以及压缩等级有关,最终在我的环境下只分成了6各部分。尝试分析了xz代码的这部分逻辑,但是对我而言实在是有点复杂,看了一圈不觉明历,所以暂时也不会改这个地方。
最终虽然rpm的多线程打包方案不算是一个很完美的解决,但是至少会比以前快出来不少。