简单制作RPM二进包实例


有好多朋友问到怎么制作rpm包,可不可把其它服务器上编译好的软件目录复杂到其它服务器上直接应用等等。这里通过案例由简单到高级来一一讲解。


此方法是通过编写spec文件,使用rpmbuild来完成一个rpm的打包。


分别以libmad、nginx、apache为例进行介绍


制作平台:CentOS 6.x X86_64

实施思路:1、准备必须的软件。

          2、建立rpmbuild目录结构,将源码包放入指定目录。

 3、在指定的目录中编写*.spec配置文件。

 4、根据*.spec配置文件生成rpm软件包。


四步走:

准备工作:安装软件

安装rpm制作工作:yum -y install gcc  gcc-c++  rpm* rpm-build  rpmdev*

安装nginx依赖的包:yum install -y  openssl openssl-devel  pcre  pcre-devel  zlib  zlib-devel


第一步:建立目录结构

centos 6.x目录:mkdir -pv ~/rpmbuild/{BUILD,RPMS,SOURCES,SPECS,SRPMS}


相关目录介绍:

--查看rpmbuild环境参数:rpmbuild  --showrc | grep  _topdir

~/rpmbuild/SOURCES    #存放源代码、补丁等文件 

~/rpmbuild/SPECS      #存放用于管理rpm制作进程的spec文件 

~/rpmbuild/BUILD      #解压后的文件存放目录 

~/rpmbuild/RPMS       #存放由rpmbuild制作好的二进制包 

~/rpmbuild/SRPMS      #存放由rpmbuild制作好的源码包 


修改rpmbuild环境参数:用下面的命令生成rpmbuild所需要的宏文件,这个文件里包含的是.spec中要引用的相对路径。文件里的内容可以手动配置和编写,格式符合要求即可。

echo '%_topdir  %(echo $HOME)/rpmbuild' > ~/.rpmmacros


##需求:创建libmad-0.15.1b.tar.gz源码包的rpm软件包。(已测试OK金)

第一步:建立目录结构

centos 6.x目录:mkdir -pv ~/rpmbuild/{BUILD,RPMS,SOURCES,SPECS,SRPMS}


第二步:把源码包放在SOURCES目录下

cd  ~/rpmbuild/SOURCES

wget  http://downloads.sourceforge.net/mad/libmad-0.15.1b.tar.gz


第三步:生成nginx.spec文件

cd  ~/rpmbuild/SPECS 

rpmdev-newspec -o libmad-0.15.1b.spec     //生成模板文件

vi   libmad-0.15.1b.spec     //修改模板文件的完整代码

#以下依次为软件名、版本号、系统版本、功能描述。

Name:           libmad

Version:        0.15.1b

Release:        1%{?dist}

Summary:        This is a free MP3 Codec.


#以下依次是分组信息、协议、软件网址、软件包名变量、制作的根目录环境。

Group:          System Environment/Libraries

License:        GPL

URL:            http://downloads.net/libmad.tar.gz

Source0:        %{name}-%{version}.tar.gz

BuildRoot:      %{_topdir}/BUILDROOT


#必备的软件包、依赖的软件包。

BuildRequires:  gcc,gcc-c++

Requires:       gcc,gcc-c++


#软件的基本描述信息。

%description


#软件包说明

%package        devel

Summary:        Development files for %{name}

Group:          Development/Libraries

Requires:       %{name}-%{version}-%{release}


#软件devel开发的描述信息

%description    devel

The %{name}-devel package contains libraries and header files for

developing applications that use %{name}.


#安装或者升级软件前要做的事情,比如停止服务、备份相关文件等都在这里做。

%prep

%setup -q


#编译阶段的参数设置

%build

sed -i '/-fforce-mem/d' configure

%configure --enable-shared

make %{?_smp_mflags}


#安装阶段的参数设置。

%install

rm -rf $RPM_BUILD_ROOT

make install DESTDIR=$RPM_BUILD_ROOT


#清除阶段的参数设置。

%clean

rm -rf $RPM_BUILD_ROOT


#文件和目录参数设置。

%files

%defattr(-,root,root,-)

%doc

%{_libdir}/*

%{_includedir}/*


#

%changelog

*  Thu Dec 01 2016 flyer <[email protected]> - libmad-0.15.1b.1.el6

- Initial version


第四步:生成rpm软件包。

rpmbuild  -bb   libmad-0.15.1b.spec    //生成rpm软件包,需要待编译安装过程。

ls  /root/rpmbuild/RPMS/x86_64/    //查看生成的rpm软件包。


第五步:测试rpm软件包的安装和查询。

安装:rpm -ivh /root/rpmbuild/RPMS/x86_64/libmad-0.15.1b-1.el6.x86_64.rpm

查是否已安装:rpm  -q  libmad

查文件:rpm  -ql  libmad

卸载:rpm  -e  libmad

------------------------------------

##以下是关于*.spec文件格式解释:

Name: test

Version:

Requires:

%description

#==================================SPEC头部====================================

%prep

%setup -q

%patch <==== 在这里打包

%build

%configure

make %{?_smp_mflags}

%install

rm -rf $RPM_BUILD_ROOT

make install DESTDIR=$RPM_BUILD_ROOT

%clean

rm -rf $RPM_BUILD_ROOT

%files

%defattr(-,root,root,-)

要打包到rpm包里的文件清单

%doc

%changelog

#==================================SPEC主体====================================

%pre

安装或者升级软件前要做的事情,比如停止服务、备份相关文件等都在这里做。

%post

安装或者升级完成后要做的事情,比如执行ldconfig重构动态库缓存、启动服务等。

%preun

卸载软件前要做的事情,比如停止相关服务、关闭进程等。

%postun

卸载软件之后要做的事情,比如删除备份、配置文件等。


-------------------------------------------

#需求:将nginx-1.2.0.tar.gz生成一个基础版本的rpm包。

说明:此版本的rpm包安装后,并无service启动脚本,需要手工创建。需要手工启动nginx服务。


准备工作:

安装rpm制作工作:yum -y install gcc  gcc-c++  rpm* rpm-build  rpmdev*

安装nginx依赖的包:yum install -y  openssl openssl-devel  pcre  pcre-devel  zlib  zlib-devel


第一步:建立目录结构

centos 6.x目录:mkdir -pv ~/rpmbuild/{BUILD,RPMS,SOURCES,SPECS,SRPMS}


第二步:把源码包放在SOURCES目录下

useradd  -r  nginx

cd  ~/rpmbuild/SOURCES

wget http://nginx.org/download/nginx-1.2.0.tar.gz

 

第三步:生成nginx.spec文件

cd  ~/rpmbuild/SPECS 

rpmdev-newspec -o nginx-1.2.0.spec

vi  nginx-1.2.0.spec   //内容如下(测试OK金,直接复制代码)

Name:   nginx

Version:    1.2.0

Release:    1%{?dist}

Summary:    nginx_install


Group:  System Environment/Daemons 

License:    GPLv2

URL:    http://nginx.org/download

Source0:    %{name}-%{version}.tar.gz

Source1:    nginx_init

Source2:    nginx.conf

BuildRoot:  %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX)


BuildRequires:  gcc,gcc-c++,pcre-devel,zlib-devel,make,openssl-devel

Requires:   pcre-devel,zlib-devel,openssl-devel

#软件包详述

%description

Build nginx-1.2.0.tar.gz to nginx-1.2.0.rpm

#构建包前的处理

%prep

#静默模式解压并cd

%setup -q


#生成:这里主要是构建二进制包的的时候执行编译生成二进制文件

%build export DESTDIR=%{buildroot}

./configure --user=nginx \

--group=nginx \

--prefix=/usr/local/nginx \

--sbin-path=/usr/sbin/nginx \

--conf-path=/etc/nginx/nginx.conf \

--error-log-path=/var/log/nginx/error.log \

--http-log-path=/var/log/nginx/access.log \

--pid-path=/var/run/nginx/nginx.pid  \

--lock-path=/var/lock/nginx.lock \

--with-http_ssl_module \

--with-http_flv_module \

--with-http_stub_status_module \

--with-http_gzip_static_module \

--http-client-body-temp-path=/var/tmp/nginx/client/ \

--http-proxy-temp-path=/var/tmp/nginx/proxy/ \

--http-fastcgi-temp-path=/var/tmp/nginx/fcgi/ \

--http-uwsgi-temp-path=/var/tmp/nginx/uwsgi \

--http-scgi-temp-path=/var/tmp/nginx/scgi \

--with-pcre 


# 多处理器的话,可以加 -j 参数

make %{?_smp_mflags}


#构建的时候把当前文件安装到系统目录$RPM_BUILD_ROOT/下,二进制安装的时候是安装文件到/根目录下    

%install

rm -rf %{buildroot}

make install DESTDIR=%{buildroot}

#%%{__install}这个宏代表install命令

#%%{__install} -p -D -m 0755 %{SOURCE1} %{buildroot}/etc/rc.d/init.d/nginx

#%%{__install} -p -D %{SOURCE2} %{buildroot}/etc/nginx/nginx.conf


#rpm安装前执行的脚本

#$1有3个值,代表动作,安装类型,处理类型 1:表示安装 2:表示升级 0:表示卸载

%pre

if [ $1 == 1 ];then

      /usr/sbin/useradd  -r nginx 2> /dev/null

fi


#rpm安装后执行的脚本

%post

if [ $1 == 1 ];then

    #/sbin/chkconfig --add nginx

    echo  -e  '#!/bin/sh\nPATH=$PATH:/usr/local/nginx/bin' > /etc/profile.d/nginx.sh

    source  /etc/profile.d/nginx.sh

    /sbin/install-info %{_infodir}/%{name}.info %{_infodir}/dir 2> /dev/null || :

    mkdir -p /var/log/nginx/  /var/tmp/nginx/client/

    touch /var/log/nginx/error.log /var/log/nginx/access.log

    mkdir -p /var/run/nginx/

    touch /var/run/nginx/nginx.pid

fi


#rpm卸载前执行的脚本

%preun

if [ $1 == 0 ];then

    nginx  -s  stop  &>  /dev/null

    /usr/sbin/groupdel nginx 2> /dev/null

    /usr/sbin/userdel -r nginx 2> /dev/null

    #/sbin/chkconfig --del nginx 2> /dev/null

    /usr/local/nginx/bin/nginx  -s stop > /dev/null 2>&1

    /sbin/install-info --delete %{_infodir}/%{name}.info %{_infodir}/dir 2> /dev/null || :

fi

#rpm卸载后执行的脚本

%postun

#清理段,clean的主要作用就是删除BUILD

%clean

rm -rf %{buildroot}

#文件列表段,这个阶段是把前面已经编译好的内容要打包了,其中exclude是指要排除什么不打包进来

%files

#%%defattr (-,root,root) 指定包装文件的属性,分别是(mode,owner,group),-表示默认值,对文本文件是0644,可执行文件是0755

%defattr(-,root,root,-)

/etc/nginx/

#/usr/html/index.html

#/usr/html/50x.html

/usr/local/nginx/html/50x.html

/usr/local/nginx/html/index.html

/usr/sbin/nginx

%doc


#变更日志

%changelog

*  Thu Dec 01 2016 flyer <[email protected]> -nginx-1.2.0-1.el6

- Initial version


第四步:RPM包制作

首先系统要安装好必备的制作工具:gcc、rpmbuild等

yum -y install gcc rpm-build rpmdev*  rpm* 

cd ~/rpmbuild/SPECS/ 

rpmbuild  -bb  nginx-1.2.0.spec 

通过上面这条命令,会在~/rpmbuild/RPMS/x86_64/下面生成nginx-1.2.0-1.el6.x86_64.rpm这个文件

 

-bb 这个选项就是制作二进制包(build binary package only from


第五步:用rpm安装nginx测试。

安装:rpm -ivh /root/rpmbuild/RPMS/x86_64/nginx-1.2.0-1.el6.x86_64.rpm

查询:rpm  -q  nginx


启动服务:nginx

停止服务:nginx  -s  stop

测试访问:curl  127.0.0.1

查看端口:lsof  -i:80  或  netstart  -tunlp|grep  :80  或  ss  -tunlp|grep  :80


对spec文件内容进行简单说明:

spec文件是制作rpm包的核心!

以#开头的是注释信息; 

Summary:对相关软件进行简单描述说明 

Name:定义rpm包的名称。例:nginx-1.2.0.tar.gz名称用nginx 

Version:定义软件的版本号。例: nginx-1.2.0.tar.gz版本用1.2.0

Release:发行版本。例:rhel6.5则用11.el6。 

License:定义许可证

Group:说明软件属于哪种应用类型 

Source:软件×××地址 

URL:软件相关官方站点 

Distribution: 发行版系列 

Packager: 制作人的简单信息 

  

%description:软件详细描述信息 

%prep:软件编译之前的处理 

%build:编译软件

%pre:安装时处理

%install:安装软件

%post:安装后处理

%preun:定义卸载之前的动作 

%files:指定要打包的软件包,这里是/usr/local/nginx

 

对于更详细的说明请参考官方资料:http://www.rpm.org/max-rpm/ch-rpm-inside.html

 

下面是apache的spec文件实例:

yum  remove  -y  httpd

cd  ~/rpmbuild/SPECS 

rpmdev-newspec  -o  httpd-2.2.22.spec

vi   httpd-2.2.22.spec    //参考代码如下(测试OK金,httpd-2.2.22.tar.gz源码包可直接复制下面的代码,100%成功生成rpm包):

Name:           httpd

Version:        2.2.22

Release:        1%{?dist}

Summary:       this is a web server httpd


Group:          app/server

License:        GPL

URL:            http://www.apache.org

Source0:        %{name}-%{version}.tar.gz


BuildRequires:  gcc,gcc-c++,apr,apr-util,pcre,pcre-devel,openssl,openssl-devel,zlib,zlib-devel

Requires:       gcc,gcc-c++,apr,apr-util,pcre,pcre-devel,openssl,openssl-devel,zlib,zlib-devel


#description是指定软件的描述信息。

%description

httpd is apache  web soft.


#prep是软件编译之前的处理,setup -q是静默解压tar包,并cd进入解压后的目录。

%prep

%setup -q


#build是指定编译时要执行的命令。

%build

./configure --prefix=/usr/local/apache2  --sysconfdir=/etc/apache2/conf --enable-so --enable-deflate --enable-headers --enable-mods-shared=all --enable-rewrite

make %{?_smp_mflags}


#install是指定安装时要执行的命令。

%install

rm -rf $RPM_BUILD_ROOT

make install DESTDIR=$RPM_BUILD_ROOT


#pre是指安装前执行命令,$ 1是参数,值为1时是安装,值为0时是卸载,值为2时是升级安装。

%pre

if [ $1 == 1 ];then

   useradd  -r  apache

fi


#preun是指卸载时要执行的命令。

%preun

if [ $1 == 0 ];then

        /usr/sbin/userdel -r  apache  2> /dev/null

rm  -rf  /etc/apache2  /usr/local/apache2

fi


#post是指定安装后执行的命令。

%post

if [ $1 == 1 ];then

        echo -e '#!/bin/sh\nPATH=$PATH:/usr/local/apache2/bin' > /etc/profile.d/apache.sh

        source  /etc/profile.d/apache.sh

        cp -pv  /usr/local/apache2/bin/apachectl  /etc/init.d/apache

        sed  -i  '2a\#chkconfig: - 83 15' /etc/init.d/apache

        /sbin/chkconfig --add apache

        /sbin/chkconfig  apache  on

sed  -i  's/^#ServerName/ServerName/'  /etc/apache2/conf/httpd.conf

fi


#clean是清除垃圾文件。

%clean

rm -rf $RPM_BUILD_ROOT


#files是指定安装时要创建的目录及权限。

%files

/usr/local/apache2

/etc/apache2/conf

%defattr(-,root,root,-)

%doc


%changelog

*  Thu Dec 01 2016 flyer <[email protected]> - httpd-2.2.22-3.el6.x86_64

- Initial version


第四步:RPM包制作

首先系统要安装好必备的制作工具:gcc、rpmbuild等

yum -y install gcc rpm-build rpmdev*  rpm* 

cd ~/rpmbuild/SPECS/ 

rpmbuild  -bb  httpd-2.2.22.spec 

通过上面这条命令,会在~/rpmbuild/RPMS/x86_64/下面生成httpd-2.2.22-1.el6.x86_64.rpm这个文件

 

-bb 这个选项就是制作二进制包(build binary package only from


第五步:用rpm安装nginx测试。

安装:rpm -ivh /root/rpmbuild/RPMS/x86_64/httpd-2.2.22-1.el6.x86_64.rpm

查询:rpm  -q  nginx


启动服务:nginx

测试访问:curl  127.0.0.1

查看端口:lsof  -i:80  或  netstart  -tunlp|grep  :80  或  ss  -tunlp|grep  :80

--------------------------------

以下是有错误的代码,需要修复

# spec file for apache 

# Build 2017-07-17 

# By flyer 

Summary:    High stability web server 

Name:       httpd 

Version:    2.2.22

Release:    3.el6

License:    2-clause BSD-like license 

Group:      Applications/Server 

Source: http://apache.etoak.com/httpd/httpd-2.2.22.tar.gz 

URL: http://apache.org 

Distribution: Centos/Redhat 

Packager: flyer <[email protected]

  

%description 

Apache is a first web server 

%prep 

%setup -q


%build

./configure --prefix=/usr/local/apache2  --sysconfdir=/etc/apache2/conf --enable-so --enable-deflate --enable-headers --enable-mods-shared=all --enable-rewrite

make %{?_smp_mflags}


%install

rm -rf $RPM_BUILD_ROOT

make install DESTDIR=$RPM_BUILD_ROOT


%pre

echo  "PATH=$PATH:/usr/local/apache2/bin" > /etc/profile.d/apache.sh

source  /etc/profile.d/apache.sh

if [ $1 == 1 ];then

        /usr/sbin/useradd -r apache 2> /dev/null

fi           

#id  apache &> /dev/null  && echo 'nginx user ok' ||  /usr/sbin/useradd -r apache &> /dev/null


%preun 

if [ -z "`ps aux | grep httpd | grep -v grep`" ];then 

pkill httpd >/dev/null 

fi 

if [ $1 == 0 ];then

        /usr/sbin/userdel -r apache2 2> /dev/null

fi


%post

echo  'ServerName  www.example.com:80'  >> /etc/apache2/conf/httpd.conf

cp  -pv  /usr/local/apache2/bin/apachectl  /etc/init.d/apache

sed  -i  '2a\#chkconfig: - 83  15'  /etc/init.d/apache

chkconfig  apache  on

chkconfig  apache  --list


%clean

#rm -rf $RPM_BUILD_ROOT


%files

/usr/local/apache2

%defattr(-,root,root,-)

%doc


%changelog

*  Thu Dec 01 2016 flyer <[email protected]> - httpd-2.2.22-3.el6.x86_64

- Initial version

 以后对于相同或类似平台可以到其它服务器上进行rpm安装部署。


另外还有一种rpm打包的方法:rpm_create

这是一种新的打rpm的工具,不用spec语言,只需要会简单的shell命令,即可完成打包操作,非常方便,结合了spec语言和checkinstall,相比spec方法要简单很多!

 

官方站点:http://code.google.com/p/rpmcreate/

下载站点:wget http://rpmcreate.googlecode.com/files/rpm_create-1.7.5-9.x86_64.rpm

大家可以去官方站点参考!


--------------------------------------

--------------------------------------

#需求:将nginx-1.2.0.tar.gz生成一个高级完整优化版本的rpm包。(已测试OK金)

说明:此版本的rpm包安装后,会自动生成service启动脚本,能正常启动。

第一步:建立目录结构

centos 6.x目录:mkdir -pv ~/rpmbuild/{BUILD,RPMS,SOURCES,SPECS,SRPMS}


第二步:把源码包放在SOURCES目录下

cd  ~/rpmbuild/SOURCES

wget http://nginx.org/download/nginx-1.2.0.tar.gz


第2.2步:创建fastcgi配置文件

#cd  ~/rpmbuild/SOURCES

#vi  fastcgi_params   //配置代码如下

fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;

fastcgi_param  SERVER_SOFTWARE    nginx;

fastcgi_param  QUERY_STRING       $query_string;

fastcgi_param  REQUEST_METHOD     $request_method;

fastcgi_param  CONTENT_TYPE       $content_type;

fastcgi_param  CONTENT_LENGTH     $content_length;

fastcgi_param  SCRIPT_FILENAME    $document_root$fastcgi_script_name;

fastcgi_param  SCRIPT_NAME        $fastcgi_script_name;

fastcgi_param  REQUEST_URI        $request_uri;

fastcgi_param  DOCUMENT_URI       $document_uri;

fastcgi_param  DOCUMENT_ROOT      $document_root;

fastcgi_param  SERVER_PROTOCOL    $server_protocol;

fastcgi_param  REMOTE_ADDR        $remote_addr;

fastcgi_param  REMOTE_PORT        $remote_port;

fastcgi_param  SERVER_ADDR        $server_addr;

fastcgi_param  SERVER_PORT        $server_port;

fastcgi_param  SERVER_NAME        $server_name;


第2.3步:创建init.nginx启动脚本

cd  ~/rpmbuild/SOURCES

vi  init.nginx   //启动脚本代码如下:

#!/bin/sh

#

# nginx - this script starts and stops the nginx daemon

#

# chkconfig:   - 85 15

# description:  Nginx is an HTTP(S) server, HTTP(S) reverse \

#               proxy and IMAP/POP3 proxy server

# processname: nginx

## config:      /etc/nginx/nginx.conf

# config:      /usr/local/nginx/conf/nginx.conf

# config:      /etc/sysconfig/nginx

## pidfile:     /var/run/nginx/nginx.pid

# pidfile:     /usr/local/nginx/logs/nginx.pid

# Source function library.

. /etc/rc.d/init.d/functions

# Source networking configuration.

. /etc/sysconfig/network

# Check that networking is up.

[ "$NETWORKING" = "no" ] && exit 0

nginx="/usr/local/nginx/sbin/nginx"

prog=$(basename $nginx)

#NGINX_CONF_FILE="/etc/nginx/nginx.conf"

NGINX_CONF_FILE="/usr/local/nginx/conf/nginx.conf"

[ -f /etc/sysconfig/nginx ] && . /etc/sysconfig/nginx

lockfile=/var/lock/subsys/nginx

make_dirs() {

   # make required directories

   user=`nginx -V 2>&1 | grep "configure arguments:" | sed 's/[^*]*--user=\([^ ]*\).*/\1/g' -`

   options=`$nginx -V 2>&1 | grep 'configure arguments:'`

   for opt in $options; do

       if [ `echo $opt | grep '.*-temp-path'` ]; then

           value=`echo $opt | cut -d "=" -f 2`

           if [ ! -d "$value" ]; then

               # echo "creating" $value

               mkdir -p $value && chown -R $user $value

           fi

       fi

   done

}

start() {

    [ -x $nginx ] || exit 5

    [ -f $NGINX_CONF_FILE ] || exit 6

    make_dirs

    echo -n $"Starting $prog: "

    daemon $nginx -c $NGINX_CONF_FILE

    retval=$?

    echo

    [ $retval -eq 0 ] && touch $lockfile

    return $retval

}

stop() {

    echo -n $"Stopping $prog: "

    killproc $prog -QUIT

    retval=$?

    echo

    [ $retval -eq 0 ] && rm -f $lockfile

    return $retval

}

restart() {

    configtest || return $?

    stop

    sleep 1

    start

}

reload() {

    configtest || return $?

    echo -n $"Reloading $prog: "

    killproc $nginx -HUP

    RETVAL=$?

    echo

}

force_reload() {

    restart

}

configtest() {

  $nginx -t -c $NGINX_CONF_FILE

}

rh_status() {

    status $prog

}

rh_status_q() {

    rh_status >/dev/null 2>&1

}

case "$1" in

    start)

        rh_status_q && exit 0

        $1

        ;;

    stop)

        rh_status_q || exit 0

        $1

        ;;

    restart|configtest)

        $1

        ;;

    reload)

        rh_status_q || exit 7

        $1

        ;;

    force-reload)

        force_reload

        ;;

    status)

        rh_status

        ;;

    condrestart|try-restart)

        rh_status_q || exit 0

            ;;

    *)

        echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload|configtest}"

        exit 2

esac

##脚本init.nginx编写完毕,继续下一步。


第三步:生成nginx.spec文件。

cd  ~/rpmbuild/SPECS 

rpmdev-newspec -o nginx-1.2.0.spec

vi nginx-1.2.0.spec   //内容如下

### 1.The introduction section

#以下依次为软件名、版本号、系统版本、功能描述。用rpm  -qi  nginx查看。

Name: nginx

Version: 1.2.0

Release: 3%{?dist}

Summary: nginx-1.2.0.tar.gz to nginx-1.2.0.rpm


#以下依次是分组信息、协议、软件网址、软件包名变量、制作的根目录环境。

Group: Applications/Archiving

License: GPLv2

URL: http://rshare.ys168.com/

Packager: flyer <[email protected]>

Vendor: flyer make

Source0: %{name}-%{version}.tar.gz

Source1: init.nginx

Source2: nginx.conf

Source3: fastcgi_params

BuildRoot: %_topdir/BUILDROOT


#必备的软件包、依赖的软件包。

BuildRequires: gcc,gcc-c++

Requires: openssl,openssl-devel,pcre-devel,pcre,zlib,zlib-devel


#软件的描述信息。

%description

Custom a rpm by yourself!Build nginx-1.2.0.tar.gz to nginx-1.2.0.rpm


###  2.The Prep section 准备阶段,主要就是把源码包解压到build目录下,设置一下环境变量,并cd进去

%prep

# 这个宏的作用静默模式解压并cd进入目录。

%setup -q


###  3.The Build Section 编译制作阶段,这一节主要用于编译源码

#生成配置、编译、安装,nginx不允许直接用%  configure进行编译安装,否则会报错。

%build

./configure \

--prefix=/usr/local/nginx \

--user=nginx \

--group=nginx \

--with-http_ssl_module \

--with-http_flv_module \

--with-http_stub_status_module \

--with-http_gzip_static_module \

--http-client-body-temp-path=/var/tmp/nginx/client/ \

--http-proxy-temp-path=/var/tmp/nginx/proxy/ \

--http-fastcgi-temp-path=/var/tmp/nginx/fcgi/ \

--http-uwsgi-temp-path=/var/tmp/nginx/uwsgi \

--http-scgi-temp-path=/var/tmp/nginx/scgi \

--with-pcre

make %{?_smp_mflags}


###  4.Install section  这一节主要用于完成实际安装软件必须执行的命令,可包含4种类型脚本


%install

rm -rf %{buildroot}

make install DESTDIR=%{buildroot}

%{__install} -p -D -m 0755 %{SOURCE1} %{buildroot}/etc/rc.d/init.d/nginx

%{__install} -p -D %{SOURCE3} %{buildroot}/usr/local/nginx/conf/fastcgi_params

#%{__install} -p -D %{SOURCE2} %{buildroot}/usr/local/nginx/conf/nginx.conf


# 下面的$1有3个值,代表动作. 1:表示安装。2:表示升级。0:表示卸载。

%pre

mkdir  -pv  /var/tmp/nginx/client

if [ $1 == 1 ];then

        /usr/sbin/useradd -r nginx 2> /dev/null

fi           

#id  nginx &> /dev/null  && echo 'nginx user ok' ||  /usr/sbin/useradd -r nginx &> /dev/null


#安装之后要执行的命令。

%post

if [ $1 == 1 ];then

        /sbin/chkconfig --add %{name}

        /sbin/chkconfig %{name} on

        echo '

net.ipv4.tcp_max_syn_backlog = 65536

net.core.netdev_max_backlog =  32768

net.core.somaxconn = 32768


net.core.wmem_default = 8388608

net.core.rmem_default = 8388608

net.core.rmem_max = 16777216

net.core.wmem_max = 16777216


net.ipv4.tcp_timestamps = 0

net.ipv4.tcp_synack_retries = 2

net.ipv4.tcp_syn_retries = 2


net.ipv4.tcp_tw_recycle = 1

net.ipv4.tcp_tw_reuse = 1


net.ipv4.tcp_mem = 94500000 915000000927000000

net.ipv4.tcp_max_orphans = 3276800


#net.ipv4.tcp_fin_timeout = 30

#net.ipv4.tcp_keepalive_time = 120

net.ipv4.ip_local_port_range = 1024  65535' > /etc/sysctl.conf

sysctl -p 2>&1 /dev/null

fi


#卸载软件前要做的事情,比如停止相关服务、关闭进程等。

%preun

if [ $1 == 0 ];then

        /etc/init.d/nginx stop > /dev/null 2>&1

        /usr/sbin/userdel -r nginx 2> /dev/null

fi

%postun


###  5.clean section 清理段,clean的主要作用就是删除BUILD

#清除垃圾文件。

%clean

rm -rf %{buildroot}


###  6.file section 文件列表段,这个阶段是把前面已经编译好的内容要打包了,其中exclude是指要排除什么不打包进来。

#文件权限设置。

%files

%defattr(-,root,root,0755)

/usr/local/nginx/

/usr/local/nginx/conf/nginx.conf

%attr(0755,root,root) /etc/rc.d/init.d/nginx

%config(noreplace) /usr/local/nginx/conf/fastcgi_params

#%config(noreplace) /usr/local/nginx/conf/nginx.conf


###  7.chagelog section  日志改变段, 这一段主要描述软件的开发记录.

%changelog

*  Thu Dec 01 2016 flyer <[email protected]> - nginx-1.2.0-3.el6.x86_64

- Initial version


第四步:RPM包制作

首先系统要安装好必备的制作工具:gcc、rpmbuild等

yum -y install gcc rpm-build rpmdev*  rpm* 

cd ~/rpmbuild/SPECS/ 

rpmbuild -bb nginx.spec 

通过上面这条命令,会在~/rpmbuild/RPMS/x86_64/下面生成nginx-1.2.0-1.el6.x86_64.rpm这个文件


###附加功能学习:

一、分段执行制作rpm包

rpmbuild -bp nginx.spec 制作到%prep段

rpmbuild -bc nginx.spec 制作到%build段

rpmbuild -bi nginx.spec 执行 spec 文件的 "%install" 阶段 (在执行了 %prep 和 %build 阶段之后)。这通常等价于执行了一次 "make install"

rpmbuild -bb nginx.spec 制作二进制包

rpmbuild -ba nginx.spec 表示既制作二进制包又制作src格式包


二、rpm包的签名

1、查询软件包信息

[root@localhost ~]# rpm -qi nginx

Name        : nginx                        Relocations: (not relocatable)

Version     : 1.7.7                             Vendor: nmshuishui

Release     : 3.el6                         Build Date: Wed 26 Nov 2014 06:39:00 PM CST

Install Date: Wed 26 Nov 2014 06:42:19 PM CST      Build Host: localhost

Group       : Applications/Archiving        Source RPM: nginx-1.7.7-3.el6.src.rpm

Size        : 793593                           License: GPLv2

Signature   : (none)    # rpm包未签名状态

Packager    : nmshuishui <[email protected]>

URL         : http://nmshuishui.blog.51cto.com/

Summary     : nginx-1.7.7.tar.gz to nginx-1.7.7.rpm

Description :

Custom a rpm by yourself!Build nginx-1.7.7.tar.gz to nginx-1.7.7.rpm


2、使用gpg方式生成签名密钥

[root@localhost ~]# gpg --gen-key

Your selection?1  #默认即可

What keysize do you want? (2048) 1024  #选择密钥长度

Key is valid for? (0) 1y  #有效期

Is this correct? (y/N) y  #确认

Real name: nmshuishui  #密钥名称

Email address: [email protected]  #邮件

Comment: GPG-RPM-KEY  #备注

Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O #okay确认

Enter passphrase  OK  #按Enter输入密码                    

#确认使用此密码

#####

在生成密钥的时候,会报这么一个信息:can't connect to `/root/.gnupg/S.gpg-agent': No such file or directory,可以不用理会它。

接下来就是一些随机数的说明了:We need to generate a lot of random bytes. It is a good idea to perform

some other action (type on the keyboard, move the mouse, utilize the

disks) during the prime generation; this gives the random number

generator a better chance to gain enough entropy.

就狂敲键盘和移动鼠标吧,也可以链接一个伪随机数(不过不安全),接下来的活儿就是等了

生成密钥后会是这样的:

gpg: checking the trustdb

gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model

gpg: depth: 0  valid:   1  signed:   0  trust: 0-, 0q, 0n, 0m, 0f, 1u

pub   2048R/DF63EDFB 2014-11-26

      Key fingerprint = 338D 476F 29C9 E2D6 6604  1D96 6F73 1E81 DF63 EDFB

uid                  nmshuishui (gen-key) <[email protected]>

sub   2048R/263FB359 2014-11-26


3、查看生成的密钥

[root@localhost ~]# gpg --list-keys

/root/.gnupg/pubring.gpg

------------------------

pub   2048R/DF63EDFB 2014-11-26

uid                  nmshuishui (gen-key) <[email protected]>

sub   2048R/263FB359 2014-11-26


4、导出公钥以供验证

[root@localhost ~]# gpg --export -a "nmshuishui" > RPM-GPG-KEY-nmshuishui


5、在~/.rpmmacros宏中定义加密密钥

[root@localhost ~]# vim ~/.rpmmacros

%_gpg_name nmshuishui


6、为rpm包签名

[root@localhost ~]# rpm --addsign /home/hero/rpmbuild/RPMS/x86_64/nginx-1.7.7-3.el6.x86_64.rpm 

Enter pass phrase: 

Pass phrase is good.

/home/hero/rpmbuild/RPMS/x86_64/nginx-1.7.7-3.el6.x86_64.rpm:


7、将公钥导入rpm包

[root@localhost ~]# rpm --import RPM-GPG-KEY-nmshuishui


8、验证

[root@localhost ~]# rpm --checksig /home/hero/rpmbuild/RPMS/x86_64/nginx-1.7.7-3.el6.x86_64.rpm

/home/hero/rpmbuild/RPMS/x86_64/nginx-1.7.7-3.el6.x86_64.rpm: rsa sha1 (md5) pgp md5 OK


9、重新安装nginx,验证安装包的签名信息

[root@localhost ~]# rpm -ivh /home/hero/rpmbuild/RPMS/x86_64/nginx-1.7.7-3.el6.x86_64.rpm 

Preparing...                ########################################### [100%]

   1:nginx                  ########################################### [100%]

[root@localhost ~]# 

[root@localhost ~]# rpm -qi nginx

Name        : nginx                        Relocations: (not relocatable)

Version     : 1.7.7                             Vendor: nmshuishui

Release     : 3.el6                         Build Date: Wed 26 Nov 2014 06:39:00 PM CST

Install Date: Thu 27 Nov 2014 10:58:44 AM CST      Build Host: localhost

Group       : Applications/Archiving        Source RPM: nginx-1.7.7-3.el6.src.rpm

Size        : 793593                           License: GPLv2

Signature   : RSA/SHA1, Thu 27 Nov 2014 10:40:02 AM CST, Key ID 6f731e81df63edfb   # 与 1 比起来,多了签名信息

Packager    : nmshuishui <[email protected]>

URL         : http://nmshuishui.blog.51cto.com/

Summary     : nginx-1.7.7.tar.gz to nginx-1.7.7.rpm

Description :

Custom a rpm by yourself!Build nginx-1.7.7.tar.gz to nginx-1.7.7.rpm


##到这里,一个完整的 rpm 包就制作完成了!

--------------------------------------

--------------------------------------

说明:以下内容只用于学习参数,不用分享到笔记文档中。文件中有些错误未修复,不能正常使用。

系统环境:CentOS release 6.5

目标:用软件的tar源码包生成rpm软件包。


准备工作:安装软件

安装rpm制作工作:yum -y install gcc rpm-build pcre-devel 

安装nginx依赖的包:yum install -y openssl-devel  pcre  pcre-devel  zlib


第一步:建立目录结构

centos 6.x目录:mkdir -pv ~/rpmbuild/{BUILD,RPMS,SOURCES,SPECS,SRPMS}


相关目录介绍:

~/rpmbuild/SOURCES    #存放源代码、补丁等文件 

~/rpmbuild/SPECS      #存放用于管理rpm制作进程的spec文件 

~/rpmbuild/BUILD      #解压后的文件存放目录 

~/rpmbuild/RPMS       #存放由rpmbuild制作好的二进制包 

~/rpmbuild/SRPMS      #存放由rpmbuild制作好的源码包 


用下面的命令生成rpmbuild所需要的宏文件,这个文件里包含的是.spec中要引用的相对路径。文件里的内容可以手动配置和编写,格式符合要求即可。

echo '%_topdir %(echo $HOME)/rpmbuild' > ~/.rpmmacros

-------------------------------

##需求1:制作asterisk的rpm软件包。

第一步:建立目录结构

centos 6.x目录:mkdir -pv ~/rpmbuild/{BUILD,RPMS,SOURCES,SPECS,SRPMS,BUILDROOT}


第二步:把源码包放在SOURCES目录下

cd  ~/rpmbuild/SOURCES

wget http://nginx.org/download/nginx-1.2.0.tar.gz


第三步:创建制作rpm包配置文件。

# vim ~/rpmbuild/SPECS/nginx.spec    //代码内容如下:

Name:          nginx

Version:       1.2.0

Release:        1%{?dist}

Summary:        Design by flyer

Group:          Applications/Internet

License:        GPL

URL:            rshare.ys168.com

Source0:        nginx-1.2.0.tar.gz

BuildRoot: %_topdir/rpmbuild 


%description

Design by flyer

%prep

cd $RPM_BUILD_DIR

tar xzvf ../SOURCES/nginx-1.2.0.tar.gz

%build

cd $RPM_BUILD_DIR/nginx-1.2.0

./configure  --prefix=/usr/local/nginxt

make

%install

cd $RPM_BUILD_DIR/nginx-1.2.0

make install

%{_install} -p -D -m 0755 %{_buildrootdir}/%{name}-%{version}-%{release}.x86_64

#%{_install} -p -D -m 0755 %{SOURCE1} %{buildroot}/etc/rc.d/init.d/nginx

%files

/usr/local/nginxt

%clean

rm -rf $RPM_BUILD_DIR/nginx-1.2.0


第四步:生成rpm包:

cd  ~/rpmbuild/SPECS/

rpmbuild  -bb  nginx.spec


-------------------------------

##需求2:制作nginx的rpm软件包。

第一步:建立目录结构

centos 6.x目录:mkdir -pv ~/rpmbuild/{BUILD,RPMS,SOURCES,SPECS,SRPMS}


第二步:把源码包放在SOURCES目录下

cd  ~/rpmbuild/SOURCES

wget http://nginx.org/download/nginx-1.2.0.tar.gz

 

# rpmdev-setuptree

查看所有的宏


# rpmbuild –showrc

目录结构

--BUILD #编译之前,如解压包后存放的路径

--BUILDROOT #编译后存放的路径

--RPMS #打包完成后rpm包存放的路径

--SOURCES #源包所放置的路径

--SPECS #spec文档放置的路径

--SPRMS #源码rpm包放置的路径自动配置命令创建一个RPM构建根目录结构,并配置一些必要操作。


rpmbuild命令的用法:


从spec文档建立有以下选项:

-bp  #只执行spec的%pre 段(解开源码包并打补丁,即只做准备)

-bc  #执行spec的%pre和%build 段(准备并编译)

-bi  #执行spec中%pre,%build与%install(准备,编译并安装)

-bl  #检查spec中的%file段(查看文件是否齐全)

-ba  #建立源码与二进制包(常用)

-bb  #只建立二进制包(常用)

-bs  #只建立源码包


从tarball包建立,与spec类似


-tp #对应-bp

-tc #对应-bc

-ti #对应-bi

-ta #对应-ba

-tb #对应-bb

-ts #对应-bs


从源码包建立


--rebuild  #建立二进制包,通-bb

--recompile  #同-bi

* rpmbuild的其他参数

--buildroot=DIRECTORY   #确定以root目录建立包

--clean  #完成打包后清除BUILD下的文件目录

--nobuild  #不进行%build的阶段

--nodeps  #不检查建立包时的关联文件

--nodirtokens

--rmsource  #完成打包后清除SOURCES

--rmspec #完成打包后清除SPEC

--short-cricuit

--target=CPU-VENDOR-OS #确定包的最终使用平台


软件包所属类别,具体类别有:


# less /usr/share/doc/rpm-4.8.0/GROUPS

Amusements/Games (娱乐/游戏)

Amusements/Graphics(娱乐/图形)

Applications/Archiving (应用/文档)

Applications/Communications(应用/通讯)

Applications/Databases (应用/数据库)

Applications/Editors (应用/编辑器)

Applications/Emulators (应用/仿真器)

Applications/Engineering (应用/工程)

Applications/File (应用/文件)

Applications/Internet (应用/因特网)

Applications/Multimedia(应用/多媒体)

Applications/Productivity (应用/产品)

Applications/Publishing(应用/印刷)

Applications/System(应用/系统)

Applications/Text (应用/文本)

Development/Debuggers (开发/调试器)

Development/Languages (开发/语言)

Development/Libraries (开发/函数库)

Development/System (开发/系统)

Development/Tools (开发/工具)

Documentation (文档)

System Environment/Base(系统环境/基础)

System Environment/Daemons (系统环境/守护)

System Environment/Kernel (系统环境/内核)

System Environment/Libraries (系统环境/函数库)

System Environment/Shells (系统环境/接口)

User Interface/Desktops(用户界面/桌面)

User Interface/X (用户界面/X窗口)

User Interface/X Hardware Support (用户界面/X硬件支持)


其他


make %{?_smp_mflags} 

它就自动将软件安装时的路径自动设置成如下约定: 

可执行程序/usr/bin 

依赖的动态库/usr/lib或者/usr/lib64视操作系统版本而定。 

二次开发的头文件/usr/include 

文档及手册/usr/share/man


%setup 不加任何选项,仅将软件包打开。 

%setup -n newdir 将软件包解压在newdir目录。 

%setup -c 解压缩之前先产生目录。 

%setup -b num 将第num个source文件解压缩。 

%setup -T 不使用default的解压缩操作。 

%setup -T -b 0 将第0个源代码文件解压缩。 

%setup -c -n newdir 指定目录名称newdir,并在此目录产生rpm套件。 

%patch 最简单的补丁方式,自动指定patch level。 

%patch 0 使用第0个补丁文件,相当于%patch ?p 0。 

%patch -s 不显示打补丁时的信息。 

%patch -T 将所有打补丁时产生的输出文件删除。


/sbin/install-info –delete %{_infodir}/%{name}.info %{_infodir}/dir 2> /dev/null || : 

These two scriptlets tell install-info to add entries for the info pages to the main index file on installation and remove them at erase time. The “|| :” in this case prevents failures that would typically affect systems that have been configured not to install any %doc files, or have read-only mounted, %_netsharedpath /usr/share.


Nginx rpm


# vim ~/rpmbuild/SPECS/nginx.spec    //代码内容如下:

#警告请将每行后面的#中文说明删掉,否则会语法错误,导致无法执行。

Name:   nginx   # 软件包名称

Version:    1.2.0   # 版本号,(不能使用-)

Release:    1%{?dist}   # release号,对应下面的changelog,如 nginx-1.2.0-1.el6.x86_64.rpm

Summary:    nginx_install   # 简要描述信息


Group:  System Environment/Daemons 

License:    GPLv2

URL:    http://nginx.org/download

Source0:    %{name}-%{version}.tar.gz   # source主要是引用一下自己定义好的脚本,配置文件之类的内容

Source1:    nginx-init

Source2:    nginx.conf

BuildRoot:  %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX)


BuildRequires:  gcc,gcc-c++,pcre-devel,zlib-devel,make,openssl-devel

#可选装的包gd-devel

Requires:   pcre-devel,zlib-devel,openssl-devel

#可选装的包gd-devel

#软件包详述

%description

Build nginx-1.2.0.tar.gz to nginx-1.2.0.rpm

#构建包前的处理

%prep

#静默模式解压并cd

%setup -q

#生成:这里主要是构建二进制包的的时候执行编译生成二进制文件

%build export DESTDIR=%{buildroot}

./configure --user=nginx --group=nginx \

--prefix=/usr/local/nginx \

--sbin-path=/usr/sbin/nginx \

--conf-path=/etc/nginx/nginx.conf \

--error-log-path=/var/log/nginx/error.log \

--http-log-path=/var/log/nginx/access.log \

--pid-path=/var/run/nginx/nginx.pid  \

--lock-path=/var/lock/nginx.lock \

--with-http_ssl_module \

--with-http_flv_module \

--with-http_stub_status_module \

--with-http_gzip_static_module \

--http-client-body-temp-path=/var/tmp/nginx/client/ \

--http-proxy-temp-path=/var/tmp/nginx/proxy/

#其他可选项:

#--with-pcre --with-http_p_w_picpath_filter_module

#--http-fastcgi-temp-path=/var/tmp/nginx/fcgi/

#--http-uwsgi-temp-path=/var/tmp/nginx/uwsgi

#--http-scgi-temp-path=/var/tmp/nginx/scgi

#--with-file-aio

# 多处理器的话,可以加 -j 参数

make %{?_smp_mflags}

#构建的时候把当前文件安装到系统目录$RPM_BUILD_ROOT/下,二进制安装的时候是安装文件到/根目录下    

%install

rm -rf %{buildroot}

make install DESTDIR=%{buildroot}

#%{__install}这个宏代表install命令

%{__install} -p -D -m 0755 %{SOURCE1} %{buildroot}/etc/rc.d/init.d/nginx

%{__install} -p -D %{SOURCE2} %{buildroot}/etc/nginx/nginx.conf

#rpm安装前执行的脚本

#$1有3个值,代表动作,安装类型,处理类型 1:表示安装 2:表示升级 0:表示卸载

%pre

if [ $1 == 1 ];then

    /usr/sbin/groupadd nginx 2> /dev/null

    /usr/sbin/useradd -g nginx -M -s /sbin/nologin nginx 2> /dev/null

fi

#rpm安装后执行的脚本

%post

if [ $1 == 1 ];then

    /sbin/chkconfig --add nginx

    /sbin/install-info %{_infodir}/%{name}.info %{_infodir}/dir 2> /dev/null || :

    mkdir -p /var/log/nginx/

    touch /var/log/nginx/error.log /var/log/nginx/access.log

    mkdir -p /var/run/nginx/

    touch /var/run/nginx/nginx.pid

fi

#rpm卸载前执行的脚本

%preun

if [ $1 == 0 ];then

    /usr/sbin/groupdel nginx 2> /dev/null

    /usr/sbin/userdel -r nginx 2> /dev/null

    /sbin/chkconfig --del nginx 2> /dev/null

    /etc/init.d/nginx stop > /dev/null 2>&1

    /sbin/install-info --delete %{_infodir}/%{name}.info %{_infodir}/dir 2> /dev/null || :

fi

#rpm卸载后执行的脚本

%postun

#清理段,clean的主要作用就是删除BUILD

%clean

rm -rf %{buildroot}

#文件列表段,这个阶段是把前面已经编译好的内容要打包了,其中exclude是指要排除什么不打包进来

%files

#%%defattr (-,root,root) 指定包装文件的属性,分别是(mode,owner,group),-表示默认值,对文本文件是0644,可执行文件是0755

%defattr(-,root,root,-)

/etc/nginx/

%attr(0755,root,root) /etc/rc.d/init.d/nginx

%config(noreplace) /etc/nginx/nginx.conf

#/usr/html/index.html

#/usr/html/50x.html

/usr/local/nginx/html/50x.html

/usr/local/nginx/html/index.html

/usr/sbin/nginx

%doc

#变更日志

%changelog

*  Thu Dec 01 2016 tian - 1.2.0-1.el6

- Initial version