Rpm打包入门

来自linux中国网wiki
跳到导航 跳到搜索

rpm打包入门


一、安装 rpmbuild

# for centos6 
yum install rpm-build

// for fedora linux
yum install rpmbuild -y

// for ubuntu
apt-get install rpmbuild

http://my.oschina.net/lj2007331/blog/522306
BUILD:源代码解压以后放的位置
RPMS:制作完成后的rpm包存放目录,为特定平台指定子目录(x86_64)
SOURCES:收集的源文件,源材料,补丁文件等存放位置    
SPECS:存放spec文件,作为制作rpm包的领岗文件,以rpm名.spec
SRPMS:src格式的rpm包位置 ,既然是src格式的包,就没有平台的概念了           
BuiltRoot:假根,使用install临时安装到这个目录,把这个目录当作根来用的,所以在这个目录下的目录文件,才是真正的目录文件。当打包完成后,在清理阶段,这个目录将被删除


[root@rpmbuild SOURCES]#  rpmbuild --showrc | grep topdir 
-14: _builddir	%{_topdir}/BUILD
-14: _buildrootdir	%{_topdir}/BUILDROOT
-14: _rpmdir	%{_topdir}/RPMS
-14: _sourcedir	%{_topdir}/SOURCES
-14: _specdir	%{_topdir}/SPECS
-14: _srcrpmdir	%{_topdir}/SRPMS
-14: _topdir	%{getenv:HOME}/rpmbuild

rpmbuild –showrc显示所有的宏,以下划线开头,一个下划线:定义环境的使用情况,二个下划线:通常定义的是命令,为什么要定义宏,因为不同的系统,命令的存放位置可能不同,所以通过宏的定义找到命令的真正存放位置






二、rpm specification file
spec文件规范
能熟练掌握以上命令以及部分参数含义,管理日常的rpm软件包就不成问题了。然而随着Linux风靡全球,越来越多的开发者喜欢采用RPM格式来发布自己的软件包。那么RPM软件包是怎样制作的呢?对大多数Linux开发工程师来说是比较陌生的。

其实,制作RPM软件包并不是一件复杂的工作,其中的关键在于编写SPEC软件包描述文件。要想制作一个rpm软件包就必须写一个软件包描述文件 (SPEC)。这个文件中包含了软件包的诸多信息,如软件包的名字、版本、类别、说明摘要、创建时要执行什么指令、安装时要执行什么操作、以及软件包所要 包含的文件列表等等。

描述文件说明如下:

(1) 文件头

一般的spec文件头包含以下几个域:

Summary:
用一句话概括该软件包尽量多的信息。

Name:
软件包的名字,最终RPM软件包是用该名字与版本号,释出号及体系号来命名软件包的。

Version:
软件版本号。仅当软件包比以前有较大改变时才增加版本号。

Release:
软件包释出号。一般我们对该软件包做了一些小的补丁的时候就应该把释出号加1。

Vendor:
软件开发者的名字。

Copyright:
软件包所采用的版权规则。具体有:GPL(自由软件),BSD,MIT,Public Domain(公共域),Distributable(贡献),commercial(商业),Share(共享)等,一般的开发都写GPL。

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

Source:
源程序软件包的名字。如 stardict-2.0.tar.gz。

%description:
软件包详细说明,可写在多个行上。

(2)%prep段

这个段是预处理段,通常用来执行一些解开源程序包的命令,为下一步的编译安装作准备。%prep和下面的%build,%install段一样,除 了可以执行RPM所定义的宏命令(以%开头)以外,还可以执行SHELL命令,命令可以有很多行,如我们常写的tar解包命令。

(3)build段

本段是建立段,所要执行的命令为生成软件包服务,如make 命令。

(4)%install段

本段是安装段,其中的命令在安装软件包时将执行,如make install命令。

(5)%files段

本段是文件段,用于定义软件包所包含的文件,分为三类--说明文档(doc),配置文件(config)及执行程序,还可定义文件存取权限,拥有者及组别。

(6)%changelog段

本段是修改日志段。你可以将软件的每次修改记录到这里,保存到发布的软件包中,以便查询之用。每一个修改日志都有这样一种格式:第一行是:* 星期 月 日 年 修改人 电子信箱。其中:星期、月份均用英文形式的前3个字母,用中文会报错。接下来的行写的是修改了什么地方,可写多行。一般以减号开始,便于后续的查阅。

三、源代码打包

将源代码打包,如 stardict-2.0.tar.gz,并将文件放到spec文件Source段所描述的路径下,通常为 SOURCES/目录下

四、rpm打包

rpmbuild -ba ‘spec文件路径’
(rpmbuild常用参数: -bb 只编译二进制rpm包 -bs 只编译源码rpm包 -ba 同时编译二进制和源码rpm包)




#rpm note from book  the development of shftware management platform on linux 

#查看  
[root@localhost ~]# rpm -qpl /root/rpmbuild/RPMS/x86_64/libiconv-1.14-1.x86_64.rpm
/etc/ld.so.conf.d
/etc/ld.so.conf.d/libiconv.conf
/usr/local
/usr/local/bin
/usr/local/bin/iconv
/usr/local/include
/usr/local/include/iconv.h
/usr/local/include/libcharset.h
/usr/local/include/localcharset.h
/usr/local/lib
/usr/local/lib/charset.alias
/usr/local/lib/libcharset.a
/usr/local/lib/libcharset.la
省略

#4 系统服务注册 
 rpm -qpl /root/rpmbuild/RPMS/x86_64/ dkm_nginx-1.8.1-1.1.x86_64.rpm | grep init 


#5 软件依赖检查
[root@localhost ~]# rpm -qp /root/rpmbuild/RPMS/x86_64/libiconv-1.14-1.x86_64.rpm -requires
/bin/sh  
/bin/sh  
/bin/sh  
/bin/sh  
libc.so.6()(64bit)  
libc.so.6(GLIBC_2.2.5)(64bit)  
libcharset.so.1()(64bit)  
libiconv.so.2()(64bit)  
rpmlib(CompressedFileNames) <= 3.0.4-1
rpmlib(FileDigests) <= 4.6.0-1
rpmlib(PayloadFilesHavePrefix) <= 4.0-1
rtld(GNU_HASH)  
rpmlib(PayloadIsXz) <= 5.2-1



RPM实现引子 

[root@localhost SPECS]# rpm -qp /root/dkm_php-5.6.6-2.x86_64.rpm  -scripts
preinstall program: /bin/sh
postinstall scriptlet (using /bin/sh):
# Register the nginx service
if [ $1 -eq 1 ]; then
    /sbin/chkconfig --add php-fpm
fi
preuninstall scriptlet (using /bin/sh):
if [ $1 -eq 0 ]; then
    /sbin/service php-fpm stop > /dev/null 2>&1
    /sbin/chkconfig --del php-fpm
fi
postuninstall program: /bin/sh



rpmbuild -bb  libiconv.spec;rpmbuild -ba  libiconv.spec
-ba                           build source and binary packages from <specfile>
-bb                           build binary package only from <specfile>




Autoreqprov: no

4.Macros(宏)

先说下RPM的宏命令
对于spec文件中未明确定义的宏命令,都继承自/usr/lib/rpm/macros
http://mattshma.github.io/2015/11/04/rpm%E6%89%93%E5%8C%85/

#       Path to top of build area.
%_topdir                %{getenv:HOME}/rpmbuild
%_sourcedir             %{_topdir}/SOURCES

#       The directory where the spec file from a source package will be
#       installed.
%_specdir               %{_topdir}/SPECS

#       The directory where newly built source packages will be written.
%_srcrpmdir             %{_topdir}/SRPMS

#       The directory where buildroots will be created.
%_buildrootdir          %{_topdir}/BUILDROOT

#       Build root path, where %install installs the package during build.
%buildroot              %{_buildrootdir}/%{name}-%{version}-%{release}.%{_arch}


若vim新建的.spec文件不包括默认内容,一般原因可能是当前vim不是系统默认自带的vim,可拷贝/usr/share/vim/vimfiles/template.spec内容到新建的空白spec文件中。


BuildRoot 注意其与BUILD目录的区别。BUILD目录即%{_builddir},编译是在BUILD目录中进行的,当编译完成后,将打包需要的文件从BUILD目录复制到BuildRoot目录,然后在BuildRoot目录进行安装,若设置BuildRoot为/usr/local,可用$RPM_BUILD_ROOT或%{buildroot}访问它,值为rpmbuild/BUILDROOT/usr/local。除了在spec文件中设置BuildRoot外,还可以在rpmrc文件或在rpmbuild命令使用--buildroot来设置BuildRoot。


对于configure,不建议在configure时即指定安装目录:./configure --prefix=$RPM_BUILD_ROOT。因为在install阶段,可能会删除buildroot目录,见%install。



%setup -q  #这个宏的作用静默模式解压并cd

#翻译成可执行脚本 为

cd rpmbuild/BUILD
rm -rf libiconv-1.14 
 gzip -dc /root/rpmbuild/SOURCES/libiconv-1.14.tar.gz | tar -xvvf -
if [ $? -ne 0 ]; then
   exit $?
fi
cd libiconv-1.14  
/root/rpmbuild/BUILD/libiconv-1.14
chown -R root:root .
chmod -R a+rx ,g-w ,o-w . # a+rX ?



-n 选项 
设置源码编译目录的名字 
%setup -n php-%{version}  # 可见 和上面的不太一样


evan@evanpc:~/dkm$ ls   rpmbuild_dkm/rpmbuild4php20161028/BUILD/php-5.6.6/


-c 选项
自动创建build 目录 

等于多了  
mkdir -p libiconv-1.14


-D选项
少了删除目录的过程




-T选项 不进行默认压缩文件的解压

-b选项 进入目录前,解压某个源码 
 eg %setup -b 0 解压第0个源码 

%setup -T -b 0  #结合使用 就只解压一次,不会像上面的解压两次 



-a 选项 进入目录后解压  

一般使用 
%setup -T -b/-a` -c  0 


(2) patch 宏 

%patch2  == $patch -P 2



5.files(文件 )

%defattr用来设置文件权限,格式为%defattr(<文件权限>, <用户>, <用户组>, <目录权限>),如%defattr(-,root,root,-),-表示默认权限。注意不能再用%{buildroot}/usr/local之类的命令引用文件,这会在%{buildroot}/%{buildroot}/usr/local中查找文件。
%attr  指令用来设置文件默认的权限 属主和属组 

(-,root,root)

%dir  /usr/local/data #只会把这个目录打包进入rpm中,而不包含其中的文件 

7.Conditionals (条件)




[root@localhost SPECS]# rpmbuild --showrc | grep topdir  #工作车间目录:_topdir /root/rpmbuild
-14: _builddir	%{_topdir}/BUILD
-14: _buildrootdir	%{_topdir}/BUILDROOT
-14: _rpmdir	%{_topdir}/RPMS
-14: _sourcedir	%{_topdir}/SOURCES
-14: _specdir	%{_topdir}/SPECS
-14: _srcrpmdir	%{_topdir}/SRPMS
-14: _topdir	%{getenv:HOME}/rpmbuild




正式打包

#没这两个命令呀 
首先可使用rpmlint mysql.spec来测试SPEC文件的错误。然后可使用yum-builddep SPECS/mysql.spec来安装依赖。
使用rpmbuild来打包,执行命令:rpmbuild -v -bb --clean SPECS/mysql.spec,打包过程都可以在/var/tmp/rpm-tmp.xxxxx看到,若出错的话,可查看该文件。

打包好后,将rpm文件放在yum服务器上,然后执行createrepo rpm_目录名。编写相关repo文件,并执行yum makecache更新yum源,即可安装相应包。


rpmbuild 打包遇到的问题

解决error: Package already exists: %package debuginfo
在spec中注释掉字段或tag会提示以上错误,不要的字段和tag直接删除掉

我的问题 要直接删除 注释也不行 
#%install

Chapter 3 深入理解和使用YUM 

参考

RPM打包

RPM包rpmbuild SPEC文件深度说明


制作PHP的RPM包教程

rpmbuild on linuxchina

rpm 打包入门举例

RPMBUILD nignx 打包总结


Set Up an RPM Build Environment under CentOS