> Linux集群 > Ceph >

ceph存储 Linux下rpm制作中spec文件编写规范

1.The RPM system assumes five RPM directories

BUILDrpmbuild编译软件的目录
RPMSrpmbuild创建的binary RPM所存放的目录
SOURCES:存放源代码的目录
SPEC:存放spec文件的目录
SRPMSrpmbuild创建的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    #
ftphttp命名源码包

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.0bash包有冲突
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, $2the 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)