rm包安装时新旧对比的原理(编译后rpm安装时,常会报错:which is newer than):
第一比较:rpm的属性 epoch > version > release
第二比较:将version 与 release 分段比较(分隔符以符号字符分割),逐段比较。
第三比较:与第二类似,将代表版本的字符串分段,适用于数字与字符比较,字符与字符比较
数字大于字符,字符与字符比较时按acii码表的顺序比较,越排后代表越新,小写字母新与大写字母
参考链接:RPM 打包指南 | Red Hat Product Documentation
打包小技巧:
1.rpmbuild 命令支持使用参数传到宏和变更,以下是给内置的宏‘_prefix’(默认为空)一个自定义路径,实现rpm包文件的安装目录自定义。
2.使用rpm --eavl %{} 格式可以打印宏和变量的值
3.可以使用rpmbuild --showrc 查看预定的宏及变量值,找到宏或者变量的引用链,即可通过命令行传参,而不用逐个修改SPEC文件内容。下图就是示例
4.如果打包中的一些配置文件或其他文件,不想在安装包的时候覆盖了系统原有的文件,可以修改attr指令添加(noreplace)选项,指明安装包的时候如果文件存在则不安装包内的文件
SPEC文件介绍:
文件主体分为二大部分一为“Preamble”,用于定义包的元数据信息(可以在Body 中引用),一为“Body ”
,用于描述包的构建过程到安装过程。
Body 部分,在不同的阶段使用不同指令集合,实现具体的构建或安装执行细节。
Body-build:构建包阶段,使用的指令集有%description、%prep、%build、%install、%check、%files、%changelog,每个指令后面都可以跟上子包的名称,实现二进制的分类。
Boyd-Scriptlet: 脚本注入阶段,该内容用于rpm安装与卸载时,不同阶段运行不同命令。可实现安装前后的配置备份,还原,冲突检测,修复环境变量,启动方式等等。使用的指令集有
Boyd-Triggers:同样定义rpm包在安装于卸载时执行的命令,但是这个阶段所定义的内容都是交互式的。
但是在redhat7系列的SPEC中看似被用于在启动服务时所执行的命令,如图:
SPEC各个阶段:
自己不会常用的变量 "1" 的取值为 0: 卸载 、1:安装、2:升级。
下面的用法示例:
if [ "$1"="1" ];then
xxxx
fi
所有的内置宏都能在 /usr/lib/rpm/macros 找到
spec 文件示例:
# 注解
##### 这几个宏可以解决rpm 安装的依赖冲突#############
AutoProv: no
%undefine __find_provides
AutoReq: no
%undefine __find_requires
# Do not try autogenerate prereq/conflicts/obsoletes and check files
%undefine __check_files
%undefine __find_prereq
%undefine __find_conflicts
%undefine __find_obsoletes
# Be sure buildpolicy set to do nothing
%define __spec_install_post %{nil}
# Something that need for rpm-4.1
%define _missing_doc_files_terminate_build 0
###### end ######################################
Name: openssl
Version: 1.1.1v
Release: x86_64.el7
Summary: Utilities from the general purpose cryptography library with TLS implementation
# 定义虚拟根目录(在%install 步骤种安装的路径)
BuildRoot: %_topdir/BUILDROOT
License: OpenSS
URL: http://www.openssl.org/
# 源码文件 ‘0’表示第几个文件
Source0: %{name}-%{version}.tar.gz
# 构建是需要的依赖
BuildRequires: make,gcc,cpio
# 运行时需要的依赖(rpm安装,及程序运行)
Requires: %{name}-libs = %{version}-%{release}
# rpm的安装路径(也是编译的参数,在编译过程中该目录的上级目录为bulidroot)
Prefix: %_prefix
# %define 是自定义宏的关键字,“%()” 定义shell
# 宏预定义规范 ,一个“_"开头为字符量 ,二个为命令
%define back_name %(date +"%F")
# 这里因为rpm的目录宏中没有openssl编译时需要的”openssldir"参数(存放配置文件),所以自定义一个
%define _openssldir /etc/pki/tls
%description
The OpenSSL toolkit provides support for secure communications between
machines. OpenSSL includes a certificate management tool and shared
libraries which provide various cryptographic algorithms and
protocols.
# 解决rpm安装时报的依赖冲突问题
%global __requires_exclude ^libthirdpartyplugin.so$
# we don't want to either provide or require anything from _docdir, per policy
%global __provides_exclude_from ^%{_docdir}/.*$
%global __requires_exclude_from ^%{_docdir}/.*$
# we don't want to either provide or require anything from _mandir, per policy
%global __provides_exclude_from ^%{_mandir}/.*$
%global __requires_exclude_from ^%{_mandir}/.*$
%prep
%setup -q
%build
./config -fPIC \
--prefix=%{prefix} \
--openssldir=%{_openssldir}
make %{?_smp_mflags}
%pre
#rpm -ql openssl | cpio -ocvB > /tmp/openssl-back-%{back_name}.cpio
#ls -l /etc/ssh | cpio -ocvB > /tmp/etc_ssh-%{back_name}.cpio
%install
rm -rf $RPM_BUILD_ROOT
%make_install
# 定义主包之外的包
%package libs
Summary: Development files for programs which will use the openssl library
Group: Development/Libraries
%description libs
OpenSSL RPM for version 1.1.1v on CentOS (development package)
%files
# 定义需要打包的文件,exclude 标识不需要打包的文件 正侧。
%{_bindir}/openssl
%config(noreplace) %{_openssldir}
%exclude %{_bindir}/c_rehash
%exclude %{_datadir}
%exclude %{_includedir}
%files libs
%{_libdir}/*
%changelog