CentOS 如何打 RPM 包
Table of Contents
打包前的准备
安装相关打包工具
sudo yum install rpmdevtools rpmlint
rpmbuild --version
❯ rpmbuild --version z@z RPM 版本 4.11.3
新建用户
RPM 在打包的过程中会将文件临时安装到系统中,为了保证构建程序不破坏系统环境,要使用普通用户打包:
sudo useradd rpmuser
sudo passwd rpmuser
su - rpmuser
初始化打包环境
rpmdev-setuptree是rpmdevtools中带的初始化环境脚本,执行后会在用户主目录下创建rpmbuild目录和.rpmmacros文件,同时生成所需的子目录和默认的控制参数,执行:
rpmdev-setuptree
生成的目录结构:
`-- rpmbuild
|-- BUILD
|-- RPMS
|-- SOURCES
|-- SPECS
`-- SRPMS
默认的全局控制宏文件.rpmmacros内容:
%_topdir %(echo $HOME)/rpmbuild
%_smp_mflags %( \
[ -z "$RPM_BUILD_NCPUS" ] \\\
&& RPM_BUILD_NCPUS="`/usr/bin/nproc 2>/dev/null || \\\
/usr/bin/getconf _NPROCESSORS_ONLN`"; \\\
if [ "$RPM_BUILD_NCPUS" -gt 16 ]; then \\\
echo "-j16"; \\\
elif [ "$RPM_BUILD_NCPUS" -gt 3 ]; then \\\
echo "-j$RPM_BUILD_NCPUS"; \\\
else \\\
echo "-j3"; \\\
fi )
%__arch_install_post \
[ "%{buildarch}" = "noarch" ] || QA_CHECK_RPATHS=1 ; \
case "${QA_CHECK_RPATHS:-}" in [1yY]*) /usr/lib/rpm/check-rpaths ;; esac \
/usr/lib/rpm/check-buildroot
安装编译软件
制作rpm包要先编译在打二进制包,所以要装 gcc、make 等工具,如果是给 Golang 的项目打 RPM 包,还需要有 go 环境
yum install gcc gcc-c++ make
开始打包
准备源码
将源码包和补丁等放入rpmbuild/SOURCE目录
编写 SPEC 文件
SPEC文件控制整个rpm的打包过程,包含了打包的全部信息和控制参数,可以使用 rpmdev-newspec 命令来创建一个初始的SPEC文件,SPEC文件需放入rpmbuild/SPECS目录
rpmdev-newspec package-name.spec
SPEC 脚本文件名需以包名一致,/etc/rpmdevtools/spectemplate-* 下有许多常用软件 RPM 打包的 SPEC 文件模板。
SPEC 脚本主要定义了打包过程中的几个阶段的配置:
- 信息定义阶段 :定义软件包的名字、版本等信息和打包过程中用到的变量等
- 制作准备阶段 :解压源码包、补丁包并打补丁
- 编译阶段 :设置编译参数并编译源码
- 安装阶段 :定义安装过程所执行的命令,包括安装前、安装后、卸载前、卸载后执行的操作
- 清理阶段 :清理打包过程中用到的目录文件等
- 文件设置阶段 :要打包的文件和目录,并设置文件权限等
下面是打包 motan-go 所使用 SPEC 文件(motan-go.spec):
# 自定义宏
%define bindir /data1/weibo/motan-go
# 1.信息定义阶段
### 软件名字,要与spec的文件名一致 openresty
Name: motan-go
### 软件主版本号
Version: 1.0
### 发行编号,每打包一次值递增,主版本号发布新版后需重置该值
Release: 4%{?dist}
### 一行简短的软件简介,结尾不要加标点
Summary: Motan is Weibo RPC
Group: Weibo Motan G.
### 软件许可
License: Apache License 2.0
### 软件项目主页
URL: http://git.intra.weibo.com/openapi_rd/motan-go/
### 放置在SOUIRCES目录的软件源码包名,可以指定多个:source1、source2等
Source0: %{name}.%{version}.tar.gz
### 补丁名,也可以写多个 patch1、patch2等
#patch0: 0.patch
### 在 install 阶段的测试安装目录,方便写files
buildroot: %_topdir/BUILDROOT
BuildRequires: go
### 安装软件包时所需的依赖包列表,可以指定版本如 bash >= 1.1.1
Requires: readline-devel,pcre-devel,openssl-devel
### 程序的详细多行描述,每行必须小于等于 80 个字符,空行表示开始新段
%description
Motan java.go.php
# 2.准备阶段
%prep
## 静默模式解压并进入解压后的目录,也常用:%autosetup -n %{name}
%setup -q -n motan-go
### 需要打补丁,在这里写打补丁的命令
#%patch0 -p1
# 3. 编译阶段
%build
### 编译参数
#./configure
#使用多核处理器并行编译
#make %{?_smp_mflags}
cd main/
go build magent.go
# 4.安装阶段
%install
### 删除之前的残留文件
rm -rf %{buildroot}
mkdir -p %{buildroot}/%{bindir}/bin
install -m755 main/magent %{buildroot}/%{bindir}/bin/
install -d -m755 %{buildroot}/%{bindir}/bin/
cp -pvr motan.yaml %{buildroot}/%{bindir}/
## rpm安装前制行的脚本
%pre
### $1==1 代表的是第一次安装,2代表是升级,0代表是卸载
#if [ $1 == 1 ];then
# /usr/sbin/useradd -r %{nginx_user} 2> /dev/null
#fi
## rpm安装后制行的脚本
%post
###卸载前执行的脚本
%preun
###卸载后执行的脚本
%postun
# 5.清理阶段
%clean
### 删除buildroot目录
rm -rf %{buildroot}
# 6.文件设置阶段
%files
### 设定默认权限,如果下面没有指定权限,则继承默认
%defattr (-,root,root,0755)
###要打包的文件和目录,在执行完rpmbuild -bi后,参考%{rootbuild}下生成的文件和目录
%{bindir}/bin/magent
/data1/weibo/motan-go
### 变更日志 格式固定,生成请用命令: rpmdev-bumpspec --comment=COMMENT --userstring=NAME+EMAIL_STRING SPECFILES
#%changelog
#* Thu Dec 31 2015 will <will@52os.net> - 1.9.7.1-4
#- openresty init
%define __debug_install_post %{_rpmconfigdir}/find-debuginfo.sh %{?_find_debuginfo_opts} "%{_builddir}/%{?buildsubdir}" %{nil}
编写完 SEPC 文件后,可以通过 rpmlint 检查是否有配置错误
rpmlint motan-go.spec
如果有错误或者警告,使用 “-i” 选项可以查看更详细的信息
开始打 RPM 包
rpmbuild命令会根据spec文件来生成rpm包,主要用到以下几个参数
rpmbuild --help
-bp 执行到%prep阶段结束
-bc 执行到%build阶段结束
-bi 执行到%install阶段结束
-bl 检测%files文件是否有丢失
-ba 创建src.rpm和二进制包
-bs 只创建src.rpm源码包
-bb 只创建二进制rpm包
常用的参数就这几个,其它的自己看man手册,开始打包:
rpmbuild -bp motan-go.spec
rpmbuild -bc motan-go.spec
rpmbuild -bi motan-go.spec
rpmbuild -bl motan-go.spec
rpmbuild -ba motan-go.spec
分阶段测试,方便排错,如果哪个阶段有错误,可以使用–short-circuit跳过之前成功的阶段,节省时间
rpmbuild -bi --short-circuit ngx_openresty.spec
打包遇到的问题
extracting debug info from /home/rpmuser/rpmbuild/BUILDROOT/motan-go-1.0-4.el7.centos.x86_64/data1/weibo/motan-go/bin/magent
*** ERROR: No build ID note found in /home/rpmuser/rpmbuild/BUILDROOT/motan-go-1.0-4.el7.centos.x86_64/data1/weibo/motan-go/bin/magent
错误:/var/tmp/rpm-tmp.ozJYbO (%install) 退出状态不好
解法: 在 SPEC 文件中添加一行
%define __debug_install_post %{_rpmconfigdir}/find-debuginfo.sh %{?_find_debuginfo_opts} "%{_builddir}/%{?buildsubdir}" %{nil}
rpm 执行安装包
二进制包(Binary)以及源代码包(Source)两种。二进制包可以直接安装在计算机中,而源代码包将会由 RPM自动编译、安装。源代码包经常以src.rpm作为后缀名。
常用命令组合:
-ivh:安装显示安装进度–install–verbose–hash
-Uvh:升级软件包–Update;
-qpl: 列出RPM软件包内的文件信息[Query Package list];
-qpi:列出RPM软件包的描述信息[Query Package install package(s)];
-qf:查找指定文件属于哪个RPM软件包[Query File];
-Va:校验所有的 RPM软件包,查找丢失的文件[View Lost];
-e:删除包
rpm -q samba //查询程序是否安装
rpm -ivh /media/cdrom/RedHat/RPMS/samba-3.0.10-1.4E.i386.rpm //按路径安装并显示进度
rpm -ivh –relocate /=/opt/gaim gaim-1.3.0-1.fc4.i386.rpm //指定安装目录
rpm -ivh –test gaim-1.3.0-1.fc4.i386.rpm //用来检查依赖关系;并不是真正的安装;
rpm -Uvh –oldpackage gaim-1.3.0-1.fc4.i386.rpm //新版本降级为旧版本
rpm -qa | grep httpd #[搜索指定rpm包是否安装]–all搜索httpd
rpm -ql httpd #[搜索rpm包]–list所有文件安装目录
rpm -qpi Linux-1.4-6.i368.rpm #[查看rpm包]–query–package–install package信息
rpm -qpf Linux-1.4-6.i368.rpm #[查看rpm包]–file
rpm -qpR file.rpm #[查看包]依赖关系
rpm2cpio file.rpm |cpio -div #[抽出文件]
rpm -ivh file.rpm #[安装新的rpm]–install–verbose–hash
rpm -ivhhttp://mirrors.kernel.org/fedora/core/4/i386/os/Fedora/RPMS/gaim-1.3.0-1.fc4.i386.rpm
rpm -Uvh file.rpm #[升级一个rpm]–upgrade
rpm -e file.rpm #[删除一个rpm包]–erase
常用参数:
Install/Upgrade/Erase options:
-i, –install install package(s)
-v, –verbose provide more detailed output
-h, –hash print hash marks as package installs (good with -v)
-e, –erase erase (uninstall) package
-U, –upgrade=+ upgrade package(s)
--replacepkge 无论软件包是否已被安装,都强行安装软件包
–test 安装测试,并不实际安装
–nodeps 忽略软件包的依赖关系强行安装
–force 忽略软件包及文件的冲突
Query options (with -q or –query):
-a, –all query/verify all packages
-p, –package query/verify a package file
-l, –list list files in package
-d, –docfiles list all documentation files
-f, –file query/verify package(s) owning file
RPM源代码包装安装
.src.rpm结尾的文件,这些文件是由软件的源代码包装而成的,用户要安装这类RPM软件包,必须使用命令:
rpm –recompile vim-4.6-4.src.rpm #这个命令会把源代码解包并编译、安装它,如果用户使用命令:
rpm –rebuild vim-4.6-4.src.rpm #在安装完成后,还会把编译生成的可执行文件重新包装成i386.rpm 的RPM软件包。
[root@localhost src]# rpm -ivh awstats-6.8-1.noarch.rpm
error: Failed dependencies:
perl(LWP::UserAgent) is needed by awstats-6.8-1.noarch
[root@localhost src]#
使用rpm 属性相依套件的档案
[root@localhost src]# rpm -qpR awstats-6.8-1.noarch.rpm
/bin/sh
/usr/bin/perl
config(awstats) = 6.8-1
perl >= 0:5.005
perl(LWP::UserAgent)
perl(POSIX)
perl(Socket)
perl(Time::Local)
perl(strict)
perl(vars)
rpmlib(CompressedFileNames) <= 3.0.4-1
rpmlib(PayloadFilesHavePrefix) <= 4.0-1