rpmbuild的原理,意义,在此不介绍了,本文主要是一个思路,具体参考官方文档
http://docs.fedoraproject.org/en-US/Fedora_Draft_Documentation/0.1/html/RPM_Guide/index.html
一,rpmbuild的步骤
-
1.Set up the directory structure
-
2.Place the sources in the right directory
-
3.Create a spec file that tells the rpmbuild command what to do
-
4.Build the source andbinary RPMs
二,rpmbuild各目录的作用
BUILD | The rpmbuild command builds software in this directory |
RPMS | The rpmbuild command stores binary RPMs it reates in this irectory |
SOURCES | You should put the sources for the application in this directory |
SPECS | You should place the spec file for each RPM you plan to make in this directory |
SRPMS | The 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
默认的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
|
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
|
四,实例说明
#定义变量
1
2
3
|
%define nginx_home %{_localstatedir}/cache/nginx
%define nginx_user nginx
%define nginx_group nginx
|
# 软件包的内容概要
1
|
Summary: high performance web server
|
#软件包的名称
1
|
Name: nginx
|
#软件包的版本
1
|
Version: 1.2.6
|
#软件包的发布实际版本号
1
|
Release: 1%{?dist}.ngx
|
#发行商或者打包组织的信息
1
|
Vendor: nginx inc.
|
#软件的主页
URL: http://nginx.org/
#源代码包,可以带多个source0,source1等源,后面可以用%{SOURCE0},%{SOURCE1}引用
1
2
3
4
5
6
7
8
9
|
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
|
#软件授权方式
1
2
|
License: 2-clause BSD-like license
%if 0%{?suse_version}
|
#软件分组
1
2
3
4
|
Group: Productivity/Networking/Web/Servers
%else
Group: System Environment/Daemons
%endif
|
#安装或者编译时使用的“虚拟目录”
1
|
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
|
#需要依赖的软件包
1
2
3
4
5
6
7
8
9
10
11
12
|
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识别
1
|
Provides: webserver
|
#软件的详细说明
1
2
3
4
5
6
7
8
9
10
|
%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 [子包选项]
1
|
%setup -q
|
#此为预处理阶段,其内容为预处理脚本程序,该程序完成以下任务:
1.建立软件编译用目录
2.将源程序解压缩
3.通过打补丁,升级源程序
4.执行其他一些操作,使源程序随时可进行编译
在此脚本程序中,可以使用如下两个宏命令:
%setup
这个宏利用系统中的gzip与tar等命令,来解压源程序包。RPM会自动探测源程序是否压缩,如果压缩,它会用gzip将其解压缩,否则直接使用
tar命令展开包中文件,其格式为
%setup [-n name] [-c] [-D] [-T] [-b N] [-a N]
注意:[]所括为可选项。
(1)当没有任何选项时
这个宏用来解压默认的源程序包(由头文件Source或Source0域指定).注意:源程序包中的文件应用“软件名-版本号”作为其上层目录,这样%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个源程序包
1
|
%patch
|
此宏利用系统中的patch命令,来给指定的源程序包打补丁,从而将程序升级。其使用格式为:
1
|
%patch [-P N] [-p N] [-b name] [-E]
|
注: []所括为可选项
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
(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),则删除这个文件。
|
#开始构建包
1
|
%build
|
1
|
此为编译段,其内容为编译脚本程序。该程序完成源程序的编译和连接。一个最简单的例子就是程序中仅有一个make命令。这适用于大部分情况 ,因为多数软件均有自己的makefile,这样通过make命令就可实现编译与连接。如果没有makefile的话,需要软件包制作者自己在编译段书写上一系列的编译连接命令。
|
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
|
./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
1
|
此为安装段,其内容是安装脚本程序。该程序将已编译连接好的执行程序或其它文件存放到指定目录下,这些程序或文件供RPM打包时使用。一个最简单的例子就是程序中仅用一个make install命令,从而完成安装。这也需要相应的软件有makefile维护文件。没有的话,软件包制作者也得自己写指令。
|
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
|
%{__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
|
1
|
#清理临时文件
|
1
2
|
%clean
%{__rm} -rf $RPM_BUILD_ROOT
|
#定义哪些文件或者目录会放入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
26
|
%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安装前执行的脚本
1
2
3
4
5
6
7
|
%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程序等,以利软件的正常运
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
[ -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代表升级
1
2
3
4
5
6
7
8
9
|
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
|
#变更日志
1
2
3
|
%changelog
* Thu Jan 31 2013 change config file<
itnihao
@qq.com>
- 1.2.6
|