1.The RPM system assumes five RPM directories
	BUILD:rpmbuild编译软件的目录 
	RPMS:rpmbuild创建的binary RPM所存放的目录 
	SOURCES:存放源代码的目录 
	SPEC:存放spec文件的目录 
	SRPMS:rpmbuild创建的source RPM所存放的目录 
	2.rpm调试有问题的spec文件的宏
	%dump:打印宏的值 
	%{echo:message} :打印信息到标准错误 
	%{error:message} :打印信息到标准错误,然后返回BADSPEC 
	%{expand:expression} :like eval, expands expression 
	%{F:file_exp} :扩展file_exp到一个文件名 
	%global name value :定义一个全局宏 
	%{P:patch_exp} :扩展patch_exp到一个补丁文件名 
	%{S:source_exp} :扩展source_exp到一个源码文件名 
	%trace :跟踪调试信息 
	%{uncompress:filename} 
	Tests if file filename is compressed. If so, uncompresses and includes 
	in the given context. If not compressed, calls cat to include file in givencontext. 
	%undefine macro :取消给定的宏定义 
	%{warn:message} :打印信息到标准错误 
	3.宏
	%define macro_name  value 
	然后可以用%macro_name或者%{macro_name}来调用,也可以扩展到shell,如 
	%define today %(date) 
	也可以传递参数给宏 
	%define macro_name(option)  value 
	%foo 1 2 3 传递1,2,3三个参数给宏foo 
	在宏扩展的宏参数 
	%0:宏的名字 
	%*:传递给宏的所有参数 
	%#:传递给宏的参数个数 
	%1:第一个参数 
	%2:第二个参数,等等 
	%{-p}:Holds -p 
	%{-p*}:Holds the valuepassed with the -p parameter, if the -p parameter was passed to themacro;otherwise holds nothing 
	%{-p:text}:Holds text if the-p parameter was passed to the macr;otherwise holds nothing 
	%{?macro_to_text:expression}:如果macro_to_text存在,expand expression,如国不存在,则输出为空;也可以逆着用,:%{!?macro_to_text:expression} 
	%{?macro}:忽略表达式只测试该macro是否存在,如果存在就用该宏的值,如果不存在,就不用,如:./configure%{?_with_ldap} 
	%if %{old_5x} 
	%define b5x 1 
	%undefine b6x 
	%endif 
	or 
	%if %{old_5x} 
	%define b5x 1 
	%undefine b6x 
	%else 
	%define b6x 1 
	%undefine b5x 
	%endif 
	还可以用!,&&等符号,如: 
	%if %{old_5x} && %{old_6x} 
	%{error: you cannot build for .5x and .6x at the same time} 
	%quit 
	%endif 
	%ifarch sparc  alpha:判断处理器的结构 
	%ifnoarch i386 alpha:跟%ifarch相反 
	%ifos linux:测试操作系统 
	%ifnos linux:跟%ifos相反 
	4.# This is a comment.
	以#开头的一行为注释,如果在注释里加%会产生错误,如%prep,应该加上两个%,即%%prep 
	5.spec文件的写法:
	Name: myapp   #设置rpm包的名字 
	Version: 1.1.2    #设置rpm包的版本号 
	Release:1        #设置rpm包的修订号 
	Group: System Environment/Shells        #设置rpm包的分类,所有组列在文件/usr/share/doc/rpm-version/GROUP 
	Distribution: Red Hat Linux    #列出这个包属于那个发行版 
	Icon: file.xpm or file.gif        #存储在rpm包中的icon文件 
	Vendor: Company            #指定这个rpm包所属的公司或组织 
	URL: http://www.somesite.com    #公司或组织的主页 
	Packager: sam shen <sxc_1985921@126.com>    #rpm包制作者的名字和email 
	License: LGPL            #包的许可证 
	Copyright: BSD            #包的版权 
	Summary: something descripe the package    #rpm包的简要信息 
	ExcludeArch: sparc s390        #rpm包不能在该系统结构下创建 
	ExclusiveArch: i386 ia64        #rpm包只能在给定的系统结构下创建 
	Excludeos:windows             #rpm包不能在该操作系统下创建 
	Exclusiveos: linux            #rpm包只能在给定的操作系统下创建 
	Buildroot: /tmp/%{name}-%{version}-root    #rpm包最终安装的目录 
	Source0: telnet-client.tar.gz 
	Source1: telnet-xinetd 
	Source2: telnet-wmconfig        #源代码文件,如果只有一个源码目录,可以只写Source:telnet-client.tar.gz 
	Source3: ftp://ftp.somesite.you/pub/name.tar.gz    #用ftp或http命名源码包 
	NoSource:0               #第一个源码不包含在包中 
	Patch1:telnet-client-cvs.patch 
	Patch2:telnetd-0.17.diff 
	Patch3:telnet-0.17-env.patch    #补丁文件 
	NoPatch:0               #第一个补丁文件不包含在包中 
	Requires:packagename        #该包需要给定的packagename包 
	Requires:bash>=2.0        #该包需要包bash,且版本至少为2.0,还有很多比较符号如<,>,<=,>=,= 
	Requires:perl(Carp)>=3.2        #requirementfor the Carp add-on module for Perl 
	PreReq: capability >=version    #capability包必须先安装 
	Conflicts:bash>=2.0           #该包和所有不小于2.0的bash包有冲突 
	BuildRequires: 
	BuildPreReq: 
	BuildConflicts:           
	#这三个选项和上述三个类似,只是他们的依赖性关系在构建包时就要满足,而前三者是在安装包时要满足 
	Autoreq: 0                #禁用自动依赖 
	Prefix: /usr            
	#定义一个relocatable的包,当安装或更新包时,所有在/usr目录下的包都可以映射到其他目录,当定义Prefix时,所有%files标志的文件都要在Prefix定义的目录下 
	%triggerin --package < version   
	#当package包安装或更新时,或本包安装更新且package已经安装时,运行script    
	...script...                    
	%triggerun --package        
	#当package包删除时,或本包删除且package已经安装时,运行script    
	...script...                        
	%triggerpostun --package        
	#当package删除时运行script,本包删除时不运行 
	...script... 
	%triggerpostun -p /usr/bin/perl  --vixie-cron <3.0.1-56 
	               -p/usr/sh package < version 
	              -n subpackage_name –vixie-cron <3.0.1-56 
	...script... 
	in trigger script,$1:the number ofinstances of your package that will remain     after operationhas completed, $2:the number ofinstances of the target package that will remain after the operation ,if $2 is0, the target package will be removed 
	%description: something        #rpm包的描述 
	%prep                #定义准备编译的命令 
	%setup   -c           #在解压之前创建子目录 
	         -q           #在安静模式下且最少输出 
	     -T           #禁用自动化解压包 
	      -n name     #设置子目录名字为name 
	         -D           #在解压之前禁止删除目录 
	         -anumber        #在改变目录后,仅解压给定数字的源码,如-a 0 for source0 
	        -b number       #在改变目录前,仅解压给定数字的源码,如-b 0 forsource0                            
	%patch -p0               #remove no slashes 
	%patch -p1                #remove one slashes 
	%patch               #打补丁0 
	%patch1               #打补丁1 
	%patch2               #打补丁2 
	%patch -P 2          #打补丁2 
	%build               #编译软件 
	./configure  --prefix=$RPM_BUILD_ROOT/usr 
	make     
	or 
	%configure            #可以用rpm –eval '%configure'命令查看该宏 
	make 
	%install              #安装软件 
	make install PREFIX=$RPM_BUILD_ROOT/usr 
	install -m755 myapp $RPM_BUILD_ROOT/usr/bin/myapp 
	or 
	%makeinstall 
	%clean               #清除编译和安装时生成的临时文件 
	rm -rf $RPM_BUILD_ROOT 
	%post                #定义安装之后执行的脚本 
	...script...          
	#rpm命令传递一个参数给这些脚本,1是第一次安装,>=2是升级,0是删除最新版本,用到的变量为$1,$2,$0 
	%preun               #定义卸载软件之前执行的脚本 
	...script... 
	%postun               #定义卸载软件之后执行的脚本 
	...script... 
	%files               #rpm包中要安装的所有文件列表 
	file1                #文件中也可以包含通配符,如* 
	file2 
	directory             #所有文件都放在directory目录下 
	and so on 
	%dir   /etc/xtoolwait    #包含一个空目录/etc/xtoolwait 
	%doc  /usr/X11R6/man/man1/xtoolwait.*    #安装该文档 
	%doc README NEWS            #安装这些文档到/usr/share/doc/ or/usr/doc 
	%docdir                   #定义存放文档的目录 
	%config /etc/yp.conf            #标志该文件是一个配置文件 
	%config(noreplace) /etc/yp.conf       
	 #该配置文件不会覆盖已存在文件(被修改)覆盖已存在文件(没被修改),创建新的文件加上扩展后缀.rpmnew(被修改) 
	%config(missingok)    /etc/yp.conf    #该文件不是必须要的 
	%ghost  /etc/yp.conf           #该文件不应该包含在包中 
	%attr(mode, user, group)  filename    #控制文件的权限如%attr(0644,root,root)/etc/yp.conf,如果你不想指定值,可以用- 
	%config  %attr(-,root,root) filename    #设定文件类型和权限 
	%defattr(-,root,root)            #设置文件的默认权限 
	%lang(en) %{_datadir}/locale/en/LC_MESSAGES/tcsh*    #用特定的语言标志文件 
	%verify(owner group size) filename    #只测试owner,group,size,默认测试所有 
	%verify(not owner) filename        #不测试owner 
	                   #所有的认证如下: 
	                   #group:认证文件的组 
	                   #maj:认证文件的主设备号 
	                   #md5:认证文件的MD5 
	                   #min:认证文件的辅设备号 
	                   #mode:认证文件的权限 
	                   #mtime:认证文件最后修改时间 
	                   #owner:认证文件的所有者 
	                   #size:认证文件的大小 
	                   #symlink:认证符号连接 
	%verifyscript               #check for an entry in a system             
	...script...               #configuration file     
	%changelog 
	* Wen Sep 24 sam shen <sxc_1985921@126.com> 
	- sam updated to 1.3 
	     
	%package sub_package_name   #定义一个子包,名字为package-subpackage 
	       -n sub_package_name  #定义一个子包,名字为sub_package_name 
	当定义一个子包时,必须至少包含Summary:,Group:,%description选项,任何没有指定的选项将用父包的选项,如版本等,如: 
	%package server 
	Requires: xinetd 
	Group: System Environment/Daemons 
	Summary:The server program for the telnet remote login protocol 
	%description server 
	Telnet is a popular protocol for logging into remote systems 
	如果在%package时用-n选项,那么在%description时也要用,如: 
	%description -n my-telnet-server 
	%files server 
	%defattr(-,root,root) 
	%{_sbindir}/in.telnetd 
	如果在%package时用-n选项,那么在%files时也要用,如: 
	%files -n my-telnet-server,也可以定义安装或卸载脚本,像定义%files和%description 一样 
	echo '%debug_package %{nil}' >>~/.rpmmacros避免生成debuginfo 
	  
	6.安装和卸载脚本
	安装和卸载脚本看起来很简单,但它们工作原理中的一些意外可能会引起大问题。 
	这里是一些基本信息。可以将下列四节中的任意一个添加到 .spec 文件, 它列出了在您的包安装期间各个点上运行的 shell 脚本: 
	%pre 
	在安装包之前运行 
	%post 
	在安装包之后运行 
	%preun 
	在卸载包之前运行 
	%postun 
	在卸载包之后运行 
	尤其要注意 %install 与这些节之间的差异。构建 RPM 时, %install 在开发机器上运行; 它应该将产品安装在开发机器上或安装到一个构建根目录中。 另一方面,这些节指定当用户正在安装或卸载您的 RPM 包时将在 用户的机器上运行什么。 
	这里有一个示例,是在前文基础上建立的。我们要使用 install-info 将 GNU indent 的 info 文件添加到目录中。 
	清单 1. indent-4.spec 
	# Simplistic example of install scripts - do not use 
	Summary: GNU indent 
	Name: indent 
	Version: 2.2.6 
	Release: 4 
	Source0: %{name}-%{version}.tar.gz 
	License: GPL 
	Group: Development/Tools 
	BuildRoot: %{_builddir}/%{name}-root 
	%description 
	The GNU indent program reformats C code to any of a variety of 
	formatting standards, or you can define your own. 
	%prep 
	%setup -q 
	%build 
	./configure 
	make 
	%install 
	rm -rf $RPM_BUILD_ROOT 
	make DESTDIR=$RPM_BUILD_ROOT install 
	%post 
	if [ -x /sbin/install-info ]; then 
	  /sbin/install-info /usr/local/info/indent.info /usr/local/info/dir 
	fi 
	%preun 
	if [ -x /sbin/install-info ]; then 
	  /sbin/install-info --delete /usr/local/info/indent.info/usr/local/info/dir 
	fi 
	%clean 
	rm -rf $RPM_BUILD_ROOT 
	%files 
	%defattr(-,root,root) 
	/usr/local/bin/indent 
	%doc /usr/local/info/indent.info 
	%doc %attr(0444,root,root) /usr/local/man/man1/indent.1 
	%doc COPYING AUTHORS README NEWS 
	  
	请注意,在尝试使用 install-info 工具之前,首先对它进行检查。我们不希望只是因为我们不能提供至产品文档的链接而使安装失败。 
	但也有可能在某种情况下您希望安装过程失败。一种好的技术是使用 %pre 脚本来检查安装前提条件,它们比 RPM 可以直接支持的更复杂。 如果不符合前提条件,那么脚本以非零状态退出,而且 RPM 不会继续安装。 
 
 
      (责任编辑:IT) |