• spec 文件详解


     转自http://blog.sina.com.cn/s/blog_43b39e250100nnu4.html

    rpm软件包系统的标准分组:/usr/share/doc/rpm-4.3.3/GROUPS

    rpmrc配置文件:/usr/lib/rpm/rpmrc  /etc/rpmrc   ~/.rpmrc
    各种宏定义: /usr/lib/rpm/macros  /etc/rpm/macros   ~/.rpmmacros
    已经安装的rpm包数据库: /var/lib/rpm*

    临时文件:/var/tmp/rpm*

    可以通过命令rpm --showrc查看实现代码。另外直接通过rpm --eval "%{macro}"来查看具体对应路径。

    比如我们要查看%{_bindir}的路径,就可以使用命令rpm --eval "%{_bindir}"来查看。

    用以下命令将spec文件取出。
      $rpm -qlp *.src.rpm
      $rpm2cpio *.src.rpm|cpio -ivh *.spec
      首先执行rpm -qlp查询�得知该套件中有几个.spec文件�再执行rpm2cpio将rpm文件转换成cpio文件格式�并将转换结果输出给cpio程序�把source rpm套件中的sepc文件解压取出。

    SPEC脚本引用定义部分

    �fine userpath /var/www/html/demo

    Name:

    软件包的名称,后面可使用%{name}的方式引用
    Summary:

    软件包的内容概要
    Version:

    软件的实际版本号,例如:1.0.1等,后面可使用%{version}引用
    Release:

    发布序列号,例如:1linuxing等,标明第几次打包,后面可使用%{release}引用

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

    License:

    软件授权方式,通常就是GPL
    Source:

    源代码包,可以带多个用Source1、Source2等源,后面也可以用%{source1}、%{source2}引用。

    NoSource:0 #第一个源码不包含在包中


    Patch:

    补丁源码,可使用Patch1、Patch2等标识多个补丁,使用%patch0或%{patch0}引用,

    补丁 ID 规则
    0-9 Makefile、configure 等的补丁
    10-39 指定功能或包含他的文件的补丁
    40-59 配置文件的补丁
    60-79 字体或字符补丁
    80-99 通过 xgettexize 得到的目录情况的补丁
    100- 其他补丁
    NoPatch:0 #第一个补丁文件不包含在包中
    BuildRoot:

    这个是安装或编译时使用的“虚拟目录”,考虑到多用户的环境,一般定义为:%{_tmppath}/%{name}-%{version}-root
    %{_tmppath}/%{name}-%{version}-%{release}-root

    %{_tmppath}/%{name}-%{version}-%{release}-buildroot-%(%{__id_u} -n}
    该参数非常重要,后面可使用$RPM_BUILD_ROOT 方式引用。因为在生成rpm的过程中,执行make install时就会把软件安装到上述的路径中,在打包的时候,同样依赖“虚拟目录”为“根目录”进行操作。

    ※注意区分$RPM_BUILD_ROOT和$RPM_BUILD_DIR:
    $RPM_BUILD_ROOT是指定义的BuildRoot,而$RPM_BUILD_DIR通常就是指/usr/src/asianux/BUILD,其中,前面的才是%file需要的。

    URL:

    软件的主页
    Vendor:

    软件开发者名字,发行商或打包组织的信息,例如RedFlag Co,Ltd
    Distribution:

    发行版标识

    例如Red Hat Linux

    ExcludeArch: sparc s390  #rpm包不能在该系统结构下创建,如果是这个环境,将报错。

    ExclusiveArch: i386 ia64 #rpm包只能在给定的系统结构下创建

    ExcludeOS:windows        #rpm包不能在该操作系统下创建

    ExclusiveOS: linux       #rpm包只能在给定的操作系统下创建

    (

    %ifarch sparc s390  判断处理器的结构

    %ifnoarch i386 alpha 与上边相反

    %ifos  linux        测试操作系统

    %ifnos  linux       与上边相反

    )

    Icon:

    file.xpm or file.gif #存储在rpm包中的icon文件


    Prefix:

    %{_prefix} 这个主要是为了解决今后安装rpm包时,并不一定把软件安装到rpm中打包的目录的情况。这样,必须在这里定义该标识,并在编写%install脚本的时候引用,才能实现rpm安装时重新指定位置的功能
    %{_sysconfdir} 这个原因和上面的一样,但由于%{_prefix}指/usr,而对于其他的文件,例如/etc下的配置文件,则需要用%{_sysconfdir}标识

    Prefix: /usr #定义一个relocatable的包,当安装或更新包时, #所有在/usr目录下的包都可以映射到其他目录,当定义Prefix时,所有%files标志的文件都要在Prefix 定 义的目录下


    BuildArch:

    指编译的目标处理器架构,noarch标识不指定,但通常都是以/usr/lib/rpm/marcros中的内容为默认值

    Obsoletes:

    过时的,废弃的。

    Obsoletes:anaconda-images <= 10

    Provides:

    指明本软件提供一些特定的功能,以便其他rpm识别

    例如:

    Provides: mail-reader
    Requires:

    该rpm包所依赖的软件包名称,可以用>=或<=表示大于或小于某一特定版本,

    ※“>=”号两边需用空格隔开,而不同软件名称也用空格分开

    例如:该包需要 libpng-devel版本至少为 1.0.20,以及zlib
    Requires: libpng-devel >= 1.0.20 zlib

    Requires: bzip2 = %{version}, bzip2-libs = %{version}

    Requires: perl(Carp)>=3.2 需要perl模块Carp
    PreReq、Requires(pre)、Requires(post)、Requires(preun)、Requires(postun)、BuildRequires等都是针对不同阶段的依赖指定
    PreReq: capability >=version      #capability包必须先安装

    Conflicts:bash>=2.0              #该包和所有不小于2.0的bash包有冲突

    以上三者是在安装RPM包时要满足.

    BuildRequires:

    BuildRequires: zlib-devel

    BuildPreReq:

    BuildConflicts:

    这三个选项的依赖性关系在构建RPM包时就要满足

    Autoreq:

    rpm_build时会为包里的二进制文件找出对应的共享库(.so)依赖,打成RPM包后可能在安装时提示缺少依赖并退出,要避免执行find-requires找共享库依赖,可以加上禁用自动依赖Autoreq:no   或者设为0

    Autoprov:

    rpm_build时会为包里的二进制文件找出对应的共享库(.so)依赖,打成RPM包后可能在安装时提示缺少依赖并退出,要避免执行find-provides找共享库依赖,可以加上禁用自动依赖Autoprov:no   或者设为0

    AutoReqProv:no

    rpm_build时会为包里的二进制文件找出对应的共享库(.so)依赖,打成RPM包后可能在安装时提示缺少依赖并退出,要避免执行find-provides与find-requires找共享库依赖,可以加上禁用自动依赖

    Autoprov:no   或者设为0 或者为flase 相当于同时设定上边两个的值Autoreq:和Autoprov:

    上边3个会因为顺序的不同而导致结果会有所不同,一般以最后一个为准。

    %triggerin -- package < version

    执行脚本或者命令

    #当package包安装或更新时,或本包安装更新且 package已经安装时,运行script

    当其所在软件包与指定软件包仅有一方安装时,安装另一方将触发此程序执行。

    %triggerun -- package

    执行脚本或者命令

    #当package包删除时,或本包删除且package已经安装时,运行script

    当其所在软件包与指定软件包都已安装时,卸载任一方将触发此程序执行。

    例如:

    %triggerun -- anaconda < 8.0-1

    ./script

    %triggerpostun -- package

    #当package删除时运行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...

    -p  解释程序

    --  触发条件

    -n  子包的触发条件等

    Packager:

    打包者的信息,姓名以及邮箱等,处于同一行。
    �scription

    软件的详细说明

    上边是关于RPM包信息的一些描述。

    spec脚本主体

    %package

    #定义一个子包

    %package -n sub_package_name #定义一个子包,名字为sub_package_name

    当定义一个子包时,必须至少包含Summary:,Group:,�scription选项,任何没有指定的选项将用父包的选项,如版本等,如:

    %package server

    Requires: xinetd

    Group: System Environment/Daemons

    Summary:The server program for the telnet remote login protocol

    �scription server

    Telnet is a popular protocol for logging into remote systems

    如果在%package时用-n选项,那么在�scription时也要用,如:

    �scription -n my-telnet-server

    如果在%package时用-n选项,那么在%files时也要用,如:

    %files -n my-telnet-server,也可以定义安装或卸载脚本,像定义%files和�scription 一样

    %package devel

    Summary: Header files and libraries for developing apps which will use bzip2.

    Group: Development/Libraries

    Requires: bzip2 = %{version}, bzip2-libs = %{version}

    �scription devel

    Header files and a static library of bzip2 functions, for developing apps

    which will use the library.

    %package libs

    Summary: Libraries for applications using bzip2

    Group: System Environment/Libraries

    �scription libs

    Libraries for applications using the bzip2 compression format.


    %prep

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

    rpm卸载前执行的脚本
    %setup

    把源码包解压并放好
    通常是从/usr/src/asianux/SOURCES里的包解压到/usr/src/asianux/BUILD/%{name}-%{version}中。

    %setup -q %{name}-%{version}
    一般用%setup -q就可以了,但有两种情况:一就是同时编译多个源码包,二就是源码的tar包的名称与解压出来的目录不一致,此时,就需要使用-n参数指定一下了。

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

    %setup -q 在安静模式下且最少输出

    %setup -D #在解压之前禁止删除目录

    %setup -a number #在改变目录后,仅解压给定数字的源码,如-a 0 for source0
    %setup -n newdir 将软件包解压到newdir目录。
    %setup -c 解压缩之前先产生目录。
    %setup -b num 包含多个源文件时,将第num个source文件解压缩。
    %setup -T 不使用default的解压缩操作。
    %setup -T -b 0 将第0个源代码文件SOURCE0解压缩。
    %setup -c -n newdir 指定目录名称newdir,并在此目录产生rpm套件。

    %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 将所有打补丁时产生的输出文件删除。

    %patch #打补丁0

    %patch1 #打补丁1

    %patch2 #打补丁2

    %patch -P 2 #打补丁2

    在%build之前,%prep部分将准备好编译工作,解开源码包,并将相应的补丁打进去。
    %build

    开始编译源码构建包,相当于configure以及make部分

    所要执行的命令为生成软件包服务,如

    %configure 这个不是关键字,而是rpm定义的标准宏命令。意思是执行源代码的configure配置,可以用rpm –eval '%configure'命令查看该宏
    在/usr/src/asianux/BUILD/%{name}-%{version}目录中进行操作 ,使用标准写法,会引用/usr/lib/rpm/marcros中定义的参数。
    另一种不标准的写法是,可参考源码中的参数自定义,例如:

    引用

    CFLAGS="$RPM_OPT_FLAGS" CXXFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=%{_prefix}

    make 命令
    在/usr/src/asianux/BUILD/%{name}-%{version}目录中进行make的工作 ,常见写法:

    make %{?_smp_mflags} OPTIMIZE="%{optflags}"
    都是一些优化参数,定义在/usr/lib/rpm/marcros中

    %check
    %install

    开始把软件安装到虚拟的根目录中,本段是安装段,其中的命令在安装软件包时将执行,如make install命令、cp、mv、install、ln。
    在/usr/src/asianux/BUILD/%{name}-%{version}目录中进行make install的操作。这个很重要,因为如果这里的路径不对的话,则下面%file中寻找文件的时候就会失败。 常见内容有:
    %makeinstall 这不是关键字,而是rpm定义的标准宏命令,相当于执行make install命令那一步。

    也可以使用非标准写法:

    make DESTDIR=$RPM_BUILD_ROOT install

    make prefix=$RPM_BUILD_ROOT install

    make INSTROOT=$RPM_BUILD_ROOT install
    需要说明的是,这里的%install主要就是为了后面的%file服务的。所以,还可以使用常规的系统命令:

    rm -rf ${RPM_BUILD_ROOT}

    mkdir -p $RPM_BUILD_ROOT/{%{_bindir},%{_mandir}/man1,%{_libdir},%{_includedir}}

    install -m 755 bzlib.h $RPM_BUILD_ROOT/%{_includedir}

    install -m 644 bzip2.1 bzdiff.1 bzgrep.1 bzmore.1  $RPM_BUILD_ROOT/%{_mandir}/man1/

    install -d $RPM_BUILD_ROOT/
    cp -a * $RPM_BUILD_ROOT/

    ln -s file/magic  ${RPM_BUILD_ROOT}%{_datadir}/magic

    %find_lang  %{name}

    %files -f  %{name}.lang

    第一句生成一个名为%{name}.lang的文件,内容是所有的%{name}.mo,第二句意思是一个一个列举.mo文件很麻烦,-f参数是将其后边接的文件合并到%files的文件列表。

    %clean

    清除编译和安装时生成的临时文件
    通常内容为:

    [ "$RPM_BUILD_ROOT" != "/" ] && rm -rf "$RPM_BUILD_ROOT"
    rm -rf $RPM_BUILD_DIR/%{name}-%{version}
    %post

    rpm安装后执行的脚本
    %post libs -p /sbin/ldconfig

    libs包时执行这部分动作
    %postun

    rpm卸载后执行的脚本
    %postun libs  -p /sbin/ldconfig

    rpm还提供了一种信号机制:不同的操作会返回不同的信息,并放到默认变量$1中。

    引用

    0代表卸载、1代表安装、2代表升级


    可这样使用:

    引用

    %postun
    if [ "$1" = "0" ]; then
    /sbin/ldconfig
    fi

    %verifyscript #软件包校验脚本程序开始执行

    %files

    �fattr (-,root,root)

    本段是文件段,用于定义构成软件包的文件列表,那些文件或目录会放入rpm中,分为三类-说明文档(doc),配置文件(config)及执行程序,还可定义文件存取权限,拥有者及组别。

    这里会在虚拟根目录下进行,千万不要写绝对路径,而应用宏或变量表示相对路径。

    ※特别需要注意的是:%install部分使用的是绝对路径,而%file部分使用则是相对路径,虽然其描述的是同一个地方。千万不要写错。
    %files  -f %{name}.lang tui

    file1 #文件中也可以包含通配符,如*

    file2

    directory #所有文件都放在directory目录下

    %dir /etc/xtoolwait #仅是一个空目录/etc/xtoolwait打进包里

    %doc  表示这是文档文件,因此如安装时使用--excludedocs将不安装该文件,

    %doc /usr/X11R6/man/man1/xtoolwait.* #安装该文档

    %doc README NEWS #安装这些文档到/usr/share/doc/%{name}-%{version} 或者 /usr/doc或者

    %docdir #定义说明文档的目录,例如/root,在这一语句后,所有以/root开头的行都被定义为说明文件。

    %config /etc/yp.conf #标志该文件是一个配置文件,升级过程中,RPM会有如下动作。

    %config(missisgok) /etc/yp.conf 此配置文件可以丢失,即使丢失了,RPM在卸载软件包时也不认为这是一个错误,并不报错。一般用于那些软件包安装后建立的符号链接文件,如

    /etc/rc.d/rc5.d/S55named文件,此类文件在软件包卸载后可能需要删除,所以丢失了也不要紧。

    %config(noreplace) /etc/yp.conf

    #该配置文件不会覆盖已存在文件(RPM包中文件会以.rpmnew存在于系统,卸载时系统中的该配置文件会以.rpmsave保存下来,如果没有这个选项,安装时RPM包中文件会以.rpmorig存在于系统 )

    覆盖已存在文件(没被修改),创建新的文件加上扩展后缀.rpmnew(被修改)

    %{_bindir}/*

    %config  /etc/aa.conf

    %ghost /etc/yp.conf #该文件不应该包含在包中,一般是日志文件,其文件属性很重要,但是文件内容不重要,用了这个选项后,仅将其文件属性加入包中。

    %attr(mode, user, group) filename #控制文件的权限如%attr(0644,root,root) /etc/yp.conf

    如果你不想指定值,可以用-

    %config %attr(-,root,root) filename #设定文件类型和权限

    �fattr(-,root,root) #设置文件的默认权限,-表示默认值,对文本文件是0644,可执行文件是0755

    %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:认证符号连接

    如果描述为目录,表示目录中出%exclude外的所有文件。

    %files
    �fattr(-,root,root)

    %doc
    %{_bindir}/*
    %{_libdir}/liba*
    %{_datadir}/file

    %{_infodir}/*

    %{_mandir}/man[15]/*

    %{_includedir}
    %exclude %{_libdir}/debug

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

    %files
    �fattr(-,root,root)
    %{_bindir}
    写成

    %files
    �fattr(-,root,root)
    /usr/bin
    则打包的会是根目录下的/usr/bin中所有的文件。

    %files libs

    �fattr(-,root,root)

    %{_libdir}/*so.*

    %files devel

    �fattr(-,root,root)

    %{_includedir}/*

    由于必须在%file中包括所有套件中的文件,所以,我们需要清楚编译完的套件到底包括那些文件,常见的做法是,人工模拟一次编译的过程:

    ./configrue --prefix=/usr/local/xxx
    make
    make DESTDIR=/usr/local/xxx install

    make prefix=/usr/local/xxx install
    这样,整个套件的内容就会被放到/usr/local/xxx中,可根据情况编写%file和%exclude段
    ※当然,这个只能对源码按GNU方式编写,并使用GNU autotool创建的包有效,若自定义Makefile则不能一概而论。
    %changelog

    变更日志,本段是修改日志段。你可以将软件的每次修改记录到这里,保存到发布的软件包中,以便查询之用。每一个修改日志都有这样一种格式:

    第一行是:* 星期月日 年 修改人电子信箱。

    其中:星期、月份均用英文形式的前3个字母,用中文会报错。接下来的行写的是修改了什么地方,可写多行。一般以减号开始,便于后续的查 阅。

    * Mon Mar 31 1997 Erik Troan <ewt@redhat.com>

    - Fixed problems caused by 64 bit time_t.



     

    技巧:

    如果要避免生成debuginfo包:这个是默认会生成的rpm包。则可以使用下面的命令:

    echo '�bug_package %{nil}' >> ~/.rpmmacros
    如果rpm包已经做好,但在安装的时候想修改默认路径,则可以:

    rpm -ivh --prefix=/opt/usr xxx.rpm
    又或者同时修改多个路径:

    rpm xxx.rpm --relocate=/usr=/opt/usr --relocate=/etc=/usr/etc

    所有的宏都可以在/usr/lib/rpm/macros里找到。

    下面是宏对应路径一览表:

    Macros mimicking autoconf variables

    %{_sysconfdir}        /etc

    %{_prefix}            /usr

    %{_exec_prefix}      %{_prefix}

    %{_bindir}           %{_exec_prefix}/bin

    %{_lib}               lib (lib64 on 64bit systems)

    %{_libdir}           %{_exec_prefix}/%{_lib}

    %{_libexecdir}       %{_exec_prefix}/libexec

    %{_sbindir}          %{_exec_prefix}/sbin

    %{_sharedstatedir}    /var/lib

    %{_datadir}          %{_prefix}/share

    %{_includedir}       %{_prefix}/include

    %{_oldincludedir}     /usr/include

    %{_infodir}           /usr/share/info

    %{_mandir}            /usr/share/man

    %{_localstatedir}     /var

    %{_initddir}         %{_sysconfdir}/rc.d/init.d

    Note: On releases older than Fedora 10 (and EPEL),%{_initddir}does not exist. Instead, you should use the deprecated%{_initrddir}macro.

    RPM directory macros

    %{_topdir}           %{getenv:HOME}/rpmbuild

    %{_builddir}         %{_topdir}/BUILD

    %{_rpmdir}           %{_topdir}/RPMS

    %{_sourcedir}        %{_topdir}/SOURCES

    %{_specdir}          %{_topdir}/SPECS

    %{_srcrpmdir}        %{_topdir}/SRPMS

    %{_buildrootdir}     %{_topdir}/BUILDROOT

    Note: On releases older than Fedora 10 (and EPEL),%{_buildrootdir}does not exist.

    Build flags macros

    %{_global_cflags}     -O2 -g -pipe

    %{_optflags}         %{__global_cflags} -m32 -march=i386 -mtune=pentium4 # if redhat-rpm-config is installed

    Other macros

    %{_var}               /var

    %{_tmppath}          %{_var}/tmp

    %{_usr}               /usr

    %{_usrsrc}           %{_usr}/src

    %{_docdir}           %{_datadir}/doc

  • 相关阅读:
    暑假周总结六
    常用的Linux操作
    大数据概述
    实验一
    我对编译原理的看法
    ActiveReports中自定义Winforms的Viewer 工具栏
    ActiveReport 同一单元格内图片跟文字按条件显示
    ActiveReports最终报表设计器本地化方法介绍
    ActiveReports中如何使用Excel数据源
    如何设置WebViewer的参数栏显示状态
  • 原文地址:https://www.cnblogs.com/sunshine-long/p/9809042.html
Copyright © 2020-2023  润新知