RPM HOWTO (RPM at Idle) 作者: Donnie Barnes, djb@redhat.com 译者: 胡崇伟 marr@cc.nccu.edu.tw v2.0, 8 April 1997 _________________________________________________________________ 如何使用 Red Hat 包装管理程式。 _________________________________________________________________ 1. Introduction 2. Overview 3. General Information * 3.1 Acquiring RPM * 3.2 RPM Requirements 4. Using RPM 5. Now what can I really do with RPM? 6. Building RPMs * 6.1 The rpmrc File * 6.2 The Spec File * 6.3 The Header * 6.4 Prep * 6.5 Build * 6.6 Install * 6.7 Optional pre and post Install/Uninstall Scripts * 6.8 Files * 6.9 Building It * 6.10 Testing It * 6.11 What to do with your new RPMs * 6.12 What Now? 7. Multi-architectural RPM Building * 7.1 Sample spec File * 7.2 Optflags * 7.3 Macros * 7.4 Excluding Architectures from Packages * 7.5 Finishing Up 8. Copyright Notice _________________________________________________________________ 1. Introduction RPM 指的是 Red Hat Package Manager 之缩写, 虽然名称上包含著 Red Hat 的 字号, 但其原始设计理念是采开收式的, 用意在於让这个程式能提供给所有人 使用。 透过 rpm 的管理, 使用者可以将某个新软体的 source code, 重新整 理包装成另一种 source 与 binary 的档案型式, 如此一来, 我们可以轻松地 由 binary 型式的档案, 进行安装与套件追踪管理的工作, 而 source 型式的 档案, 也很方便地能够再被重新整理包装。 同时, rpm 管理著一份资料库, 里头包含了所有的程式套件的档案资料, 透过这份资料库, 我们可以进行程式 套件之确认与查询工作。 Red Hat 公司鼓励其他协力厂商, 一同发展及使用 RPM 於它们的 distribution 当中。 RPM 相当具有弹性, 其操作非常简单, 提供系统扩充发 展的基础, 另一方面, 它的发展完全公开, 而且可免费取得, 使用者可以回 覆任何程式码上的错误与修正内容。 只要在符合 GPL 的宣告条件下, 大家可以 自由地使用及传播 RPM 程式。 如果您想获得有关 RPM 更详细的文件说明, 可以参考 Ed Bailey 所撰之 Maximum RPM 一书。 这本书可由 [1]www.redhat.com 下载或购买到。 2. Overview 首先, 让我们先来了解 RPM 背後的设计哲学, 其设计的目的之一, 便是允许 使用者能够使用「纯净」的 source 档案。 关於此点, 我们必须回溯至 RPP 程 式, ( 这是一个早期所使用的程式套件管理系统, 不过, 後来 RPM 倒没有由 其衍生 ), 它所采用的 source 档案, 都是经过额外的「破解处理」。 理论上 , 使用者可以顺畅无误地, 从一份 RPP 原始档, 完成 install 与 make 的动 作。 但是这样处理过的 source 档案, 已是面貌全非, 使用者可能无从得知, 档案里到底哪些地方被更改过, 通常必须额外取回未经处理过的 source 档案。 而 RPM 的做法, 便是让使用者取得「未经处理过的 source 档案」, 同时再附 上一份「patch 档案」, 可藉之完成程式编译的工作。 我们很容易发现, 这样 的做法带来不少好处。 怎麽说呢? 举个状况为例, 在 Red Hat Linux 下, 如 果某个新版的程式问世了, 您可能没有必要再重头开始做 compile 动作, 先观 察「patch 档案」的内容, 看看是否有哪些部份才是您需要做的。 如此一来, 所有内含的程式预设值便很容易看出来。 另一方面, RPM 也具有强大的查询功能, 您可以针对整个程式套件的资料库, 或是某些特定的档案, 进行查询的动作, 也可以轻松地查出, 某个档案是属於 哪个程式套件, 或是它打从哪里来的。 RPM 档案本身是经过压缩的, 但您还是 可以很容易而快速地, 查询每个程式套件的内容, 因为在程式套件里, 已经加 入一段特殊的 binary header, 它记录了全部查询时所需的内容, 这样的做法 , 使得查询功能变得相当快速。 另一项强大的功能, 便是程式套件的完整确认。 如果您担心误砍某个档案, 而 它正是某个程式套件的重要部份, 那麽做个「确认动作」就行了。 如有任何不 正常的地方, 便会通知您, 这时候, 您可以视情况重新安装该程式套件, 而 且所有之前的设定档, 都会完好地被保存下来。 我们非常感谢来自 BOGUS distribution 的高手们, 他们提供了许多意见构想, 後来也都被采用於 RPM 当中。 虽然 RPM 完全是由 Red Hat Software 所撰写, 但其操作模式是根据 BOGUS (PM 与 PMS) 所写的程式码。 3. General Information 3.1 Acquiring RPM 最好且最简单的方法, 当然就是安装 Red Hat Linux 罗, 如果您抵死不从, 那麽依然可以从 FTP 站, 抓取原始程式回来安装。 程式档案的位置是 [2]ftp.redhat.com。 3.2 RPM Requirements 顺利执行 RPM 的最大条件, 就是「要有 2.4.2 版以上的 cpio 程式」。 RPM 主要是设计给 Linux 使用的, 但对於其他 Unix 系统的相容性也相当不错, 事 实上, 它已经顺利在 SunOS、 Solaris、 AIX、 Irix、 AmigaOS 及其他系统上 完成 compile 动作。 值得注意的是, 由不同 Unix 作业平台所编译出来的 binary 程式套件, 是不能彼此相容的。 上述只是安装 RPM 的最低需求, 如果想要由 source 档案建造起, 那麽您还需 要 gcc, make 之类的编译工具程式, 这和建造一般程式套件并无二致。 4. Using RPM RPM 可以用於安装程式套件上, 最简单的操作格式如下: rpm -i foobar-1.0-1.i386.rpm 另一个简单的操作□例, 是用於解除某一个程式套件的安装: rpm -e foobar 接下来的指令□例较为复杂, 但它非常有用, 可以让您透过 FTP 来安装程式套 件。 如果您能够连上网路, 想安装某个新的程式套件时, 所需下达的指令, 便是在档案前加上适当的 URL 格式, 例如: rpm -i ftp://ftp.pht.com/pub/linux/redhat/rh-2.0-beta/RPMS/foobar-1.0-1.i386.rp m 请特别注意, RPM 目前已允许透过 FTP 来进行查询或安装。 上述都是些简单的指令, rpm 还有许多不同的选项方式, 这些可由 Usage 的说 明中看出: RPM version 2.3.9 Copyright (C) 1997 - Red Hat Software This may be freely redistributed under the terms of the GNU Public License usage: rpm {--help} rpm {--version} rpm {--initdb} [--dbpath ] rpm {--install -i} [-v] [--hash -h] [--percent] [--force] [--test] [--replacepkgs] [--replacefiles] [--root ] [--excludedocs] [--includedocs] [--noscripts] [--rcfile ] [--ignorearch] [--dbpath ] [--prefix ] [--ignoreos] [--nodeps] [--ftpproxy ] [--ftpport ] file1.rpm ... fileN.rpm rpm {--upgrade -U} [-v] [--hash -h] [--percent] [--force] [--test] [--oldpackage] [--root ] [--noscripts] [--excludedocs] [--includedocs] [--rcfile ] [--ignorearch] [--dbpath ] [--prefix ] [--ftpproxy ] [--ftpport ] [--ignoreos] [--nodeps] file1.rpm ... fileN.rpm rpm {--query -q} [-afpg] [-i] [-l] [-s] [-d] [-c] [-v] [-R] [--scripts] [--root ] [--rcfile ] [--whatprovides] [--whatrequires] [--requires] [--ftpuseport] [--ftpproxy ] [--ftpport ] [--provides] [--dump] [--dbpath ] [targets] rpm {--verify -V -y} [-afpg] [--root ] [--rcfile ] [--dbpath ] [--nodeps] [--nofiles] [--noscripts] [--nomd5] [targets] rpm {--setperms} [-afpg] [target] rpm {--setugids} [-afpg] [target] rpm {--erase -e} [--root ] [--noscripts] [--rcfile ] [--dbpath ] [--nodeps] [--allmatches] package1 ... packageN rpm {-b|t}[plciba] [-v] [--short-circuit] [--clean] [--rcfile ] [--sign] [--test] [--timecheck ] specfile rpm {--rebuild} [--rcfile ] [-v] source1.rpm ... sourceN.rpm rpm {--recompile} [--rcfile ] [-v] source1.rpm ... sourceN.rpm rpm {--resign} [--rcfile ] package1 package2 ... packageN rpm {--addsign} [--rcfile ] package1 package2 ... packageN rpm {--checksig -K} [--nopgp] [--nomd5] [--rcfile ] package1 ... packageN rpm {--rebuilddb} [--rcfile ] [--dbpath ] rpm {--querytags} 您可以在 RPM 的 man page 里, 找到这些选项的详细说明。 5. Now what can I really do with RPM? RPM 是个非常有用的工具, 而且如您所知的, 它具有许多选项功能。 让您了解 这些功能的最好方式, 便是实际介绍几个□例, 前面我们已经提过安装与解除 安装的简单例子, 底下是一些额外的□例: * 假设说, 您不小心误删了几个档案, 但不确定到底是哪些档案, 您想对整 个系统进行确认动作, 以了解哪些部份可能已经遗损, 您可以这样做: rpm -Va * 假设说, 您碰到一个认不出来的档案, 想要知道它是属於哪一个程式套件 的话, 您可以这样做: rpm -qf /usr/X11R6/bin/xjewel 其结果会得到: xjewel-1.6-1 * 如果您找到一个新的 RPM 档案, 却不清楚它的内容, 想要获得相关的资讯 , 可以这样做: rpm -qpi koules-1.2-2.i386.rpm 其结果会得到: Name : koules Distribution: Red Hat Linux Colgate Version : 1.2 Vendor: Red Hat Software Release : 2 Build Date: Mon Sep 02 11:59:12 199 6 Install date: (none) Build Host: porky.redhat.com Group : Games Source RPM: koules-1.2-2.src.rpm Size : 614939 Summary : SVGAlib action game with multiplayer, network, and sound support Description : This arcade-style game is novel in conception and excellent in execution. No shooting, no blood, no guts, no gore. The play is simple, but you still must develop skill to play. This version uses SVGAlib to run on a graphics console. * 如果您想了解某个 RPM 档案, 会在系统里安装哪些档案, 您可以这样做: rpm -qpl koules-1.2-2.i386.rpm 其结果会是: /usr/doc/koules /usr/doc/koules/ANNOUNCE /usr/doc/koules/BUGS /usr/doc/koules/COMPILE.OS2 /usr/doc/koules/COPYING /usr/doc/koules/Card /usr/doc/koules/ChangeLog /usr/doc/koules/INSTALLATION /usr/doc/koules/Icon.xpm /usr/doc/koules/Icon2.xpm /usr/doc/koules/Koules.FAQ /usr/doc/koules/Koules.xpm /usr/doc/koules/README /usr/doc/koules/TODO /usr/games/koules /usr/games/koules.svga /usr/games/koules.tcl /usr/man/man6/koules.svga.6 上述只是一些□例, 当您对 RPM 愈加熟悉时, 应该能想出其他更多的创意组合 。 6. Building RPMs 如果您可以自个儿取得所需的软体,那麽建造 RPM 档案也是非常简单的。 建造 RPM 档案的基本步骤如下: * 确定您的 /etc/rpmrc 已经符合系统所需, 完成设定。 * 取回所要建造的 source code。 * 进行所需的 source 档案 patch 动作, 以使得我们能顺利地 build 整个程 式。 * 为程式套件撰写一份 spec 档案。 * 确认每个档案都在正确的目录位置。 * 使用 RPM 来 build 整个程式套件。 如果一切操作正确, RPM 便能顺利 build 完成 binary 与 source 程式套件。 6.1 The rpmrc File 目前为止, RPM 系统唯一的设定档, 是透过 /etc/rpmrc 档案来管理。 其内容 □例如下: require_vendor: 1 distribution: I roll my own! require_distribution: 1 topdir: /usr/src/me vendor: Mickiesoft packager: Mickeysoft Packaging Account optflags: i386 -O2 -m486 -fno-strength-reduce optflags: alpha -O2 optflags: sparc -O2 signature: pgp pgp_name: Mickeysoft Packaging Account pgp_path: /home/packages/.pgp tmppath: /usr/tmp 档案中的 require_vendor 这一行叙述, 用以控制 RPM 是否须要找寻 vendor 那一行叙述, 而 verdor 的资讯可能来自 /etc/rpmrc 或是 spec 档案的 header 处。 如果您把上述的号码改为 0, 便能把这项寻找功能关闭。 这样的 设定方式, 同样适用於 require_distribution 与 require_group 的叙述上。 接下来, 我们看到 distribution 这一行, 您可以在此设定, 或是日後在 spec 档案的 header 处设定。 当我们在某个 distribution 上 build 程式套件 时, 就算不需要查询设定, 此行内容的设定正确, 也是能够带来许多便利。 vendor 那一行的作用, 和上述的 distribution 非常相似, 但其内容并不限定 ( 例如是 Joe's Software 或 Rock Music Emporium )。 RPM 目前支援「多平台架构」的程式套件 build 功能, 我们可以在 rpmrc 档案 里指定 ``optflags'' 变数, 当进行程式套件 build 动作时, 便可依据所需的 平台类型, 应用特定的变数内容。 我们将会在接下去的章节里, 说明如何使用 这些变数。 除了上述的 macro 设定外, 还有许多其他的设定方式, 您可以使用: rpm --showrc 来查看系统的 tag 与可供使用的 flag 有哪些。 6.2 The Spec File 在此我们将讨论 spec 档案的设定。 build 一个程式套件时, 我们需要使用到 spec 档案, 其内容为该程式套件的说明, 额外还包括一些指令, 用以指示整 个 build 的过程, 还有一份档案列表, 用以表示程式套件中的档案, 分别被 安装到哪里。 spec 档案的命名方式, 最好是遵循标准的惯例, 其格式应该为 package name-dash-version number-dash-release number-dot-spec。 这里我们举一个小型的 spec 档案为例 (vim-3.0-1.spec): Summary: ejects ejectable media and controls auto ejection Name: eject Version: 1.4 Release: 3 Copyright: GPL Group: Utilities/System Source: sunsite.unc.edu:/pub/Linux/utils/disk-management/eject-1.4.tar.gz Patch: eject-1.4-make.patch Patch1: eject-1.4-jaz.patch %description This program allows the user to eject media that is autoejecting like CD-ROMs, Jaz and Zip drives, and floppy drives on SPARC machines. %prep %setup %patch -p1 %patch1 -p1 %build make RPM_OPT_FLAGS="$RPM_OPT_FLAGS" %install install -s -m 755 -o 0 -g 0 eject /usr/bin/eject install -m 644 -o 0 -g 0 eject.1 /usr/man/man1 %files %doc README COPYING ChangeLog /usr/bin/eject /usr/man/man1/eject.1 6.3 The Header 档案 header 的部份, 有几个特定的栏位内容, 您必须加以设定完成, 另外还 有几点注意事项。 您必须设定完成的栏位内容如下: * Summary: 以一行长度的描述, 来说明程式套件的内容。 * Name: 这个档案名称必须与您准备使用的 rpm 档名一致。 * Version: 这个版本名称必须与您准备使用的 rpm 档名一致。 * Release: 这个发行序号必须与您准备使用的 rpm 档名一致。 ( 也就是说, 如果我们完成一个程式套件, 但事後发现它有些小小的问题, 必须重新 build 一次, 此时新的程式套件, 其发行序号便是 2 号 )。 * Icon: 如果您使用了其他高阶的安装工具程式 ( 像是 Red Hat 的 ``glint'' 程式 ), 那麽这里可以指定其相对应的图示档, 它必须是一个 gif 档案, 而且必须位於 SOURCES 目录。 * Source: 这里指定了那些「未经处理过的 source 档案」的 HOME 目录, 当 您想要重新取得 source 档案, 或是检察是否有新版本时, 就需要用到这 个设定。 注意事项: 这里的档名, 「务必」与您系统上的档案名称一致 ( 也就是说, 下载 source 档案後, 不要去变更其档案名称 )。 同时, 您可以指定一个以上的 source 档案, 方式如下: Source0: blah-0.tar.gz Source1: blah-1.tar.gz Source2: fooblah.tar.gz 这些档案都会到 SOURCES 目录底下 ( 相关的目录结构说明, 会在後面的 "The Source Directory Tree" 章节里加以讨论 )。 * Patch: 如果您需要重新下载 patch 档案, 那麽其目录位置设定於此。 注 意事项: 这里的档名, 必须与您系统上使用的 patch 档案名称相符, 另 一方面, 和前述多个 source 档案的设定一样, 您也可以指定多个 patch 档案名称。 其格式□例如下: Patch0: blah-0.patch Patch1: blah-1.patch Patch2: fooblah.patch 这些档案都会到 SOURCES 目录底下。 * Copyright: 这里的设定, 用以说明程式套件采用何种版权声明。 像 GPL、 BSD、 MIT、 public domain、 distributable、 commercial 等, 都是您 可以指定的。 * BuildRoot: 您可以指定一个目录, 它会被当作是 build 与 install 新程 式套件的 ``root'' 目录, 如果您想在实际安装之前, 先行测试程式内容 , 可以善用此项设定。 * Group: 这里的设定, 用於高阶的安装工具程式 ( 例如 Red Hat 的 ``glint'' 程式 ) 当中, 用以说明程式所属的群组位置。 目前的群组架构 , 大致如下所述: Applications Communications Editors Emacs Engineering Spreadsheets Databases Graphics Networking Mail Math News Publishing TeX Base Kernel Utilities Archiving Console File System Terminal Text Daemons Documentation X11 XFree86 Servers Applications Graphics Networking Games Strategy Video Amusements Utilities Libraries Window Managers Libraries Networking Admin Daemons News Utilities Development Debuggers Libraries Libc Languages Fortran Tcl Building Version Control Tools Shells Games * %description 这个并非真的是 header 项目, 但您应该连同上述的项目一 同填写, 每个「程式套件」或「子程式套件」, 都应该有一个 description tag。 这里允许您输入多行内容, 使得程式套件能够具有一份 完整详尽的说明。 6.4 Prep 这里是 spec 档案的另一个段落章节, 用以设定让 source 档案就绪, 以供下 一步的 build 动作。 平常我们必须经过 setup, 才能实际进行 make 动作, 因此在本段落章节中, 我们将视需要进行 source 档案的 patch 与 setup。 有件事值得注意的: 接下来的段落设定, 实际上只是指明某段 shell scripts 的位置, 您可以将 shell scripts 的内容, 另外以 sh script 的方式加以存 档, 并将 script 程式名称置於 %prep tag 之後, 用以执行 source 档案的 unpack 与 patch 动作。 当然, 以原有之 macro 型式来做, 应该是方便许多 的。 第一个要说明的 macro 是 %setup。 如果我们采用其最简单的格式 ( 即不加任 何命令列参数的情况 ), 它会单纯地将 source 档案加以 unpack, 并 cd 进入 source 档案的目录。 除此之外, 您还可以使用下列的选项: * -n name 这个选项设定会把 build 的目录设为 name, 原预设值为 $NAME-$VERSION, 其他可能目录名称包括 $NAME, ${NAME}${VERSION}, 或是 tar 档案本身所用的目录。 ( 请注意到, 上述的 ``$'' 变数, 并不 是 spec 档案里的变数, 它们在这里只是用来代表一个□例名称, 您必须 在程式套件里, 使用实际的档案名称与版本名称 )。 * -c 在进行 untar 动作之前, 会先建立一个目录, 并 cd 进入该目录。 * -b # 在 cd 进入该目录之前, 会先将 Source# 进行 untar 动作 ( 这个选 项与 -c 选项并存时, 是没有意义的, 所以应避免同时使用 ), 而且这个 选项, 仅适用於多个 source 档案的场合。 * -a # 在 cd 进入该目录之後, 再将 Source# 进行 untar 动作。 * -T 这个选项会盖过原本预设的 untar 动作, 同时需要一个 -b 0 或是 -a 0 的选项来配合, 当您使用到两个以上的 source 档案时, 便需要此项功 能。 * -D 在解开程式套件之前, 不要删除该目录。 这个选项仅适用於使用两个以 上 setup macro 之场合, 而且只能用於第一个 setup macro 之後 ( 千万 别用於第一个之内 )。 接下来要说明的 macro 是 %patch。 它是用来协助自动处理 source 档案更新的 动作, 其相关的选项很多, 列表说明如下: * # 会引用 Patch# 当作其所需之更新档。 * -p # 有时 patch(1) 指令需配合指定 strip 的目录数目, 你可以在此选项 中加以设定。 * -P 其预设之动作是引用 Patch ( 或 Patch0 ), 当您使用两个以上的 %patch macro, 并且需要与第一个 macro 不同之 patch number 时, 这个 选项显得相当有用。 它会盖过原本的预设动作, 并且需要配合一个 0, 以 使得主要的 source 档案得以进行 untar 动作。 * 您也可以使用 %patch#, 而不必使用这样的指令: %patch # -P 这些应该就是全部所需要知道之 macro 说明, 了解它们之後, 您也可以透过 sh 之 script 格式, 设定不同的 setup 方法, 在 %build macro ( 在下一章 节中会提及 ) 之前, 您所设定之所有选项, 都是经由 sh 来执行, 您可以再 参考一下前述的□例, 或许可以适用於您的需要。 6.5 Build 这个章节里, 所述及的并非真正的 macro。 当您把 source 档案 untar, 并且 patch 完成, cd 进入目录之後, 开始准备 build 动作时, 便是在这里设定那 些控制 build 动作的指令。 而这些指令都还是传给 sh, 所以任何 sh 之指令 , 都可以在此指定 ( 包括 comments 在内 )。 在 spec 档案里的每一段落章节 设定中, 您的目前所在目录位置, 都会被重新设定为 source directory 的最 上层, 所以请牢记在心, 必要时, 您可以 cd 进入相关的子目录。 6.6 Install 这里所设定的, 同样也不是 macro, 基本上, 您只须要在此设定一些 install 所需之指令。 如果您打算在程式套件里, 提供完整的 make install 指令设定, 那麽请在本段落设定中完成, 不然, 您也可以更改 makefile 档案 里, 有关 make install 的部份, 然後仅在本段落设定中指定 make install。 或是, 也可以把整个 install 的指令交给 sh 来做。 记住, 您的目前所在目 录位置, 应该已被重新设定为 source directory 的最上层。 6.7 Optional pre and post Install/Uninstall Scripts 程式套件在安装与解除安装之前後,您可以指定 script, 使其视情况加以执行 。 进行此项动作的主要原因之一, 便是遇到如下的场合, 譬如说, 我们在安 装或解除安装一些含有 shared library 的程式套件时, 需要执行 ldconfig。 各式 script 所需之 macro 名称如下: * %pre 执行 pre-install scripts 的 macro。 * %post 执行 post-install scripts 的 macro。 * %preun 执行 pre-uninstall scripts 的 macro。 * %postun 执行 post-uninstall scripts 的 macro。 这些段落设定的内容, 可以是任何 sh 型式之 script, 不过, 您无须指定关 键叙述 #!/bin/sh。 6.8 Files 本段落设定当中, 您必须列出程式套件内之所属档案名称。 RPM 本身并无从得 知, 执行 make install 之後, 到底有哪些 binary 档案被安装进去, 目前并 无他法可以直接解决此问题。 有些人建议在 install 程式套件的前後, 使用 find 指令来处理, 不过在一个多使用者的系统下, 这应该是不可行的, 因为 在程式套件 build 的过程中, 可能有其他与程式套件本身无关的档案被产生。 另外还有一些 macro, 它们可用来做一些特殊的工作, 兹将其列述於下: * %doc 用以标示在 install 程式套件时, 您所想要安装之 source 档案里的 说明文件是哪些, 而这些说明文件会被安装在 /usr/doc/$NAME-$VERSION-$RELEASE。 您可以在命令列上, 以此 macro 同 时指定好几个说明文件名称, 或是以此 macro, 各别为它们一一完成指定 。 * %config 用以标示程式套件里的设定档案是哪些, 这包括像 sendmail.cf、 passwd 之类的档案。 如果您事後 uninstall 了某个程式套件, 而且它含 有设定档案, 那麽所有没有改变的档案会被移除, 而所有已经改变的档案 , 会在原档案名称之後, 加上 .rpmsave 的延伸名称。 同样的, 您可以 在此同时列出多个档案名称。 * %dir 在档案列表中, 标明某一个特定的目录, 用以说明该目录为某程式套 件所拥有。 如果您在档案列表中指定一个目录名称, 但却没有在前面加 上%dir macro, 那麽该目录内, 所有档案目录都会被包含在档案列表当中 , 并在稍後, 被当作是程式套件的一部份而全被安装进去。 * %files -f 允许您引用 source 之 build 目录里, 某份档案清 单的内容。 当您遇到某一个程式套件, 它可以建立自己的档案清单时, 这 个选项便显得相当不错, 您只须要引用该份档案清单, 不必再自行辛苦地 列出。 在档案列表里, 有个最大的注意事项, 便是目录的设定。 如果您不小心将 /usr/bin 列入, 那麽您的程式套件, 将会包括系统里 /usr/bin 底下的所有档 案。 6.9 Building It The Source Directory Tree 第一件事, 您必须选定一个适当的 build tree, 此项设定可在 /etc/rpmrc 档 案里完成, 而大多数人会直接使用 /usr/src。 您可能还需要建立下列的目录, 使得 build tree 的设定能够完成: * BUILD 此目录便是 RPM 进行所有 build 动作的工作目录。 您不必特别地在 哪个目录进行测试性的 build 动作。 * SOURCES 此目录存放著您的「起始」 (original) 原始 tar 档案、 与相关 的 patch 档案, RPM 预设会寻找本目录。 * SPECS 此目录存放所有之 spec 档案。 * RPMS 此目录存放所有 build 产生之 binary 格式 RPM 档案。 * SRPMS 此目录存放所有 source 格式 RPM 档案。 Test Building 首先, 您大概会想要取回 source 档案, 在没有使用 RPM 的情况下, 进行一 次「纯净的」 build 动作。 其步骤便是, 解开 source 档案, 将该目录名称 改为 $NAME.org, 然後再次解开 source 档案, 我们需要使用此一 source 来 进行 build 动作。 进入此一 source 目录, 按照指示来进行 build, 如果您 必须编辑任何东西, 您会需要一份 patch, 一旦您完成 build 工作, 便可清 除 source 目录里的内容。 请确定将 configure script 里, 所有产生之档案 加以清除, 然後再 cd 回到 source 目录之上层, 接著便可执行这样的动作: diff -uNr dirname.orig dirname > ../SOURCES/dirname-linux.patch 上述指令会产生一份 patch, 您在 spec 档案可以使用到它。 注意到上面的 ''linux'' 名称, 它只是一个提示作用, 或许您可以使用其他名称, 诸如 ''config'' 或 ''bugs'' 之类的提示名称, 用以说明您何以制作此一 patch 档 案。 同时, 您最好也在使用 patch 档案之前, 先观察里头的内容, 确定是否 无意间包含了其他的 binary 档案。 Generating the File List 现在, 您已经有了一份可以拿来 build 的 source 档案, 而且您也知道如何完 成其相关的动作, 如 build 与 install 等。 观察 install 时, 依序产生的 结果, 我们将由此结果, 在 spec 档案中建立一份档案列表。 通常我们会在进 行上述步骤的同时, 一起建立 spec 档案, 您可以先完成档案的起始部分, 和 几个简单的部分, 然後再把其他部分的步骤加以完成。 Building the Package with RPM 一旦您有了一份 spec 档案, 一切便已就绪, 您可以准备 build 的测试动作。 最好的方式, 就是使用类似下列的指令: rpm -ba foobar-1.0.spec 配合 -b 选项, 我们还可以使用其他有用的选项: * p 指的是只执行 spec 档案之 prep 部份。 * l 针对 %files 进行档案列表的比对检查动作。 * c 执行 prep 与 compile 的动作。 当您不确定 source 档案是否能够 build 时, 此选项显得相当有用。 或许您会觉得它并没有多大用处, 因为 您可能想要继续修改 source 档案本身, 直到 build 後再开始使用 RPM, 但一旦您熟悉 RPM 的用法後, 会发现它的便利之处。 * i 执行 prep、 compile、 与 install。 * b 执行 prep、 compile、 install、 并只 build 出一份 binary 程式套件 。 * a 执行所有的 build 动作 ( 包括 source 与 binary 的程式套件 )。 配合 -b 选项, 另外还有一些细项选项可供使用, 它们分别是: * --short-circuit 会直接跳至某个特定的阶段 ( 仅可配合 c 与 i 选项来使 用 )。 * --clean 当执行完毕时, 移除相关的 build tree。 * --keep-temps 会把所有的 temp 与 scripts 档案, 都保留在 /tmp 目录, 您可以使用 -v 选项, 实际观察有哪些档案被产生。 * --test 并不实际执行任何阶段的动作, 但有执行 keep-temp 的部份。 6.10 Testing It 一旦有了 source 与 binary 的 rpm 档案, 您必须进行测试工作。 最简单且最 好的方式, 就是使用另一台机器来测试, 也就是进行 build 动作之外的机器。 毕竟, 您刚在您的机器上, 完成一大堆的 make install 动作, 若在原机器上 做测试, 当然会显得相当顺利罗。 您可以执行 rpm -u packagename 来进行测试, 但这样做还是有造假的可能, 因为在 build 的过程中, 您做了 make install 的动作, 如果您在档案列表中 遗漏了某些东西, 那麽它不会被解除安装, 然後您再 reinstall 这份 binary 程式套件, 便会发现整个系统还是完整而运作正常的, 但实际上的 rpm 档案还 是有问题。 因此请特别记住, 由於您执行的是 rpm -ba package, 而大多数的 人, 会只以 rpm -i package 方式, 来安装您的程式套件。 当 binary 档案独 自被安装时, 您必须确定在 build 或 install 的段落设定中, 并没有相关的 部份对其有影响。 6.11 What to do with your new RPMs 一旦您作出了一份自己的 RPM 档案 ( 假定这份档案, 之前并未以 RPM 方式制 作过 ), 您可以将您的作品贡献给别人 ( 此时假定您制作的 RPM 档案, 是可 以自由传布的 )。 您可以考虑把它上传至 [3]ftp.redhat.com。 6.12 What Now? 请回顾上述的章节, 在「Testing」和「What to do with new RPMs」里, 我们 希望所有的 RPM 档案都能被提供出来, 而且我们希望它们都会是好的 RPM 档案 。 因此, 请多花一点时间好好地测试它们, 然後再花点时间将它们上传, 以 造福普罗大众。 同时, 请确定您只上传可供自由传布的软体。 商业软体与共享 软体是不应该被上传的, 除非它们有份许可声明在上面。 这样的软体, 包括有 Netscape software、 ssh、 pgp 等。 7. Multi-architectural RPM Building RPM 目前可用於 build 各式作业平台之程式套件, 如 Intel i386、 安装 Linux 之 Digital Alpha、 与 Sparc 机器, 而且有人测试报告, 说明它也可 以在 SGI 与 HP 工作站上使用。 RPM 有许多特色, 使得它能够轻松地支援在各 式作业平台上 build 程式套件, 第一个特色便是在 /etc/rpmrc 档案里的 ``optflags'' 设定项目, 当我们在 build 软体套件时, 它可用於指定平台架 构的相关设定值。 另一个特色是 spec 档案里的 ``arch'' macro 项目, 根据 所要进行 build 的平台架构, 您可以指定它们执行不同的工作。 另一个特色是 在档案 header 处的 ``Exclude'' 设定项目。 7.1 Sample spec File 下列以 ``fileutils'' 程式套件为例, 其 spec 档案的部份内容, 可用来在 Alpha 与 Intel 平台架构上, 进行 build 的工作。 Summary: GNU File Utilities Name: fileutils Version: 3.16 Release: 1 Copyright: GPL Group: Utilities/File Source0: prep.ai.mit.edu:/pub/gnu/fileutils-3.16.tar.gz Source1: DIR_COLORS Patch: fileutils-3.16-mktime.patch %description These are the GNU file management utilities. It includes programs to copy, move, list, etc, files. The ls program in this package now incorporates color ls! %prep %setup %ifarch alpha %patch -p1 autoconf %endif %build configure --prefix=/usr --exec-prefix=/ make CFLAGS="$RPM_OPT_FLAGS" LDFLAGS=-s %install rm -f /usr/info/fileutils* make install gzip -9nf /usr/info/fileutils* . . . 7.2 Optflags 在此一□例中, 您可以发现 ``optflags'' 设定项目, 是如何由 /etc/rpmrc 档案中发挥作用。 首先决定您所进行 build 动作的机器, 是哪一种平台架构, 请将其正确之设定值, 指定到 RPM_OPT_FLAGS。 您必须针对程式套件之 Makefile 档案, 进行 patch 的动作, 将一些通用的变数设定值, 加以改变以 适用於您的环境 ( 如 -m486 与 -O2 )。 您可以 install 这份 source 套件, 接著解开 source 并检查其 Makefile 档案, 以进一步找出更好的设定方式, 然後观察 Makefile 的 patch 内容, 以了解我们必须做哪些改变。 7.3 Macros %ifarch 此一 macro 设定项目是非常重要的, 在许多场合, 您须要只针对某一 特定平台架构, 进行一两个 patch 工作, 这种情况下, RPM 能够让您仅针对 某一平台架构, 采用必要的 patch。 在上述□例中, fileutils 有个提供给 64 bit 机器使用的 patch, 很明显地 , 这项 patch 仅需要由 Alpha 机器所采用, 因此, 我们针对 64 bit 的 patch 部份, 增加一个 %ifarch 的 macro 设定项目, 其□例如下: %ifarch axp %patch1 -p1 %endif 这样能保证, 除了 Alpha 机器之外, 其他平台架构的机器并不会采用此 patch。 7.4 Excluding Architectures from Packages 您可以在一个目录内, 同时管理各式作业平台的 RPM 原始档案, 这项功能使得 我们在制作程式套件的时候, 不必限定於某些作业平台上。 因此您可以这样下 指令: rpm --rebuild /usr/src/SRPMS/*.rpm 使得正确的程式套件能够被 build。 如果您尚未移植某个应用程式至某一特定的 作业平台, 可以加上这样的一行内容: ExcludeArch: axp 到 source 程式套件当中, spec 档案的 header 处, 然後在原本进行 build 的作业平台上, 再做一次 rebuild 动作。 此时, 您就有了一份在 Intel 机器 上 build 完成的 source 程式套件, 同时它也很容易便能移□至 Alpha 机器上 。 7.5 Finishing Up 使用 RPM 来制作「多作业平台」的程式套件, 通常会比各别在该平台制作来得 容易, 而且随著您制作越多的程式套件, 其效应会更加明显, 因为, 我们可 以参考其他类似的原始程式套件内容, 得以处理制作时遇到的问题。 8. Copyright Notice 本说明文件及其内容, 均受版权所保护, 在原文保持完整、 未被更动的情况下 , 允许将其转载, 也就是说, 您仅能对原文加以重新排版、 重新列印、 或进 行转录。 References 1. http://www.redhat.com/ 2. ftp://ftp.redhat.com/pub/redhat/code/rpm 3. ftp://ftp.redhat.com/