请教各位 C++的老哥,发布程序的时候,需要打成 rpm、deb 包吗?

2022-05-03 17:39:05 +08:00
 liuguangxuan

自己平时在工作中,发布或者更新 C++程序时,直接发布一个文件夹,里面包含了可执行程序和相关的依赖库。用户下载下来,替换更新。

请问各位老哥:

  1. 你们发布程序的时候会打包成 rpm 、deb 格式的包吗?如果打包的话用的是什么工具?如何检测 CentOS 、Ubuntu 等不同平台的?
  2. 打包发布程序的时候,如何和 systemd 配合,使用 systemctl 来管理?
  3. 行业里面,比较规范的做法是什么?
4384 次点击
所在节点    C++
28 条回复
adoal
2022-05-04 23:50:22 +08:00
@liuguangxuan Linux 的软件安装是个很复杂的生态。可以不管发行版,自己从上游软件的源代码开始编译安装,也可以不用管 File System Hierachy 规定的什么文件放在什么目录……实际上大部分上游软件编译之前的 configure 或类似阶段的默认值就是不遵循 FSH 的。但有发行版在,对于普通用户节省了挑选上游软件具体版本测试其搭配的兼容性的精力。

同时,发行版会在自己编译开源软件时做一些风格上的适配,比如约定不同类别的文件放在什么路径、后台服务程序用什么机制启动、配置文件如何细分到各种**.d 里以便把插件的配置和主配置分开方便自动修改、日志文件如何定时切分,等等。

rpm 和 deb 是两大主流发行版 RH 系和 Debian 系的“御用”格式,发行版本身包含的组件(比如 Debian 当前版本里有 8 万多个软件)是用这两种格式来打包的。通常比起上游来经过了一系列统一风格的改造。理论上是可以跨越发行版混装的,但实际上有很多问题,有些能装成功有些则不行。所以正常的做法是,写好 spec/rules 然后针对用到的特定目标发行版和目标版本来做自动打包,当然 spec/rules 是有兼容性问题的,也要好好适配同一发行版的不同版本。你厂 IT 基建环境基本为 0 的话而你又要兼作基建的话,那强烈建议现阶段尽量减少发行版 /版本的数量。比如都统一到 Debian 或者 CentOS 的一两个版本上。暂时统一不上去的,以后逐步改版替换。操作系统版本迭代导致的屎山,等以后再去想办法治理,现阶段既然是 0 ,还是尽量简化。

还有很多开源软件(有的闭源软件也是),是发行版不会包含或者还没收录的,上游作者有时候也会打包成 rpm 或者 deb ,让用户能以使用发行版的相同操作风格来管理。甚至有些体积很大的,比如 GitLab ,比如 Elastic Search 。

但是打包 rpm 或 deb 往往是个吃力不讨好的事,因为很多人(尤其是纯开发角色的)其实不太在乎运维方面的讲究,他们更喜欢一个 tar.gz 原地解压后的 everything-under-prefix 方式,认为这样更方便和自由,而 rpm 或 deb 里遵循 FHS 等规范的生产环境打包方式对开发来说太麻烦了,比如要考虑各种路径的权限、执行时的用户身份等,而且“散落”在不同的地方,开发过程中查找起来麻烦,等等。在企业里,基建团队打包 rpm/deb 是不产生直接的业务绩效的,开发团队对这些玩意的认可度也不高。所以往往会有企业根据自己踩过的各种坑自己搞得各种“最佳实践”。其实长线下来 rpm/deb 的学习成本未必高,但是起点高,要学一大堆不能马上产生绩效的“乱七八糟”的东西,而且很可能不讨大部分开发人员喜欢。所以大部分厂的业务型软件都不太用发行版包的方式来发布。

所以,虽然我自己(一个甲方的综合信息化人员)比较喜欢按发行版打包、按 FHS 布局的行为,但在这贴里还是建议你慎重考虑。因为精力投入会比较大,不产生业务绩效,而且不太容易被其他人接受。看看这贴里的很多回复就知道了。当然,如果你觉得值得,自己能 hold 住,说不定会成为业界尤其是国内业界与众不同的一股清流( or 泥石流)。


另外,还有值得一提的是,发行版的打包方式,其实是很传统的了。在云原生时代,很多软件对于外部依赖组件所采取的 vendoring 策略跟发行版打包是矛盾的。Debian packaging team 曾经尝试把 K8S 给 deb 化,但 K8S 特定版本和 Debian 特定版本的第三方依赖锁定版本冲突,始终没办法很好解决,最后终于放弃。LWN 上还曾经专门有一篇讨论。最后的结论是,三观不同没法强融。
adoal
2022-05-04 23:55:06 +08:00
@liuguangxuan 不清楚用 cmake 如何自动识别发行版再打包……但正常的做法是,当软件出新版之后,用批处理流程为支持的每个发行版+版本组合自动起相应的 docker ,在 docker 里面打包。可以参考有个开源 API 网关叫 APISIX 的 build 系统 apisix-build-tools ,使用时可以通过参数指定包格式、发行版、版本号,只要自己写一个脚本来批量多次调用打包工具就行了。
adoal
2022-05-05 00:02:49 +08:00
就是说,你改好软件功能,测试通过了,要打包了,假设你公司的生产和开发环境使用以下发行版+版本,那……
拉起一个 centos 8 (或者 alma 8 、rocky 8 、龙蜥 8 )的 docker ,在里面打出 -el8 的 rpm 包;
拉起一个 centos 7 的 docker ,在里面打出 -el7 的 rpm 包;
拉起一个 debian 11 的 docker ,在里面打出 -bullseys 的 deb 包;
拉起一个 ubuntu 20.04 的 docker ,在里面打出 -focal 的 deb 包。
把这 4 次拉起 docker 写成一个批处理脚本自动跑完就好。
adoal
2022-05-05 00:08:25 +08:00
建议你说服领导,把公司的操作系统环境统一,至少生产环境要统一,开发环境谁不愿意跟着走的要自己负责由此导致的兼容性问题。
liuguangxuan
2022-05-05 10:42:25 +08:00
@adoal #24 感谢老哥回复,有理有据。现在已逐步放弃了打包的想法了。😂
Chipmunker
2022-05-05 13:01:30 +08:00
@liuguangxuan 如果你是做为软件发布者发布包,那么你需要对不同平台进行打包,这个你可以在不同的 docker 镜像里做,写一个脚本判断系统平台,然后给 cmake 传入不同参数即可。判断的方式应该就是你说的那个办法吧。我在 stackoverflow 找的一个类似的: https://stackoverflow.com/a/62960931/8097964

如果你是指分发给用户之后再打包,那么完全没必要啊,cmake 不是有 install 操作麽?没必要打包啊!
byaiu
2022-05-06 17:04:31 +08:00
xmake+xrepo 可能是一个可选项

如果我自己有 c++的项目,可能会考虑用这个来做构建工具+发布。
j16ZgMV9cs6ZB23n
2022-05-10 11:21:17 +08:00
不复杂,如果考虑一般用户(比如老版本的 debian 或者 archlinux 之类的)可以考虑用定制的 alphine linux 编译打包成通用的 tar.gz 。可以参考 chromium 打包。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://ex.noerr.eu.org/t/850661

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX