linux rpm包编译过程(spec文件和spec宏 )

spec文件是整个RPM包建立过程的中心,它的作用就如同编译程序时的Makefile文件。spec文件包含建立一个RPM包必需的信息,包括哪些文件是包的一部分以及它们安装在哪个目录下。这个文件一般分为如下的几节:

1,Preamle(序言)

序 言包含用户请求包的信息时所显示的内容。它可以包含包的功能描述、包的软件版本、版权信息和所属的包组等。Summary 是一行关于该软件包的描述,Name 是该软件包的基名,Version 是该软件的版本号,Release 是 RPM 本身的版本号,如果修复了 spec 文件中的一个错误并发布了该软件同一版本的新 RPM,就应该增加发行版号。License 应该给出一些许可术语(如:”GPL”、”Commercial”、”Shareware”),Group 标识软件类型。那些试图帮助人们管理 RPM 的程序通常按照组列出 RPM。您可以在usr/share/doc/rpm-4.0.4/GROUPS 文件看到一个 Red Hat 使用的组列表(假设您安装的 RPM 版本是 4.0.4)。但是您还可以使用那些组名以外的名称。Source0、Source1等等给这些源文件命名(通常为 tar.gz 文件)。%{name} 和 %{version} 是 RPM 宏,它们扩展成为头中定义的 rpm 名称和版本。

要注意的是,不要在 Source 语句中包含任何路径。缺省情况下,RPM 会在 /usr/src/redhat/SOURCES 中(对于Redhat6 系统,则是在 /root/rpmbuild/SOURCES 目录中)寻找文件,请将您的源文件复制或链接到那里。(要使 spec 文件尽量可移植的话,应当尽量避免嵌入自己开发机器上的假想路径。其他开发人员就可以指示 RPM 在别的目录下查找源文件,而不用修改您的 spec 文件。)

接下来的部分从 %description 行开始。您应该在这里提供该软件更多的描述,这样任何人使用 rpm -qi 查询您的软件包时都可以看到它。您可以解释这个软件包做什么,描述任何警告或附加的配置指令,等等。

一个序言的简单例子:

Summary: Utilities for managing accounts and shadow password files.
Name: shadow-utils
Version: 4.0.17
Release: 14%{?dist}

Source0: %{name}-%{version}.tar.bz2
Source1: shadow-4.0.17-login.defs
Source2: shadow-970616.useradd

Patch0: shadow-4.0.17-redhat.patch
Patch1: shadow-4.0.3-noinst.patch
Patch2: shadow-4.0.11.1-vipw.patch

Packager:amoblin  
Group: Application  
URL: http://www.ossxp.com 
License: GPL
BuildRequires: autoconf, automake, libtool, gettext-devel
BuildRequires: libselinux-devel >= 1.25.2-1
BuildRequires: audit-libs-devel >= 1.0.10
Requires: libselinux >= 1.25.2-1

%description
This package includes the necessary programs for XXX.

2,Prep部分

Prep 节进行实际的打包准备工作,它是使用节前缀%prep表示的。主要功能有:
将文件 (SOURCES/) 解压到构建目录 (BUILD/)
应用Patch(打补丁) (SOURCES/ => BUILD/)
描述 “rm -rf $RPM_BUILD_ROOT”
描述或编辑本部分用到的命令到 PreReq:
通过 “-b .XXX” 描述补丁备份

%setup
-n newdir #将压缩的软件源程序在newdir目录下解开。
-c #在解开源程序之前先创建目录。
-b num #在包含多个源程序时,将第num个源程序解压缩。
-T #不使用缺省的解压缩操作。

通常patch补丁都会一起放到SOURCES目录下。一般参数为
%patchN -p1 #应用前面定义的第N个patch,-p1是忽略patch的第一层目录

例如:

%setup -q   #最常用
%setup -q -n newdir    #将source解压至newdir
%setup -T -b 0    #解开第一个源程序文件
%setup -c -n newdir    #创建目录newdir,并在此目录之下解开源程序

%patch1 -p1   #应用第1个补丁

一个Prep部分的小例子:

%prep
%setup -q
%patch0 -p1
%patch1 -p1
%patch2 -p1
%patch3 -p1

cp %{SOURCE3} lib/nscd.c
rm po/*.gmo
rm po/stamp-po

3,Build部分

这一节主要用于编译源码,它是使用节前缀%build表示的。一般用于configure及make的过程。

一个build部分的例子:

%build
%configure --with-selinux  --without-libpam --disable-shared --with-libaudit
make

4,Install部分

这一节主要用于完成实际安装软件必须执行的命令,它是使用节前缀%install表示的。这一节一般是由make install指令构成,但是有时也会包含cp、mv、install等指令。

这一节还能指定在用户安装的系统上,包安装时运行的脚本。这样的脚本称为安装(卸载)脚本。它可以指定包安装前、包安装后、包除去前、包除去后的系统必须运行的外壳程序段。在用户安装的系统上,为了验证一个包是否已经成功安装的验证脚本也可由这一节指定。

一个install节的例子:

%install
rm -rf $RPM_BUILD_ROOT
make install DESTDIR=$RPM_BUILD_ROOT gnulocaledir=$RPM_BUILD_ROOT/%{_datadir}/locale MKINSTALLDIRS=`pwd`/mkinstalldirs
install -d -m 755 $RPM_BUILD_ROOT/etc/default
install -c -m 0644 %{SOURCE1} $RPM_BUILD_ROOT/etc/login.defs
install -c -m 0600 %{SOURCE2} $RPM_BUILD_ROOT/etc/default/useradd

ln -s useradd $RPM_BUILD_ROOT%{_sbindir}/adduser
ln -s %{_mandir}/man8/useradd.8 $RPM_BUILD_ROOT/%{_mandir}/man8/adduser.8
for subdir in $RPM_BUILD_ROOT/%{_mandir}/{??,??_??,??_??.*}/man* ; do
        test -d $subdir && test -e $subdir/useradd.8 && echo ".so man8/useradd.8" > $subdir/adduser.8
done

# Remove binaries we don't use.
rm $RPM_BUILD_ROOT/%{_bindir}/chfn
rm $RPM_BUILD_ROOT/%{_bindir}/chsh

5,Clean部分

这一节所描述的内容表示在完成包建立的工作之后,自动执行此节下的脚本进行附加的清除工作,它是使用节前缀%clean表示的。一般而言,这一节的内容是简单地使用rm -rf $RPM_BUILD_ROOT命令,不需要指定此节的其它内容。

一个clean部分的例子:

%clean
rm -rf $RPM_BUILD_ROOT

6,文件列表

这一节指定构成包的文件的列表,它是使用节前缀%files表示的。此外,它还包含一系列宏控制安装后的文件属性和配置信息。

%files 列出应该捆绑到 RPM 中的文件,并能够可选地设置许可权和其它信息。在 %files 中,您可以使用 %defattr 来定义缺省的许可权、所有者和组;%defattr(-,root,root) 会安装 root 用户拥有的所有文件,使用当 RPM 从构建系统捆绑它们时它们所具有的任何许可权。

可以用 %attr(permissions,user,group) 覆盖个别文件的所有者和许可权。可以在 %files 中用一行包括多个文件。可以通过在行中添加 %doc 或 %config 来标记文件。%doc 告诉 RPM 这是一个文档文件,因此如果用户安装软件包时使用 –excludedocs,将不安装该文件。您也可以在 %doc 下不带路径列出文件名,RPM 会在构建目录下查找这些文件并在 RPM 文件中包括它们,并把它们安装到 /usr/share/doc/%{name}-%{version}。以 %doc 的形式包括 README 和 ChangeLog 这样的文件是个好主意。

%config 告诉 RPM 这是一个配置文件。在升级时,RPM 将会试图避免用 RPM 打包的缺省配置文件覆盖用户仔细修改过的配置。

注意:如果在 %files 下列出一个目录名,RPM 会包括该目录下的所有文件。通常这不是您想要的,特别对于 /bin 这样的目录。

一个file部分的例子:

%files
%defattr(-,root,root)      #指定默认权限
%doc NEWS doc/HOWTO README
%dir /etc/default
%attr(0644,root,root)   %config(noreplace) /etc/login.defs
%attr(0600,root,root)   %config /etc/default/useradd
%{_bindir}/sg
%{_bindir}/chage
%{_bindir}/faillog
%{_bindir}/gpasswd
%{_bindir}/lastlog
%{_bindir}/newgrp
%{_sbindir}/adduser
%attr(0750,root,root)   %{_sbindir}/user*
%attr(0750,root,root)   %{_sbindir}/group*
%{_sbindir}/grpck
%{_sbindir}/pwck
%{_sbindir}/*conv
%{_sbindir}/chpasswd
%{_sbindir}/newusers

7,改动日志

这一节主要描述软件的开发记录,它是使用节前缀%changlog表示的。这个段的内容是为了开发人员能详细的了解该软件的开发过程,对于包的维护极有好处。

所有宏都可以在/usr/lib/rpm/macros找到,附录一些常见的宏:

%{_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 
%{_topdir}            %{getenv:HOME}/rpmbuild
%{_builddir}          %{_topdir}/BUILD
%{_rpmdir}            %{_topdir}/RPMS
%{_sourcedir}         %{_topdir}/SOURCES
%{_specdir}           %{_topdir}/SPECS
%{_srcrpmdir}         %{_topdir}/SRPMS
%{_buildrootdir}      %{_topdir}/BUILDROOT
%{_var}               /var
%{_tmppath}           %{_var}/tmp
%{_usr}               /usr
%{_usrsrc}            %{_usr}/src
%{_docdir}            %{_datadir}/doc

==================================================

一个简单的spce文件示例:

Summary:    hello world rpm package  
Name:       hello  
Version:    0.1  
Release:    1  

License:    GPL
Source:    %{name}-%{version}.tar.gz
Packager:   amoblin  
Group:      Application  
URL:        http://www.ossxp.com    

%description

%prep  
%setup -q    

%build  

%install
mkdir -p $RPM_BUILD_ROOT/%{_bindir}
gcc -o hello hello.c
install -c -m 755 hello $RPM_BUILD_ROOT/%{_bindir}

%files  
%{_bindir}/hello

%clean
rm -rf $RPM_BUILD_ROOT

发表评论

电子邮件地址不会被公开。