用工具链打包 deb:debhelper、fpm 与 checkinstall
手动 dpkg-deb 需自己摆目录、写 control。当项目要从源码构建、长期维护或上传 PPA 时,改用工具链更省心:你只写声明式规则,工具负责编译、摆放、打包。本文对比三条主流路线。
1. 三者定位对比
| 工具 | 定位 | 适用场景 |
|---|---|---|
debhelper (dh_make/dpkg-buildpackage) |
Debian 官方标准工作流 | 从源码构建、上传 PPA/官方仓库、需遵循 Debian 政策 |
fpm |
跨格式打包器(deb/rpm/apk…) | 已有成品文件,一条命令出包,多发行版分发 |
checkinstall |
拦截 make install 自动成包 |
已能 make install 的老项目,快速留痕便于卸载 |
- 追求规范、可复现、可上游 →
debhelper - 追求「一条命令、多种格式」→
fpm - 只想让
make install装的东西能被dpkg管理 →checkinstall
2. debhelper 标准工作流
debhelper 通过 debian/ 目录下的声明文件描述包,dpkg-buildpackage 一键完成构建到打包。
1 | sudo apt install debhelper dh-make build-essential |
初始化后 debian/ 的关键文件:
| 文件 | 作用 |
|---|---|
control |
包元信息与依赖(同手动方式,但由工具校验) |
rules |
构建脚本,本质是 Makefile,通常仅需一行 dh $@ |
changelog |
版本历史,Version 从这里读取,用 dch 维护 |
install |
声明「哪个文件装到哪」,替代手动 mkdir/cp |
copyright |
许可证信息,上传官方仓库必需 |
debian/rules 最小形态:
1 | #!/usr/bin/make -f |
debian/install 用一份清单描述文件布局,不再手动建目录:
1 | src/myapp usr/bin |
dh $@会自动串起dh_auto_build(跑make)、dh_install、dh_installdeb等一系列步骤- 版本号由
debian/changelog顶部条目决定,用dch -i递增并记录变更 -us -uc跳过 GPG 签名(本地测试用),上传 PPA 时需去掉并配置签名--native表示源码与打包同仓;上游 tar 分离的项目去掉它
3. fpm 一条命令出包
fpm(Effing Package Management)把「现成文件」直接压成包,无需 debian/ 目录,且同一命令可切换输出格式。
1 | sudo apt install ruby ruby-dev build-essential |
源路径=目标路径语法直接声明文件映射,省去手动摆目录树- 把
-t deb换成-t rpm、-t apk即可产出其他格式,命令其余部分不变 --after-install/--before-remove对应维护者脚本postinst/prerm- 不做源码编译,只负责「打包已有产物」;编译仍需自己先完成
- 依赖 Ruby 环境,比 debhelper 重,但比手写
control灵活
4. checkinstall 拦截安装
checkinstall 监控 make install 实际写入了哪些文件,据此自动生成并安装一个 deb,让原本「散装安装」的软件可被 dpkg 卸载。
1 | sudo apt install checkinstall |
- 交互式询问包信息后,跟踪
make install的写入动作并打成 deb,同时完成安装 - 适合没有打包脚本、只提供
make install的传统源码项目 - 生成的
.deb留在当前目录,可复制到其他机器安装 - 记录可能不完整(如安装脚本用了非常规路径),仅适合快速留痕,不适合正式分发
5. 如何选择
1 | 从源码构建、要上游/PPA、追求规范 → debhelper |
- 团队长期维护的项目优先
debhelper,规范换来可复现与可上游 - 内部快速分发、跨发行版交付选
fpm,学习成本最低 checkinstall是「过渡方案」,能规范化时应尽早迁移到前两者
手动打包的基础流程见《在 Ubuntu 上手动打包 deb》;现代化方案(nfpm、cargo-deb、CPack、CI 驱动)见《deb 包现代化打包方案:nfpm、cargo-deb、CPack 与 CI 驱动》。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 iehtian!
