RPM制作的笔记

关于制作RPM包的笔记~

Artical_Cover.jpg

一.制作RPM包教程

源码包的制作教程基于RHEL 5 & 6,当我写这个的时候还没有7版本,我会在后续更新新版本的路数.

1. rpm包的制作流程简述

  1. 放置源码进入SOURCES文件夹
  2. 写好SPEC文件
  3. 运行rpmbuild命令,自动执行安装和清理
  4. 自动将所有的源码解压到BUILD目录
  5. 自动安装所有的源码程序到BUILDROOT目录
  6. 自动根据SPEC文件里面的file程序段打包到rpm包中
  7. 自动进行后续的清理
  8. 生成完整的RPM包
  9. 手动进行安装测试

2. 如何做准备

需要明确的几个问题:

  1. 我们需要做一个什么样的RPM包,这个RPM包使用来做什么的,RPMs不一定包含的是二进制的内容,不一定需要编译。
  2. 至少我们需要源码,注意原材料的收集。
  3. 官方建议使用干净的源码,如果有补丁需要在制作的过程中打上补丁。
  4. 同一个软件,不同版本的RPM,新版本是否可以支持升级旧版本。需不需要清理旧版本的文件。升级是否会造成冲突。
  5. 依赖关系。
  6. 每一个PRM包都提供一种功能,Capability,可以被其他的PRM包依赖。RPM包的名字和所安装的文件都可以给其他的软件提供依赖。
  7. 自身名字的意义,提供的每一文件也可以被依赖,
  8. 他的安装和运行需要依赖于其他的RPM包本身或者所具有的文件,叫做依赖关系。
  9. 两类依赖关系,编译依赖和安装依赖。
  10. 规划依赖关系,写SPEC文件。
  11. 制作RPMs。
  12. 简单测试RPMs。

3. RPMs的规划

  1. 是否是应用程序,是否需要补丁,是否需要新的功能。
  2. 是一个程序的库文件
  3. 是一个系统配置文件集
  4. 是一个文档文件包
  5. 是否拆分完整的软件,例如:MySQL-5.5.22.tar.gz,在制作RPM包的时候被拆分为MySQL,mysql-server,mysql-devel,等等。
  6. 是一个二进制还是源码,当时都有。例如:src.rpm,里面包括了 source.tar.gz 和 spec,需要使用者安装完成之后编译再安装。

4. 制作过程

1. 设计目录结构(set up the directory structure)

制作RPM过程中千万不能用root用户
每个版本对于目录的要求不同,五个不同的目录:

  1. BUILD:不需要放任何的内容,这个目录是真正工作的目录。用于解压编译源码。
  2. RPMS:制作完成的RPM包放在这个里面,里面的目录的名字和结构与特定平台架构有关,可以交叉平台编译。
  3. SOURCES:所有收集的源码都在这个目录里面。
  4. SPECS:放置SPEC文件,作为制作过程的指导说明。以软件包的名字命名,以.spec结尾。
  5. SRPMS:放置了SRC(source)格式的RPM包。
    红帽提供了默认的制作目录,在/usr/src/redhat.
    1
    [LiarLee@localhost ~] tree /usr/src/redhat

2. 放置文件到正确的指定的目录(Place the sources in the right dirctory)。

我们首先需要自己制定自己的制作源码目录,在不使用root用户的前提下进行制作,需要修改系统的宏,来制定新的工作目录。修改工作目录的过程如下:

  1. 使用命令查看默认的宏:
    1
    2
    [LiarLee@localhost ~] rpmbuild --showrc   \\ 显示所有的相关宏定义
    _build——表示目录; __rm——表示命令
  2. 使用命令查看默认的配置文件:
    1
    2
    3
      [LiarLee@localhost ~] rpmbuild --showrc | grep macrofiles    \\ 显示配置文件的全局路径和文件名  
    \\ 权限由小到大,后一个文件的参数覆盖前面所有的定义
    \\ 所以我们在家目录下创建隐藏文件.rpmmacros可以直接配置自定义的设置。
  3. 使用命令查看默认的工作目录定义:
    1
    2
      [LiarLee@localhost ~] rpmbuild --showrc | grep _topdir   \\ 显示默认的工作目录宏定义  
    \\ 以相同的模式在.rpmmacros中直接覆盖配置,可以更改工作目录
  4. 更改topdir的宏,使用rpmbuilder的用户,创建.rpmmacros,添加内容配置宏:
    1
    2
    3
    4
    [LiarLee@localhost ~] vim .rpmmacros         \\ Create .rpmmacros file  
    %_topdir /home/rpmbuilder/rpmbild/
    [LiarLee@localhost ~] mkdir -pv rpmbuild/{BUILD,RPMS,SOURCES,SPEC,SRPMS}
    [LiarLee@localhost ~] rpmbuild --showrc | grep _topdir \\ Review the Result

3. 创建一个spec文件(Create a spec file that tells the rpmbuild command what to do)。

  1. spec文件使用软件的名字版本作为文件名;.spec作为扩展名。
  2. rpm -qi mysql & rpm -qpi mysql,命令查看rpm信息,信息从spec文件中定义,软件包信息说明段落定义。
  3. spec文件有如下几个段落:
    1. The introduction section
      设置软件包的基本信息
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      Summary:  \\ 简单描述
      Name: \\ 软件名字
      Version: \\ 版本号
      Release: \\ 发行号
      License: \\ 协议
      Group: \\ GROUP范围在这个文件中描述 /usr/share/doc/rpm-*/GROUPS
      URL: \\ 从何处获取的站点链接,下载路径
      Packager: \\ 制作者<制作者邮箱>
      Vendor: \\ 制作者的公司或者本人名字
      Source: \\ 源文件地址,一个链接地址
      BuildRoot: \\ 制作RPM包的时候的虚拟Root目录
      BuildRequires: \\ 制作过程依赖于哪些软件包的名字
    2. The prep section
      解压源码包到BUILD目录的段,cd到需要的目录,设置环境变量。
      1
      2
      %prep
      %setup
    3. The build section
      这是源码包安装的make过程.
      1
      2
      3
      4
      %build
      ./configure OR %configure
      ./make OR %{__make}
      make % {?_smp_mflags} \\ 多对称处理器加速编译
    4. The install section
      这里是安装make install过程。系统中有install命令,install方式类似于COPY模式.
      1
      2
      3
      4
      %install
      %{__rm}
      %{__make} install DESTDIR="%{buildroot}"
      %find_lang %{name}
    5. The script section
      这里是定义执行需要的脚本,用来配置环境。例如:添加Apache用户.
      %pre Note:安装前执行
      %post Note:安装后执行
      %preun Note:卸载前执行
      %postun Note:卸载后执行
    6. The clean section
      清理之前所用到的BuildRoot目录的。
      1
      2
      %clean
      %{__rm}
    7. The files section
      对安装的软件的程序进行规划,哪些文件安装到那个文件夹,BUILDROOT下的所有文件必须在这个段中存在
      1
      2
      %files
      %config(noreplace) \\ 不替换旧的配置
    8. The changelog section
      记录版本迭代
      1
      2
      3
      * Wed Apr 11 2012 Liarlee.site <Liarlee@site.com> - ReleaseNumber 更改时间
      - Comments
      - Comments

4. 开始编译(Build the source and binary RPMs)

  1. rpmbuild命令说明:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    rpmbuild -bp        \\ 执行到prep section
    rpmbuild -bc \\ 执行到build section
    rpmbuild -bi \\ 执行到install section

    rpmbuild -bs \\ 制作源码格式的制作
    rpmbuild -bb \\ 制作二进制格式的rpm包
    rpmbuild -ba \\ 执行全部格式,BOTH二进制和源码

    rpmbuild -bl \\ BUILDROOT存在但是没有在FILES段中为包含进去的文件的CHECK命令
  2. 关于安装错误的说明:
    在执行过程中如果有报错我们只需要去按照提示修正错误即可,在执行结束之后会在RPMS目录下生成需要的RPM包RPM-DEBUG包.我们只需要RPM包即可,使用rpm -ivh进行安装测试.
    1
    [LiarLee@localhost ~] rpmbuild -ba SoftwareName.spec   \\开始制作的命令

rpm2cpio命令的说明

src-rpm包只是将源码打包成RPM格式,当我们安装src.rpm格式的安装包的时候会把包含的文件,解压到用户默认的工作目录下,所以这种格式的RPM包我们不用安装,直接制作RPM包即可.进行rebuild OR recompile.

1
2
[LiarLee@localhost ~] rpm2cpio mysql.src.rpm > mysql.cpio  
[LiarLee@localhost ~] rpm2cpio mysql.src.rpm | cpio -t

两个网站的推荐(搜索SRC-RPM包的站点):
rpmfind.net
rpm.pbone.net

二. 从头开始写新的SPEC files

制作RPM包的核心是写SPEC files,难以掌握的地方
介绍SPEC文件的基本语法和简单用法

1. Spec files overview

SPEC file里面都是指令,告诉RPMBuild命令如何一步一步解压,编译,做成不同的RPM包,依赖关系。 Macro是指的变量
大多数的字段由tag+value组成,tag是标签–Directives,不区分大小写;value是区分大小写的.

1.1 宏的自定义

用户自定义宏 : %define macro_name value
引用方式 : %{macro_name} OR %macro_name

1.2 注释的方式

使用#来进行注释
%–不能在注释中使用,如果必须使用需要双写%%

1
2
%prep  
\#this is a comment for %%prep

2. Defining package infomation

如何定义SPEC文件内的字段

2.1 软件包的信息

  • Name - 软件包名称 - 不能有短横线
  • Version - 版本号 - 不能有短横线
  • Release - 发行版本号
  • Group - /usr/src/doc/rpm-version/GROUPS文件中有详细的描述说明有哪些组可以使用

2.2 制作方信息

  • Vendor - 公司或者组织制作的RPM
  • URL - 一个主页链接
  • Packager - 名字<邮箱地址>
  • License - 许可,GPLv2,….etc.

2.3 描述信息

  • Summary - 不能超过50个字符,短描述
  • %description section - 全面描述,如果字符过多可以提前换行.

2.4 定义依赖关系

  • Requires : Capability - 定义软件包的能力,如果未定义显示包名.
  • Provides : Capability - 定义对外提供的能力
  • BuildRequires : Capability - 可以出现多次,直接写出需要的软件包名

2.5 设定Build目录

  • build - 用于解压安装源码
  • buildroot : ${_tmppath}/%{name}-%{version}-root
    使用$RPM_BUILD_ROOT 或者 %{buildroot}

2.6 命名Source文件

使用Sources字段 和 patch字段,指定源文件和补丁

  • Source0: https:// OR 相对路径, https不会下载, 自动本地寻址
  • Source1: sourcefiles_name
  • Source2: sourcefiles_name
  • Patch1: patchfiles_name
  • Patch2: patchfiles_name
  • Patch3: patchfiles_name
    补丁定义后可以直接使用patch命令进行补丁的安装,所以使用patch字段

3. Controlling the build

如何控制编译

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
40
%prep                 \\ 把Source内的解压源码包到BUILD目录,cd到源码目录,配置环境  

%setup -q \\ 控制解压的流程
%setup -n name \\ 目录名字
%setup -q \\ 静默模式
%setup -a number \\ AFTER,cd到目录之后解压缩
%setup -b number \\ BEFORE,先解压之后cd到目录里
%setup -c \\ 解压前创建目录
%setup -T \\ 不展开 直接复制

%patch1 \\ 打补丁
%patch2 \\ 打第二个补丁

%build \\ C类程序的configure & make过程
./configure --prefix=/usr \
--sysconfdir=/etc/nginx
make %{?_smp_mflags}

%build \\Perl的不同
perl Mailfile PL
make

%install \\ make install 过程
rm -rf %{buildroot} \\ Clean Stuff
make install DESTDIR=%{buildroot} \\ make install 命令编译安装
%{__install} -p -D -m 0644 %{SOURCE5} \
%{buildroot}%{_sysconfdir}/sysconfig/%{name} \\ install命令直接安装文件到目录
%{__install} -p -d -m 0755 %{buildroot}/var/log/nginx \\ install命令直接安装文件到指定的文件路径

%clean \\ 清理BUILD目录,清空为下次做准备; rpmbuild --clean mysql.spec
rm -rf %{buildroot} \\清理BUILD目录

%prep
%post
%prepun
%postun
使用IF可以对如下参数进行判断
$1 \\ 第一次安装
$2 OR $2+ \\ 升级
$0 \\ 卸载

4. Filling the list of files

填充文件列表

5. adding change log entries

添加更新日志

CentOS7打包Nginx过程记录

  1. useradd rpmbuilder -p rpmbuilder
  2. yum install -y rpmdevtools rpmbuild
  3. cd /home/rpmbuilder/
  4. rpmdev-setuptree
  5. cd ./rpmbuilder
  6. tree ./
  7. mv nginx-1.16.1.tar.gz ./rpmbuild/SOURCES/
  8. vim ./rpmbuilder/SPECS/nginx.spec
  9. vim nginx.service
  10. mv nginx.service /rpmbuild/SOURCES/nginx.service
    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
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    %define nginx_user nginx
    %define nginx_group nginx

    Name: nginx
    Version: 1.16.1
    Release: 1%{?dist}
    Summary: make rpm for nginx, version 1.16.1

    Group: System Environment/Daemons
    License: GPLv2
    URL: http://liarlee.site
    Source0: %{name}-%{version}.tar.gz
    Source1: nginx.service
    BuildRoot: $_topdir/BUILDROOT

    BuildRequires: gcc
    BuildRequires: gcc-c++
    BuildRequires: openssl
    BuildRequires: openssl-devel
    BuildRequires: pcre
    BuildRequires: pcre-devel
    BuildRequires: systemd
    Requires: openssl
    Requires: openssl-devel
    Requires: pcre
    Requires: pcre-devel
    Requires: systemd

    %description
    For online Ean portal, make by Hayden Lee, and take some personal option.

    %prep
    %setup -q


    %build
    ./configure \
    true--prefix=/data/web-server/nginx \
    --user=%{nginx_user} \
    --group=%{nginx_group} \
    --with-threads \
    --with-http_ssl_module \
    --with-http_stub_status_module \
    --with-http_realip_module \
    --with-http_gzip_static_module
    make %{?_smp_mflags}


    %install
    %{__rm} -rf %{buildroot}
    make install DESTDIR=%{buildroot}
    # install systemd-specific files
    %{__mkdir} -p $RPM_BUILD_ROOT%{_unitdir}
    %{__install} -m644 %SOURCE1 \
    $RPM_BUILD_ROOT%{_unitdir}/nginx.service

    %files
    %defattr(-,root,root)
    /data/web-server/nginx/
    %config(noreplace) /data/web-server/nginx/conf/nginx.conf
    %config(noreplace) /usr/lib/systemd/system/nginx.service
    %attr(0644,root,root) /data/web-server/nginx/conf/nginx.conf
    %pre
    getent group %{nginx_group} >/dev/null || groupadd -r %{nginx_group}
    getent passwd %{nginx_user} >/dev/null || \
    useradd -r -g %{nginx_group} -s /sbin/nologin \
    -d %{nginx_home} -c "nginx user" %{nginx_user}
    exit 0
    %post
    /usr/bin/systemctl preset nginx.service >/dev/null 2>&1 ||:
    /usr/bin/systemctl preset nginx-debug.service >/dev/null 2>&1 ||:
    # print site info
    cat <<BANNER
    ----------------------------------------------------------------------

    Thanks for using nginx!

    Please find the official documentation for nginx here:
    * http://nginx.org/en/docs/

    Commercial subscriptions for nginx are available on:
    * http://nginx.com/products/

    ----------------------------------------------------------------------
    BANNER
    %preun
    /usr/bin/systemctl --no-reload disable nginx.service >/dev/null 2>&1 ||:
    /usr/bin/systemctl stop nginx.service >/dev/null 2>&1 ||:

    %postun
    /usr/bin/systemctl daemon-reload >/dev/null 2>&1 ||:
    %{__rm} -rf /data/web-server/nginx
文章目录
  1. 1. 一.制作RPM包教程
    1. 1.1. 1. rpm包的制作流程简述
    2. 1.2. 2. 如何做准备
    3. 1.3. 3. RPMs的规划
    4. 1.4. 4. 制作过程
      1. 1.4.1. 1. 设计目录结构(set up the directory structure)
      2. 1.4.2. 2. 放置文件到正确的指定的目录(Place the sources in the right dirctory)。
      3. 1.4.3. 3. 创建一个spec文件(Create a spec file that tells the rpmbuild command what to do)。
      4. 1.4.4. 4. 开始编译(Build the source and binary RPMs)
  2. 2. rpm2cpio命令的说明
  3. 3. 二. 从头开始写新的SPEC files
    1. 3.1. 1. Spec files overview
      1. 3.1.1. 1.1 宏的自定义
      2. 3.1.2. 1.2 注释的方式
    2. 3.2. 2. Defining package infomation
      1. 3.2.1. 2.1 软件包的信息
      2. 3.2.2. 2.2 制作方信息
      3. 3.2.3. 2.3 描述信息
      4. 3.2.4. 2.4 定义依赖关系
      5. 3.2.5. 2.5 设定Build目录
      6. 3.2.6. 2.6 命名Source文件
    3. 3.3. 3. Controlling the build
    4. 3.4. 4. Filling the list of files
    5. 3.5. 5. adding change log entries
  4. 4. CentOS7打包Nginx过程记录