近期在通过源码编译安装一些软件包时,发现一些问题。
很多工具只在编译期需要,运行时不需要。 编译安装存在难以卸载干净的问题。 在生产环境中直接进行编译安装虽然可行,但是不方便进行维护,因此还是尽量少用。像容器化,比如docker镜像,就是只打包进去最终编译后的成果。而某些场景下,我们是不建议使用容器的。此时就需要通过rpm或者deb来解决该问题。
.rpm
全名为RedHat Package Manager
,适用于RedHat
系列系统(RHEL/RockyLinux/CentOS/Fedora/openSUSE 等)。
.deb
全名为Debian Package
,适用于Debian
系列系统(Debian/Ubuntu/Kali等)。
deb包跟rpm包其实解决的场景问题都是一样的,只是适用于不同系统而已。那么如何理解deb包和rpm包的场景?
以rpm包为例,即在特定环境中(如 CentOS 7/RHEL 7)将程序编译好,并打包成一个可安装的二进制包,方便其他相同系统直接安装使用。
不用在每台机器上重新编译,节省时间和资源 解决难以卸载干净问题,并支持安装、升级、回滚、查询、卸载等 它可以包含如下内容
rpm包的名称遵循以下格式
1 <name>-<version>-<release>.<arch>.rpm
一、rpm 本章节所有示例步骤,均是基于RockyLinux9.5 完成。
1 Linux rocky-vm 5.14.0-503.14.1.el9_5.aarch64
本章节参考文章
1.1 rpm命令基础 下面简单记录常见的rpm命令使用方式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 rpm -ivh rpmbuild/RPMS/noarch/hello-0.0.1-1.el9.noarch.rpm rpm -Uvh rpmbuild/RPMS/noarch/hello-0.0.1-1.el9.noarch.rpm rpm -qi hello rpm -ql hello rpm -qf /usr/local /bin/hello rpm -ev hello rpm -qa rpm -qa --last rpm -qR hello
1.2 编译入门 准备一个完全初始化的RedHat
系统,执行如下命令,安装rpm构建工具
1 yum -y install rpm-build rpmlint rpmdevtools
初始化rpm构建目录
目录结构说明
1 2 3 4 5 6 7 [root@rocky-vm ~] /root/rpmbuild ├── BUILD:存放解压后的源代码包,是实际编译发生的地方。 ├── RPMS:包含为不同架构构建的 RPM 包 ├── SOURCES:存放原始源代码压缩包和相关的补丁文件。通常为.tar.gz或者.tgz文件 ├── SPECS:存放 .spec 文件,即 RPM 构建规范文件。 └── SRPMS:存放构建完成的源码 RPM 包(Source RPM)。
创建脚本,并将其压缩为.tgz
1 2 3 4 5 6 7 8 9 cat>hello<< EOF #!/usr/bin/env bash echo "Hello world" EOF chmod +x hello mkdir hello-0.0.1 mv hello.sh hello-0.0.1 tar -zcvf hello-0.0.1.tar.gz hello-0.0.1 mv hello-0.0.1.tar.gz rpmbuild/SOURCES
创建.spec
文件
此处直接放置hello.spec
源码,并将其放置在rpmbuild/SPECS
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 Name: hello Version: 0.0.1 Release: 1%{?dist} Summary: A simple hello world script BuildArch: noarch License: GPL Source0: %{name}-%{version}.tar.gz Requires: bash %description A demo RPM build %prep %setup -q %install rm -rf $RPM_BUILD_ROOT mkdir -p $RPM_BUILD_ROOT /%{_bindir} cp %{name} $RPM_BUILD_ROOT /%{_bindir} %clean rm -rf $RPM_BUILD_ROOT %files %{_bindir}/%{name} %changelog * Wed May 14 2025 Valentin Bajrami <valentin.bajrami@slimmer.ai> - 0.0.1 - First version being packaged
像%{_bindir}
是rpm中定义的变量名,变量值为/usr/bin
。可以通过如下命令查看变量值。
常见变量名如下
变量名 变量值 %{_bindir} /usr/bin %{_datadir} /usr/share %{_sysconfdir} /etc
编译相关的命令如下
1 2 3 4 5 6 7 8 9 10 11 rpmlint rpmbuild/SPECS/hello.spec rpmbuild -bs rpmbuild/SPECS/hello.spec rpmbuild -bb rpmbuild/SPECS/hello.spec rpmbuild -ba rpmbuild/SPECS/hello.spec
构建完成后的目录结构如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 [root@rocky-vm ~] rpmbuild ├── BUILD │ └── hello-0.0.1 │ └── hello.sh ├── BUILDROOT ├── RPMS │ └── noarch │ └── hello-0.0.1-1.el9.noarch.rpm ├── SOURCES │ └── hello-0.0.1.tar.gz ├── SPECS │ └── hello.spec └── SRPMS └── hello-0.0.1-1.el9.src.rpm 8 directories, 5 files
1.3 实践-编译 meethigher/rpm-build-examples: 基于rocky9.5构建rpm的脚本示例
1.3.1 编译postgresql12.9 rpm目录结构如下
1 2 3 4 5 6 7 8 9 10 11 [root@rocky-vm ~] rpmbuild/ ├── BUILD ├── RPMS ├── SOURCES │ └── postgresql-12.9.tar.gz ├── SPECS │ └── postgresql.spec └── SRPMS 5 directories, 2 files
postgresql.spec
内容
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 Name: postgresql Version: 12.9 Release: 1%{?dist} Summary: PostgreSQL 12.9 database server (custom compiled) License: PostgreSQL URL: https://www.postgresql.org/ Source0: postgresql-12.9.tar.gz BuildRequires: gcc,readline,readline-devel,zlib,zlib-devel %description PostgreSQL is a powerful, open source object-relational database system. %prep %setup -q -n postgresql-12.9 %build ./configure --prefix=/usr/local /postgresql make -j$(nproc) %install rm -rf $RPM_BUILD_ROOT make install DESTDIR=%{buildroot} %files /usr/local /postgresql %changelog * Thu May 15 2025 YourName <you@example.com> - 12.9-1 - Custom built PostgreSQL 12.9
首先,需要先将BuildRequires
里面要求的内容,进行安装
1 yum -y install gcc readline readline-devel zlib zlib-devel
验证并编译二进制rpm
1 2 3 4 rpmlint rpmbuild/SPECS/postgresql.spec rpmbuild -bb --nodebuginfo rpmbuild/SPECS/postgresql.spec
如果不带--nodebuginfo
,编译时会出现error: Empty %files file /root/rpmbuild/BUILD/postgresql-12.9/debugsourcefiles.lis
参考error: Empty %files file /xxxx/rpmbuild/BUILD/xxxx/debugsourcefiles.list-CSDN博客
这个过程,只将编译成果输出成rpm。后续还需要自己在rpm安装后,创建用户和配置,具体细节可以参照PostgreSQL在线安装与编译安装 - 言成言成啊
不过rpm的.spec
文件也支持在安装(或卸载)时执行自定义脚本操作,包括:
安装前执行(%pre
) 安装后执行(%post
) 卸载前执行(%preun
) 卸载后执行(%postun
) 此处不展开记录了。
1.3.2 编译geos3.9.4 geos.spec
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 Name: geos Version: 3.9.4 Release: 1%{?dist} Summary: geos-3.9.4.tar.gz (custom compiled) License: GPL-2.0 URL: http://example.com Source0: geos-3.9.4.tar.gz BuildRequires: gcc,gcc-c++ %description PostGIS extends the capabilities of the PostgreSQL relational database by adding support for storing, indexing, and querying geospatial data. %prep %setup -q -n geos-3.9.4 %build ./configure %install rm -rf $RPM_BUILD_ROOT make install DESTDIR=%{buildroot} %files /usr/local %changelog * Fri May 16 2025 root - Custom built from geos-3.9.4.tar.gz
银河麒麟v10在编译时遇到ERROR 0002: file 'xxx.so' contains an invalid rpath '/usr/local/lib' in [/usr/local/lib]
,解决方法有两种,任选其一。
1.3.3 编译proj6.3.2 proj.spec
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 Name: proj Version: 6.3.2 Release: 1%{?dist} Summary: proj-6.3.2.tar.gz (custom compiled) License: GPL-2.0 URL: http://example.com Source0: proj-6.3.2.tar.gz BuildRequires: gcc,gcc-c++,sqlite,sqlite-devel %description PostGIS extends the capabilities of the PostgreSQL relational database by adding support for storing, indexing, and querying geospatial data. %prep %setup -q -n proj-6.3.2 %build ./configure %install rm -rf $RPM_BUILD_ROOT make install DESTDIR=%{buildroot} %files /usr/local %changelog * Fri May 16 2025 root - Custom built from proj-6.3.2.tar.gz
1.3.4 编译protobuf3.15.8 protobuf.spec
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 Name: protobuf Version: 3.15.8 Release: 1%{?dist} Summary: protobuf (custom compiled) License: GPL-2.0 URL: http://example.com Source0: protobuf-3.15.8.tar.gz BuildRequires: gcc,gcc-c++ %description PostGIS extends the capabilities of the PostgreSQL relational database by adding support for storing, indexing, and querying geospatial data. %prep %setup -q -n protobuf-3.15.8 %build ./configure %install rm -rf $RPM_BUILD_ROOT make install DESTDIR=%{buildroot} %files /usr/local %changelog * Fri May 16 2025 root - Custom built protobuf-3.15.8
1.3.5 编译protobuf-c1.4.1 protobuf-c.spec
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 Name: protobuf-c Version: 1.4.1 Release: 1%{?dist} Summary: protobuf-c-1.4.1.tar.gz (custom compiled) License: GPL-2.0 URL: http://example.com Source0: protobuf-c-1.4.1.tar.gz BuildRequires: gcc,gcc-c++,protobuf %description PostGIS extends the capabilities of the PostgreSQL relational database by adding support for storing, indexing, and querying geospatial data. %prep %setup -q -n protobuf-c-1.4.1 %build export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig ./configure %install rm -rf $RPM_BUILD_ROOT make install DESTDIR=%{buildroot} %files /usr/local %changelog * Fri May 16 2025 root - Custom built from protobuf-c-1.4.1.tar.gz
1.3.6 编译gdal3.5.2 gdal.spec
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 Name: gdal Version: 3.5.2 Release: 1%{?dist} Summary: gdal-3.5.2.tar.gz (custom compiled) License: GPL-2.0 URL: http://example.com Source0: gdal-3.5.2.tar.gz BuildRequires: gcc,gcc-c++,proj %description PostGIS extends the capabilities of the PostgreSQL relational database by adding support for storing, indexing, and querying geospatial data. %prep %setup -q -n gdal-3.5.2 %build ./configure %install rm -rf $RPM_BUILD_ROOT make install DESTDIR=%{buildroot} %files /usr/local %changelog * Sat May 17 2025 root - Custom built from gdal-3.5.2.tar.gz
1.3.7 编译postgis3.3.2 postgis.spec
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 Name: postgis Version: 3.3.2 Release: 1%{?dist} Summary: postgis-3.3.2.tar.gz (custom compiled) License: GPL-2.0 URL: https://postgis.net/ Source0: postgis-3.3.2.tar.gz BuildRequires: gcc,gcc-c++,sqlite,sqlite-devel,libxml2,libxml2-devel,postgresql,geos,proj,protobuf,protobuf-c,gdal %description PostGIS extends the capabilities of the PostgreSQL relational database by adding support for storing, indexing, and querying geospatial data. %prep %setup -q -n postgis-3.3.2 %build echo -e "/usr/local/lib">/etc/ld.so.conf.d/locallib.conf sudo ldconfig ./configure --with-pgconfig=/usr/local/postgresql/bin/pg_config %install rm -rf $RPM_BUILD_ROOT make install DESTDIR=%{buildroot} %files /usr/local %changelog * Fri May 16 2025 root - Custom built from postgis-3.3.2.tar.gz
1.4 实践-安装 现在需要安装postgresql12.9与postgis3.3.2。首先,准备编译后的rpm包目录如下
1 2 3 4 5 6 7 8 9 [root@rocky-vm aarch64] . ├── gdal-3.5.2-1.el9.aarch64.rpm ├── geos-3.9.4-1.el9.aarch64.rpm ├── postgis-3.3.2-1.el9.aarch64.rpm ├── postgresql-12.9-1.el9.aarch64.rpm └── proj-6.3.2-1.el9.aarch64.rpm 0 directories, 5 files
之后,执行命令,进行安装
1 rpm -ivh postgresql-12.9-1.el9.aarch64.rpm postgis-3.3.2-1.el9.aarch64.rpm gdal-3.5.2-1.el9.aarch64.rpm geos-3.9.4-1.el9.aarch64.rpm proj-6.3.2-1.el9.aarch64.rpm
然后,进行数据库相关配置。
1 2 3 4 5 useradd postgres mkdir -p /usr/local /postgresql/data chown -R postgres:postgres /usr/local /postgresql sudo -u postgres /usr/local /postgresql/bin/initdb -D /usr/local /postgresql/data sudo -u postgres /usr/local /postgresql/bin/pg_ctl start -D /usr/local /postgresql/data
最后,开启postgis扩展。
1 2 3 4 5 6 7 echo -e "/usr/local/lib" >/etc/ld.so.conf.d/locallib.confsudo ldconfig sudo -u postgres /usr/local /postgresql/bin/psql create database tb_test; \connect tb_test; create extension postgis; select extname,extversion from pg_extension;
二、deb 本章节所有示例步骤,均是基于Debian12.10 完成。
1 Linux debian 6.1.0-32-amd64
2.1 dpkg命令基础 下面简单记录常见的dpkg命令使用方式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 dkpg -i xxx.deb dpkg -s xxx dpkg -L xxx dpkg -S /usr/bin/sh dpkg -r xxx dpkg -l cat /var/log /dpkg.log |grep " install " dpkg -s xxx
2.2 编译入门 按如下格式创建hello
目录
1 2 3 4 5 6 7 8 9 hello ├── DEBIAN │ └── control └── usr └── local └── bin └── hello 5 directories, 2 files
规范说明
路径包名/DEBIAN/control
:存放deb编译的规范文件。 路径包名/usr/local/bin/hello
:安装deb后,将脚本放置在/usr/local/bin
路径下。 创建control
1 2 3 4 5 6 7 8 9 Package: hello Version: 0.0.1 Section: base Priority: optional Architecture: all Build-Depends: gcc Depends: bash Maintainer: YourName <your.email@example.com> Description: A simple Hello World example script
运行命令,编译deb
1 dpkg-deb --build hello hello-0.0.1-1.noarch.deb
dpkg-deb
在build时,不会校验Build-Depends
,只有像debuild
或者dpkg-buildpackage
这类才会在编译时校验。
2.3 实践-编译 meethigher/deb-build-examples: 基于Debian12.10构建deb的脚本示例
2.3.1 编译PostgreSQL12.9 deb的编译,比rpm要麻烦不少,但是却又更灵活。他需要自己手动编译并导出编译结果到指定目录,然后打包。
按如下格式创建postgresql
目录
1 2 3 4 5 6 root@debian:~/debbuild postgresql/ └── DEBIAN └── control 2 directories, 1 file
首先,我们需要安装make相关的命令。
之后,安装postgresql编译需要的软件包。
1 apt -y install gcc libreadline-dev zlib1g-dev
解压postgresql-12.9.tar.gz
并将编译结果输出到指定目录~/debbuild/postgresql
1 2 3 4 5 6 tar -zxvf postgresql-12.9.tar.gz cd postgresql-12.9./configure --prefix=/usr/local /postgresql && make make install DESTDIR=~/debbuild/postgresql cd ~/debbuild/dpkg-deb --build postgresql postgresql-12.9-1.aarch64.deb
2.4 实践-安装 debian默认是不安装sudo,需要手动安装,之后再安装postgresql.deb
1 2 3 4 5 6 7 apt -y install sudo dpkg -i postgresql-12.9-1.amd64.deb useradd postgres mkdir /usr/local /postgresql/data mkdir /usr/local /postgresql/data sudo -u postgres /usr/local /postgresql/bin/initdb -D /usr/local /postgresql/data/ sudo -u postgres /usr/local /postgresql/bin/pg_ctl start -D /usr/local /postgresql/data/