RPM打包

RPM打包

  • rpmbuild
  • 构建过程
    • 1、默认工作路径
    • 2、准备
    • 3、准备Spec文件
    • 4、编译
    • 5、进行安装测试
    • 6、使用rpmlint工具检查rpm包的合规性
  • patch生成方法
  • Python打包
  • 附: Group
  • 附: gtkglarea的spec文件

rpmbuild

安装rpmdevtools 的同时一同安装上rpmlint(检查包的质量)
yum install rpmdevtools rpmlint

rpmbuild --showrc:显示rpm所有的宏

rpmbuild
-ba 既生成src.rpm又生成二进制rpm
-bs 只生成src的rpm
-bb 只生二进制的rpm
-bp 执行到pre
-bc 执行到 build段
-bi 执行install段
-bl 检测有文件没包含

macros都在这里:/usr/lib/rpm/macros or /usr/share/doc/rpm-[version]/macros
使用的时候:%{}

内置的macro
%{_libdir} /usr/lib
%{_bindir} /usr/bin/
%{_tmppath} /var/tmp
%_usr /usr

查看macro最简单的方法:rpm –eval [macro]

构建过程

1、默认工作路径

rpm从4.5.x版本开始,将rpmbuid的默认工作路径移动到用户家目录下的rpmbuild目录里,即$HOME/rpmbuild,并且推荐用户在制作rpm软件包时尽量不要以root身份进行操作。
关于rpmbuild默认工作路径的确定,通常由在/usr/lib/rpm/macros这个文件里的一个叫做%_topdir的宏变量来定义。
如果用户想更改这个目录名,可以在~/.rpmmacros的隐藏文件,然后在里面重新定义%_topdir,指向一个新的目录名:
%_topdir $HOME/rpmbuild

2、准备

1、准备构建目录(rpm build tree)
$ mkdir -p ~/rpmbuild/{BUILD,BUILDROOT,RPMS,SOURCES,SPECS,SRPMS}
官方网站提示:执行rpmdev-setuptree会在当前用户家目录下的rpmbuild目录(如果该目录不存在也会被自动创建)里自动建立上述目录。

目录名 宏别名 说明
BUILD %_builddir 编译rpm包的临时目录
BUILDROOT %_buildrootdir 编译后生成的软件临时安装目录。最新官网上已经不创建这个目录了!
RPMS %_rpmdir 最终生成的可安装rpm包的所在目录
SOURCES %_sourcedir 所有源代码和补丁文件的存放目录
SPECS %_specdir 存放SPEC文件的目录(重要)
SRPMS %_srcrpmdir 最终的rpm源码格式存放路径(暂时忽略掉,别挂在心上)

2、将所有用于生成rpm包的源代码、shell脚本、配置文件都拷贝到SOURCES目录里,注意通常情况下源码的压缩格式都为*.tar.gz格式
cp main-0.1.tar.gz ~/rpmbuild/SOURCES

3、准备Spec文件

%define nginx_user nginx       #这是我们自定义了一个宏,名字为nginx_user值为nginx,%{nginx_user}引用
    
Name:           main
Version:        0.1
Release:        1%{?dist}        #?表示后面的dist有值就启用,没有值就舍弃
                                 #dist根据系统版本来定义,redhat5是el5,redhat6是el6,Fedora 9就是 .fc9
Summary:        Calculate sin and cos value  #一行写完,不要太长;不要在末尾加句点!!RPM 不喜欢最后有个句点
Group:          System Environment/Daemons   #通过cat  /usr/share/doc/rpm-4.8.0/GROUPS这条命令查看系统上支持的组
License:        GPL
URL:            http://linux.vbird.org
Source0:        main-0.1.tar.gz
Source0:        %{name}-%{version}.tar.gz 
Source1:        index.html 
Source2:        init.nginx 
Source3:        fastcgi_params 
Source4:        nginx.conf 
#patch0:        a.patch                 #如果需要补丁,依次写
BuildRoot:      %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX)  #最好置空。package build的地方,也是从这里install的
#BuildRoot:     %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
 
%description      #一句话不要太长,否则rpmlint 会提示your description is too long;不要在末尾加句点!!RPM 不喜欢最后有个句点
This package will let you input your name and calculate sin and cos value


BuildRequires:gcc gcc-c++ autoconf automake openssl-devel pcre-devel    #编译时依赖的包
Requires:pcre-devel                                                     #安装时依赖的包


%prep        预处理脚本。默认的,这个段落里唯一执行的就是setup宏。
%setup             不加任何选项,仅将软件包打开。把源码包解压并放好。默认从SOURCES里的包解压到BUILD目录下
%setup -q
%setup -n newdir    将软件包解压在newdir目录。从SOURCES里的包解压到BUILD/newdir目录下
%setup -n %{name}-%{version} 把源码包解压并放好 
                     有两种情况:一就是同时编译多个源码包, 二就是源码的tar包的名称与解压出来的目录不一致,需要使用-n参数指定。
%setup -c 解压缩之前先产生目录。 
%setup -b num 将第num个source文件解压缩。 
%setup -T 不使用default的解压缩操作。 
%setup -T -b 0 将第0个源代码文件解压缩。 
%setup -c -n newdir 指定目录名称newdir,并在此目录产生rpm套件。 


#package built in this section。在BUILD/%{name}-%{version}目录中进行make的工作
%build
./configure --prefix=/usr/local 
%configure    #执行源代码的configure配置,在BUILD/%{name}-%{version}目录中进行 ,使用标准写法,会引用/usr/lib/rpm/marcros中定义的参数。
另一种不标准的写法是,可参考源码中的参数自定义,例如:
CFLAGS="$RPM_OPT_FLAGS" CXXFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=%{_prefix}

make                             #执行编译命令,编译后会在BUILD目录下存在暂时文件
make %{?_smp_mflags}             #_smp_mflags:表示系统如果支持多颗cpu,将启用这个功能,提高编译速度
make %{?_smp_mflags} OPTIMIZE="%{optflags}"     都是一些优化参数,定义在/usr/lib/rpm/marcros中             



%install                     
rm -rf %{buildroot}                         #安装之前先要删除里面已有的多余的编译内容
mkdir -p %{buildroot}/usr/local/bin         #将编译完成源代码试安装在~/rpmbuild/BUILDROOT目录下,其中的宏%{buildroot}=~/rpmbuild
make install RPM_INSTALL_ROOT=%{buildroot}  #安装package
make install DESTDIR=%{buildroot}           #最后进行安装
%{__install} -p -D %{SOURCE1} %{buildroot}/usr/html/index.html  #%{__install}这个宏代表install命令
%{__install} -p -D -m 0755 %{SOURCE2} %{buildroot}/etc/rc.d/init.d/nginx 
%{__install} -p -D %{SOURCE3} %{buildroot}/etc/nginx/fastcgi_params 
%{__install} -p -D %{SOURCE4} %{buildroot}/etc/nginx/nginx.conf
# 提高rpmlint的结果,或者无权修改上一版本时,以及给他人解决问题时,都可以打补丁
%patch 打补丁
通常补丁都会一起在源码tar.gz包中,或放到SOURCES目录下。一般参数为:
%patch -p1 使用前面定义的Patch补丁进行,-p1是忽略patch的第一层目录
%Patch2 -p1 -b xxx.patch 打上指定的补丁,-b是指生成备份文件
%patch 最简单的补丁方式,自动指定patch level。 
%patch 0 使用第0个补丁文件,相当于%patch ?p 0。 
%patch -s 不显示打补丁时的信息。 
%patch -T 将所有打补丁时产生的输出文件删除。


%pre:  #rpm安装之前执行的脚本。在install段落之前执行
    if [ $1 == 1 ];then                #$1:表示第一次安装,当等于1为安装,等于0为卸载,等于2为升级
       /usr/sbin/useradd -s /bin/false -r nginx 2>/dev/null ||:    #失败了就打印冒号
    fi

#rpm安装完成之后执行的脚本
%post:
    if [ $1== 1 ];then
       /sbin/chkconfig --add %{name}
    fi

#卸载之前执行的脚本
%preun:
    if [ $1== 0 ];then
        /sbin/service %{name} stop >/dev/null 2>&1
        /sbin/chkconfig --del %{name}
    fi

#卸载完成之后执行的脚本
%postun:

%preun   %postun 的区别:前者在升级的时候会执行,后者在升级rpm包的时候不会执行


#最终在安装生成的rpm软件包时的安装目录。定义那些文件会在make-install执行时安装到电脑中
#可以先留空,先执行package的build,会报错,并且提示你需要在这个段落中声明的文件的列表。。。
%files  
%defattr (-,root,root)      指定包装文件的属性,分别是(mode,owner,group),-表示默认值,对文本文件是0644,可执行文件是0755
%defattr (-,root,root,0755) 
%doc /usr/html/index.html     #%doc表明这个是文档   
%doc docs/LICENSE
%doc docs/README                                 

/etc/ 
/usr/ 
/var/ 
%config(noreplace) /etc/nginx/nginx.conf  #%config表明这是个配置文件noreplace表明不能替换
%config(noreplace) /etc/nginx/fastcgi_params 
%attr(0755,root,root) /etc/rc.d/init.d/nginx     #%attr后面的是权限,属主,属组。设置的是
这里会在虚拟根目录下进行,千万不要写绝对路径,而应用宏或变量表示相对路径。
如果描述为目录,表示目录中除%exclude外的所有文件。

%exclude 列出不想打包到rpm中的文件
※小心,如果%exclude指定的文件不存在,也会出错的。 


%clean                          #build之后,清理buildroot下的安装产物
rm -rf %{buildroot}

%changelog       #每次更新rpm的时候都要修改的
 * Wed Jul 4 2018 VBird Tsai  0.1
 - Build the program

%changelog
*Sun Jul 13 2008  1
--Initial Build.
--Added setup.py file.
--Fixed bin/vpd, src/vpd.py.

可以使用rpmdev-newspec命令创建一个spec文件的样例

$ rpmdev-newspec
Skeleton specfile (minimal) has been created to "newpackage.spec".

rpm最终的文件名称是[name]-[version]-[release].[arch].rpm,其中的[arch]可以自定义修改,noarch代表不挑架构

__rm /bin/rm:两个下划线后接命令,代表的就是当前系统本身的命令

4、编译

输入如下命令,在最后出现exit 0表示生成成功。
rpmbuild -ba main.spec

5、进行安装测试

rpm -ivh ~/rpmbuild/RPMS/x86_64/main-0.1-1.el7.x86_64.rpm #安装main
rpm -ql main #查找main的安装路径
rpm -qi main #查询main相关信息

6、使用rpmlint工具检查rpm包的合规性

最好是没有返回任何信息,就是ok的
$ rpmlint visual-4.beta16-1.fc9.i386.rpm
visual.i386: W: invalid-license Boost Software License - Version 1.0
1 packages and 0 specfiles checked; 0 errors, 1 warnings.

patch生成方法

1、 两个目录分别准备上一版本和修订版本,执行以下命令生产.patch文件

diff -urN [upstream-directory] [revised-diretory] > information.patch

2、将patch文件放入SOURCES目录下。
3、打包时根据spec文件里的patch信息将会生成对应的补丁包

patch文件用法:https://www.cnblogs.com/pengdonglin137/p/3341159.html

Python打包

默认地specfile构建的是C,针对Python打包需要做以下改动
1、spec文件最开始需要添加以下一句

%{!?python_sitelib: %define python_sitelib %(%{__python} -c "from distutils.sysconfig import get_python_lib; print get_python_lib()")}

2、其他基本类似。Spec文件示例:

%prep
%setup -q

%build
%{__python} setup.py build

%install
rm -rf $RPM_BUILD_ROOT
%{__python} setup.py install -O1 --skip-build --root $RPM_BUILD_ROOT    #这里需要告诉distutils不要安装skip-build

%clean
rm -rf $RPM_BUILD_ROOT

附: Group

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

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硬件支持)

附: gtkglarea的spec文件

Name: gtkglarea
Version: 1.2.3
Release: 1%{?dist}
Summary: Gtkglarea is an opengl wigdet for the gtk+ gui toolkit

Group: Development/Libraries
License: GPLv2+
URL: http://www.bradlongo.wordpress.com
Source0: gtkglarea-1.2.3.tar.gz
Patch0:gtkglarea.patch
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)

BuildRequires: gtk+-devel >= 1.2
Requires: gtk+ >= 1.2

%description
Gtkglarea is an opengl widget similar to the GtkDrawingArea.

%package devel
Group: Development/Libraries
Summary: Development files for gtkglarea
Requires: gtkglarea == 1.2.3

%description devel
Development files for gtkglarea.

%post -p /sbin/ldconfig

%prep
%setup -q
%patch0 -p1

%build
%configure
make %{?_smp_mflags}

%install
rm -rf $RPM_BUILD_ROOT
make install DESTDIR=$RPM_BUILD_ROOT
rm -f %{_libdir}/libgtkgl.la
rm -f $RPM_BUILD_ROOT/%{_libdir}/libgtkgl.la
%postun -p /sbin/ldconfig

%clean
rm -rf $RPM_BUILD_ROOT

%files
%defattr(-,root,root,-)
%doc COPYING
%doc README
%doc INSTALL
%doc AUTHORS
%{_libdir}/libgtkgl.so.5
%{_libdir}/libgtkgl.so.5.0.0
%{_datadir}/aclocal/gtkgl.m4
%files devel
%defattr(-,root,root,-)
%doc COPYING
%doc README
%doc INSTALL
%doc AUTHORS
%{_includedir}/gtkgl/gdkgl.h
%{_includedir}/gtkgl/gtkglarea.h
%{_libdir}/libgtkgl.so
%{_libdir}/libgtkgl.a

%changelog
*Sun Jul 13 2008 Brad Longo  1.2.3-1
–Fixed files section
–Deleted zero length file.
–Created patch to get rid of rpmlint errors.

*Thu Jun 26 2008 Brad Longo  1.2.3-1
–Initial Build.

你可能感兴趣的:(Linux)