rpmbuild学习总结

版本V1.0

时间2013-05-09

版权GPL

作者itnihao

邮箱 itnihao@qq.com

博客 http://itnihao.blog.51cto.com

如需重新发行,请注明以上信息,谢谢合作


rpmbuild的原理,意义,在此不介绍了,本文主要是一个思路,具体参考官方文档

http://docs.fedoraproject.org/en-US/Fedora_Draft_Documentation/0.1/html/RPM_Guide/index.html

一,rpmbuild的步骤

  1. 1.Set up the directory structure  

  2. 2.Place the sources in the right directory  

  3. 3.Create a spec file that tells the rpmbuild command what to do  

  4. 4.Build the source andbinary RPMs  

二,rpmbuild各目录的作用

BUILDThe rpmbuild command builds software in this directory
RPMSThe rpmbuild command stores binary RPMs it reates in this irectory
SOURCESYou should put the sources for the application in this directory
SPECSYou should place the spec file for each RPM you plan to make in this directory
SRPMSThe rpmbuild command places source RPMs in this directory

三,rpmbuild系统内置变量

rpmbuild --showrc

useradd admin

su - admin  

mkdir -pv rpmbuild/{BUILD,RPMS,SOURCES,SPECS,SRPMS}  

echo "% _topdir  /home/admin/rpmbuild" >~/.rpmmacros  

rpmbuild --showrc|grep _topdir

132351574.jpg

默认的spec格式如下

Name:
Version:
Release:        1%{?dist}
Summary:
Group:
License:
URL:
Source0:
BuildRoot:      %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX)
BuildRequires:
Requires:
%description
%prep
%setup -q
%build
%configure
make %{?_smp_mflags}
%install
rm -rf %{buildroot}
make install DESTDIR=%{buildroot}
%clean
rm -rf %{buildroot}
%files
%defattr(-,root,root,-)
%doc
%changelog

四,实例说明  

#定义变量

%define nginx_home %{_localstatedir}/cache/nginx
%define nginx_user nginx
%define nginx_group nginx

# 软件包的内容概要

Summary: high performance web server

#软件包的名称

Name: nginx

#软件包的版本

Version: 1.2.6

#软件包的发布实际版本号

Release: 1%{?dist}.ngx

#发行商或者打包组织的信息

Vendor: nginx inc.

#软件的主页

URL: http://nginx.org/

#源代码包,可以带多个source0source1等源,后面可以用%{SOURCE0},%{SOURCE1}引用

Source0: http://nginx.org/download/%{name}-%{version}.tar.gz
Source1: logrotate
Source2: nginx.init
Source3: nginx.sysconf
Source4: nginx.conf
Source5: nginx.vh.default.conf
Source6: nginx.vh.example_ssl.conf
Source7: nginx.suse.init
Source8: nginx.vh.example.conf

#软件授权方式

License: 2-clause BSD-like license
%if 0%{?suse_version}

#软件分组

Group: Productivity/Networking/Web/Servers
%else
Group: System Environment/Daemons
%endif

#安装或者编译时使用的虚拟目录

BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root

#需要依赖的软件包

BuildRequires: zlib-devel
BuildRequires: pcre-devel
BuildRequires: perl
%if 0%{?suse_version}
BuildRequires: libopenssl-devel
Requires(pre): pwdutils
%else
BuildRequires: openssl-devel
Requires: initscripts >= 8.36
Requires(pre): shadow-utils
Requires(post): chkconfig
%endif

#指明本软件一些特定的功能,以便与其他rpm识别

Provides: webserver

#软件的详细说明

%description
nginx [engine x] is a HTTP and reverse proxy server, as well as
a mail proxy server
%package debug
Summary: debug version of nginx
Group: System Environment/Daemons
Requires: nginx
%description debug
not stripped version of nginx build with the debugging log support
%prep

#预处理脚本

#    该段内容为安装前脚本程序。它在软件包安装之前执行,通常是检测操作环境,建立有关目录,清理多余文件等等,为软件包的顺利安装做准备。本段很少使用 ,其段名格式为: %pre [子包选项]

%setup -q

#此为预处理阶段,其内容为预处理脚本程序,该程序完成以下任务:

1.建立软件编译用目录

2.将源程序解压缩

3.通过打补丁,升级源程序

4.执行其他一些操作,使源程序随时可进行编译

在此脚本程序中,可以使用如下两个宏命令:

%setup

  这个宏利用系统中的gziptar等命令,来解压源程序包。RPM会自动探测源程序是否压缩,如果压缩,它会用gzip将其解压缩,否则直接使用

tar命令展开包中文件,其格式为

%setup  [-n name] [-c] [-D] [-T] [-b N] [-a N]

注意:[]所括为可选项。

1)当没有任何选项时

   这个宏用来解压默认的源程序包(由头文件SourceSource0域指定).注意:源程序包中的文件应用软件名-版本号作为其上层目录,这样%setup宏就可以正常工作。如果不以软件名-版本号作为其上层目录。则%setup宏工作时有一个指令“cd  软件包-版本号(转目录)

会因为系统中没有此目录而出错退出(除非在此宏上面加上建立此目录的命令)

2-n    name引用目录

3-c:  此选项的作用是创建上层目录(软件名-版本号目录)并转到这个目录。

4-D    解压源程序之前不要删除软件的上层目录(软件名-版本号)

5-T    本选项的作用是不解压默认的源程序包(由文件头的Source或者Source0域所定义)

6-b -N 本选项指示RPM在转到上层目录前解压第N个源程序包(由文件头SourceN域定义),这适用于含上层目录的源程序包

(7) -a N   本选项指示RPM在转到上层目录后再解压第N个源程序包

%patch

此宏利用系统中的patch命令,来给指定的源程序包打补丁,从而将程序升级。其使用格式为:  

%patch [-P N] [-p N] [-b name] [-E]

: []所括为可选项  

(1) 当没有任何选项时:
没有任何选项时,该宏使用的是默认的补丁文件(第0个补丁文件),即由文件头Patch或Patch0域所定义的文件
patch命令用了两个选项:(有关patch命令用法,详见其用户手册)
* -p :这个选项用于确定patch所要操作的文件。它针对补丁文件头部的文件名,删除名字中指定数目个
斜杠(/)前面的所有字符,从而得到要操作的文件名。
* -s :这个选项指示patch在打补丁过程中不输出任何信息,即使有错误发生。
(2) -P N :
使用此选项以指示RPM使用第N个补丁文件(由文件头PatchN域定义)。
(3) -p N :
此选项与其参数是由%patch宏直接传给patch命令的。请参见上面patch命令所用的-p选项的介绍。
(4) -b name :
当有多个patch命令操作同一个文件时,patch会将原文件换名保存(其后缀变作.orig)
(5) -E :
此选项直接传给patch命令,其作用是:如果一个文件打完补丁后内容为空(字节数为0),则删除这个文件。


#开始构建包

%build

此为编译段,其内容为编译脚本程序。该程序完成源程序的编译和连接。一个最简单的例子就是程序中仅有一个make命令。这适用于大部分情况  ,因为多数软件均有自己的makefile,这样通过make命令就可实现编译与连接。如果没有makefile的话,需要软件包制作者自己在编译段书写上一系列的编译连接命令。
./configure \
        --prefix=%{_sysconfdir}/nginx/ \
        --sbin-path=%{_sbindir}/nginx \
        --conf-path=%{_sysconfdir}/nginx/nginx.conf \
        --error-log-path=%{_localstatedir}/log/nginx/error.log \
        --http-log-path=%{_localstatedir}/log/nginx/access.log \
        --pid-path=%{_localstatedir}/run/nginx.pid \
        --lock-path=%{_localstatedir}/run/nginx.lock \
        --http-client-body-temp-path=%{_localstatedir}/cache/nginx/client_temp \
        --http-proxy-temp-path=%{_localstatedir}/cache/nginx/proxy_temp \
        --http-fastcgi-temp-path=%{_localstatedir}/cache/nginx/fastcgi_temp \
        --http-uwsgi-temp-path=%{_localstatedir}/cache/nginx/uwsgi_temp \
        --http-scgi-temp-path=%{_localstatedir}/cache/nginx/scgi_temp \
        --user=%{nginx_user} \
        --group=%{nginx_group} \
        --with-http_ssl_module \
        --with-http_realip_module \
        --with-http_addition_module \
        --with-http_sub_module \
        --with-http_dav_module \
        --with-http_gzip_static_module \
        --with-http_random_index_module \
        --with-http_secure_link_module \
        --with-http_stub_status_module \
        --with-mail \
        --with-mail_ssl_module \
        --with-file-aio \
        --with-ipv6 \
        --with-debug \
        --with-cc-opt="%{optflags} $(pcre-config --cflags)" \
        $*
make %{?_smp_mflags}
%{__mv} %{_builddir}/%{name}-%{version}/objs/nginx \
        %{_builddir}/%{name}-%{version}/objs/nginx.debug
./configure \
        --prefix=%{_sysconfdir}/nginx/ \
        --sbin-path=%{_sbindir}/nginx \
        --conf-path=%{_sysconfdir}/nginx/nginx.conf \
        --error-log-path=%{_localstatedir}/log/nginx/error.log \
        --http-log-path=%{_localstatedir}/log/nginx/access.log \
        --pid-path=%{_localstatedir}/run/nginx.pid \
        --lock-path=%{_localstatedir}/run/nginx.lock \
        --http-client-body-temp-path=%{_localstatedir}/cache/nginx/client_temp \
        --http-proxy-temp-path=%{_localstatedir}/cache/nginx/proxy_temp \
        --http-fastcgi-temp-path=%{_localstatedir}/cache/nginx/fastcgi_temp \
        --http-uwsgi-temp-path=%{_localstatedir}/cache/nginx/uwsgi_temp \
        --http-scgi-temp-path=%{_localstatedir}/cache/nginx/scgi_temp \
        --user=%{nginx_user} \
        --group=%{nginx_group} \
        --with-http_ssl_module \
        --with-http_realip_module \
        --with-http_addition_module \
        --with-http_sub_module \
        --with-http_gzip_static_module \
        --with-http_random_index_module \
        --with-http_secure_link_module \
        --with-http_stub_status_module \
        --with-file-aio \
        --with-ipv6 \
        --with-cc-opt="%{optflags} $(pcre-config --cflags)" \
        $*
make %{?_smp_mflags}

#把软件安装到虚拟的根目录中

%install

此为安装段,其内容是安装脚本程序。该程序将已编译连接好的执行程序或其它文件存放到指定目录下,这些程序或文件供RPM打包时使用。一个最简单的例子就是程序中仅用一个make install命令,从而完成安装。这也需要相应的软件有makefile维护文件。没有的话,软件包制作者也得自己写指令。


%{__rm} -rf $RPM_BUILD_ROOT
%{__make} DESTDIR=$RPM_BUILD_ROOT install
%{__mkdir} -p $RPM_BUILD_ROOT%{_datadir}/nginx
%{__mv} $RPM_BUILD_ROOT%{_sysconfdir}/nginx/html $RPM_BUILD_ROOT%{_datadir}/nginx/
%{__rm} -f $RPM_BUILD_ROOT%{_sysconfdir}/nginx/*.default
%{__rm} -f $RPM_BUILD_ROOT%{_sysconfdir}/nginx/fastcgi.conf
%{__mkdir} -p $RPM_BUILD_ROOT%{_localstatedir}/log/nginx
%{__mkdir} -p $RPM_BUILD_ROOT%{_localstatedir}/run/nginx
%{__mkdir} -p $RPM_BUILD_ROOT%{_localstatedir}/cache/nginx
%{__mkdir} -p $RPM_BUILD_ROOT%{_sysconfdir}/nginx/conf.d
%{__rm} $RPM_BUILD_ROOT%{_sysconfdir}/nginx/nginx.conf
%{__install} -m 644 -p %{SOURCE4} \
   $RPM_BUILD_ROOT%{_sysconfdir}/nginx/nginx.conf
%{__install} -m 644 -p %{SOURCE5} \
   $RPM_BUILD_ROOT%{_sysconfdir}/nginx/conf.d/example.txt
%{__install} -m 644 -p %{SOURCE6} \
   $RPM_BUILD_ROOT%{_sysconfdir}/nginx/conf.d/example_ssl.conf
%{__install} -m 644 -p %{SOURCE8} \
   $RPM_BUILD_ROOT%{_sysconfdir}/nginx/conf.d/example.conf
%{__mkdir} -p $RPM_BUILD_ROOT%{_sysconfdir}/sysconfig
%{__install} -m 644 -p %{SOURCE3} \
   $RPM_BUILD_ROOT%{_sysconfdir}/sysconfig/nginx
# install SYSV init stuff
%{__mkdir} -p $RPM_BUILD_ROOT%{_initrddir}
%if 0%{?suse_version}
%{__install} -m755 %{SOURCE7} \
   $RPM_BUILD_ROOT%{_initrddir}/nginx
%else
%{__install} -m755 %{SOURCE2} \
   $RPM_BUILD_ROOT%{_initrddir}/nginx
%endif
# install log rotation stuff
%{__mkdir} -p $RPM_BUILD_ROOT%{_sysconfdir}/logrotate.d
%{__install} -m 644 -p %{SOURCE1} \
   $RPM_BUILD_ROOT%{_sysconfdir}/logrotate.d/nginx
%{__install} -m644 %{_builddir}/%{name}-%{version}/objs/nginx.debug \
   $RPM_BUILD_ROOT%{_sbindir}/nginx.debug
#清理临时文件
%clean
%{__rm} -rf $RPM_BUILD_ROOT

#定义哪些文件或者目录会放入rpm中

%files
%defattr(-,root,root)
%{_sbindir}/nginx
%dir %{_sysconfdir}/nginx
%dir %{_sysconfdir}/nginx/conf.d
%config(noreplace) %{_sysconfdir}/nginx/nginx.conf
#%config(noreplace) %{_sysconfdir}/nginx/conf.d/default.conf
%config(noreplace) %{_sysconfdir}/nginx/conf.d/example.conf
%config(noreplace) %{_sysconfdir}/nginx/conf.d/example_ssl.conf
%config(noreplace) %{_sysconfdir}/nginx/conf.d/example.txt
%config(noreplace) %{_sysconfdir}/nginx/mime.types
%config(noreplace) %{_sysconfdir}/nginx/fastcgi_params
%config(noreplace) %{_sysconfdir}/nginx/scgi_params
%config(noreplace) %{_sysconfdir}/nginx/uwsgi_params
%config(noreplace) %{_sysconfdir}/nginx/koi-utf
%config(noreplace) %{_sysconfdir}/nginx/koi-win
%config(noreplace) %{_sysconfdir}/nginx/win-utf
%config(noreplace) %{_sysconfdir}/logrotate.d/nginx
%config(noreplace) %{_sysconfdir}/sysconfig/nginx
%{_initrddir}/nginx
%dir %{_datadir}/nginx
%dir %{_datadir}/nginx/html
%{_datadir}/nginx/html/*
%attr(0755,root,root) %dir %{_localstatedir}/cache/nginx
%attr(0755,root,root) %dir %{_localstatedir}/log/nginx
%files debug

#%attr(权限,属主,属组)

%attr(0755,root,root) %{_sbindir}/nginx.debug

#rpm安装前执行的脚本

%pre
# Add the "nginx" user
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

#rpm安装后执行的脚本

%post

该段内容为安装后脚本程序。它在软件包安装完成之后执行,常用来建立符号连接,修改系统配置文件,运行ldconfig程序等,以利软件的正常运

[ -d "/opt/web/www" ]
[ "$?" != "0" ]  && mkdir -p /opt/web/www
# Register the nginx service
if [ $1 -eq 1 ]; then
    /sbin/chkconfig nginx on
    /sbin/service nginx start
#ngpassword is a tool for nginx to create password
cat >/usr/sbin/ngpassword <<EOF
#!/usr/bin/perl
use strict;
my \$pw=\$ARGV[0] ;
print crypt(\$pw,\$pw)."\n";
EOF
chmod 755 /usr/sbin/ngpassword
fi

#preun  rpm卸载前执行的脚本

%preun

#$1 代表动作

  0代表卸载

  1代表安装

  2代表升级

if [ $1 -eq 0 ]; then
    /sbin/service nginx stop > /dev/null 2>&1
    /sbin/chkconfig --del nginx
fi
#postrun rpm卸载后执行的脚本
%postun
if [ $1 -ge 1 ]; then
    /sbin/service nginx upgrade &>/dev/null || :
fi

#变更日志

%changelog
* Thu Jan 31 2013        change config file<itnihao@qq.com>
- 1.2.6


以上内容见附件

记录一个相关内容http://blog.sina.com.cn/s/blog_5d867af101019b7i.html