编译目录组成介绍

rpm-build 包和  /usr/src/redhat ,这些 rpm build 的程序是要靠 spec 文件的控制。它是配置指定安装到另外的机器上的,用来指示转换的源码补丁编译成二进制文件的包。默认编译操作是在下面的目录中,它是编译源码的相关动作操作的位置。
如果不指定其它的地方,那么 rpm building 的地方是主要在 /usr/src/redhat 的目录,目录的架构如下,这就是为 rpm-build 提供的目录结构.

/usr/src/redhat/          
          |-- BUILD          
          |-- RPMS          
          |   |-- i386          
          |   `-- ...          
          |-- SOURCES          
          |   |-- foo-1.2.tar.gz          
          |   |-- foo-1.2-add_feature.patch          
          |   `-- foo-1.2-change_default.patch          
          |-- SPECS          
          |   `-- foo.spec          
          `-- SRPMS



文件的提取,编译都将在 BUILD 的目录,运行后结果的包会在 RPMS 和 RPMS 目录.

RPM 的宏命令

宏(Macros)是使用变量和功能来控制rpm和 rpmbuild 的自定义的行为,宏指令一般地定义在 spec 文件中。语法象 %define macro value .宏指定也可以事先在配置文件中调整。
就是下面的文件。

  • 默认设置为 /usr/lib/rpm/macros or /etc/rpm/macros
  • 用户设置 ~/.rpmmacros

在打包的过程中,spec files 和 rpmbuild 能使用RPM 的宏命令中的变量.
此外,在 rpmbuild 时要不顾当前设置,可以在后面加上 –define=’macro value’ 选项,要显示当前的宏指令可以使用 rpm –eval %{macro} ,也可以rpm –showrc 来 dump 全部当前的宏指令和设置。

你没有必要使用所有的宏指令,也能容易的管理 rpm 的 spec 文件。一个好的建议是,不要编译包使用 root 用户.你能创建一个 ${HOME}/.rpmmacro 文件,然后设置 %_topdir ,非 root 用户能就能不使用 /usr/src/redhat 架构的目录在系统上。另外还有一个好处,就是安装  SRPMs 时,会安装到 %_topdir 目录.宏指令象 %_rpmdir, %_specdir 可以更加细的控制 rpm 在编译过程中的目录.

宏指令有时指定在使用命令时,%configure 宏运行源码在 .configure 脚本在运行源码给合适的你的机器架构信息。 %makeinstall 宏指令通过使用 GNU Automake 传送合适的选项。

宏指令的目录是参考本地的相关信息, %_tmppath 是编译时的临时的目录,默认设置的是 /var/tmp. 其它的宏指令如 %_perfix 是设置目录象 %configure 宠中和 –prefix 的选项.默认是 /usr.这个 %_perfix 选项也会影响到其它使用这个目录的变量,如 %_bindir 它是设置的 %{_prefix}/bin 为默认的. 可以通过 /usr/lib/rpm/macros 查看其它更加多的例子.

在运行时可以重新定义宏,用户自己可以设置rpm-build的非特权的目录%{_topdir}. 来指定任意目录.
 

Spec 文件

重点注意

  1. 版本: Name,Version,Release
  2. 其它软件有关的信息: Group,License,URL,Summary
  3. 先决条件: PreReq,Requires,BuildPreRep,Provides,Obsoletes,Conflicts
  4. 输入: Source[#],Patch[#]
  5. BuildRoot,BuildArch

%define           name foo            # 名字          
          %define           version 1.2            #version          
          Name: %{name}             #name 就是使用的上面的宏指令          
          Version: %{version}             #version 也是使用的上面的宏指令          
          Release: 3          
          License: GPL          
          Group: Applications/Productivity            # 软件是哪个组的,更多信息查看 /usr/share/doc/rpm-version/GROUPS          
          URL:  http://www.foo.org         
          Source:  ftp://www.foo.org/pub/people/elvis/          %25          %7Bname          %7D          -          %25          %7Bversion          %7D          .tar.gz          
          Patch0: foo-1.2-change_default.patch          
          Patch1: foo-1.2-add_feature.patch          
          PreReq: unzip             # 安装前需要什么          
          Requires: pam            # 安装后需要什么          
          BuildPreReq: gcc >= 2.96           #打包前需要什么          
          BuildRoot: %{_tmppath}/%{name}-root            # 准备源码文件的 chroot 的目录          
          Summary: A fictional           open          source           package          for           the offering.            #摘要          
          %description                       #描述



注意,spec 文件很多信息都是取自宏指令,如果没有明确指定,就会继承 /usr/lib/rpm/macros 和其它相关宏指令的文件.

 

Spec 文件之 %prep
%prep 这部分其它是由一些参数来组成一个 shell 脚本来从 SOURCES 中解压源码和应用补丁到 BUILD 目录中来准备下面的编译。
和 %prep 相关的宏指令
%setup
%patch
例:

%prep         
          %setup           -q             #提取源码到 BUILD 目录; -q 指不显示输出(quietly)          
          %patch0           -p1            # 应用 patch0          
          %patch1           -p1 -b .orig             # 应用 Patch1 但是存下源文件成 .oring 的后缀          
          unzip foo_data.zip             # 接下来解压 zip 文件



 
Spec 文件之 %build
%build 是编译和准备软件,运行象一个 shell 脚本,它运行在上下文目录指定的源码目录。在编译过程中,调用脚本 .config 在本地的目录(%configure 中配置的).
和 %build 相关的宏
%configure  # 可以通过运行 rpm -eval %configure 来看它的设置
例:



%build         
          %configure          --enable-shared          
          CFLAGS=-O2 make



 
Spec 文件之 %install
%install 是用来做 rpm 安装所有需要的文件。这些打包的文件会复制到前面的讲的 BuildRoot 中的目录树中。通常这个目录是使用的 /var/tmp 中。
$RPM_BUILD_ROOT 参数来设置 BuildRoot.
主要不能使用真实目录来设置的主要原因是,在编译的过程中有可能会有文件替换到你系统中的文件引起系统和软件问题.对其它的文件路径象在 %{_mandir}, %{_bindir} , %{_sysconfdir} 等等,都是使用预先定义的宏来指定的. 默认都是跑在这个 RPM_BUILD_ROOT 目录下的。
例:

%install         
          rm -rf           $RPM_BUILD_ROOT            # 默认的$RPM_BUILD_ROOT 是 /var/tmp/%{name}-root          
          make DESTDIR=          $RPM_BUILD_ROOT          install             # 指定安装文件的路径          
          install -m644 foo.8 ${RPM_BUILD_ROOT}/%{_mandir}/man8/foo.8



 

Spec 文件之 %clean
%clean 是用来清理 build 后的临时文件,主要是怕这些旧的文件影响以后编译。主要是要删除 $RPM_BUILD_ROOT 和运行 make clean 。
例:

%clean         
          rm -rf           $RPM_BUILD_ROOT         
          make clean



 

 Spec 文件之 Scriptlets
这些选项可以让你动态的使用 shell 脚本来控制安装和删除,
%pre,%post  是用脚本运行在包安装后,注意没法交互
%preun,%postun  用脚本运行在包删除时
rpm -q –scripts packagename # 可以看到脚本的信息

例如:



%pre         
          groupadd -g 201 foo          
          useradd -g foo -s /bin/false -d /var/foo -M foo          
          %post         
          /sbin/ldconfig          
          chkconfig --add food          
          %preun         
          if           [           $1          = 0 ]          
          then          
                    service food stop > /dev/null 2>&1          
                    chkconfig --del food          
          fi          
          %postun         
          if           [           $1          = 0 ]          
          then          
                    userdel foo          
                    groupdel foo          
          else         
                    /sbin/ldconfig          
                    service food condrestart > /dev/null 2>&1          
          fi



注意,在这个当中的 $1 的数字,如果是 1 是指是第一次安装,如果是 2 是指也许是升级。如果是 0 在 %postun , 是指被完全的删除

 

Spec 文件之 %files
%files 任何打包的文件,都需要在这个包的详细的文件列表中,如果是目录,包的所有者的全部目录都在中间,%dir 来指定空目录,可以用 %files -f /tmp/dyanmic_filelist 来指定一个文件列表。默认 %config 会替换掉配置,给原来的配置修改名字为 .rpmorig ,如果不想修改的话,就用%config(noreplace) 就会给新的配置文件名字命名为 .rpmnew.
%defattr(mode,user,group)
    %attr(mode,user,group) filename
%config  配置文件
%doc 文档
例:


%files         
          %defattr          (-,root,root)          
          %config           /etc/foo.conf           # 指定了才能在更新和删除时有用          
          /usr/sbin/food          
          /usr/bin/foo          
          %doc           README           # 目录是在 /usr/share/doc/%{name}-%{version}          
          %doc           /usr/share/man/man8/food.8          
          /usr/share/foo/          
          %dir           /var/          lock          /foo/            # 空的目录



 

 Spec 文件之 %changelog
%changelog 是记录包的修改,比如加入一个新的补丁,修改配置,日志使用 data +"%a %b %d %Y",需要显示包的日志改变的信息可以使用 rpm-q –changelog.