RPM相关知识准备
RPM 基础知识
若要构建一个标准的 RPM 包,您需要创建 .spec 文件,其中包含软件打包的全部信息。然后,对此文件执行 rpmbuild 命令,经过这一步,系统会按照步骤生成最终的 RPM 包。
一般情况,您应该把源代码包,比如由开发者发布的以 .tar.gz 结尾的文件,放入 ~/rpmbuild/SOURCES 目录。将.spec 文件放入 ~/rpmbuild/SPECS 目录,并命名为 "软件包名.spec" 。当然, 软件包名 就是最终 RPM 包的名字。为了创建二进制(Binary RPM)和源码软件包(SRPM),您需要将目录切换至 ~/rpmbuild/SPECS 并执行:
$ rpmbuild -ba NAME.spec
当执行此命令时,rpmbuild 会自动读取 .spec 文件并按照下表列出的步骤完成构建。下表中,以 % 开头的语句为预定义宏,每个宏的作用如下:
在 rpmbuild 中,对上表中的每个宏代码都有对应的目录:
如果某一阶段失败,请查看输出信息以了解失败原因,并根据需要修改 .spec 文件。
做好准备打包一个特殊程序
如果这里有特殊的程序,它们需要被安装或者运行以便让您打包的普通程序正常工作,那么请先安装它们,然后记录下诸如软件包等相关信息。
不可以使用预编译代码进行打包。将源代码(通常是 .tar.gz 文件)放入 "~/rpmbuild/SOURCES" 目录(注意用户)。
仔细阅读该软件的安装说明。我们建议您先手工安装一次以了解具体情况。除少数情况外,所有二进制文件和程序库都必须由源码包中的源码编译而成。
新建一个 .spec 文件
现在,您需要在 ~/rpmbuild/SPECS 目录下,新建一个 SPEC 文件。文件应命名为 "软件包名.spec"。名称根据软件包名或通用名填写即可。但是,必须要遵守 软件包命名规定。
如果您首次创建 .spec 文件,vim 或 emacs 会自动生成模板:
$ cd ~/rpmbuild/SPECS
$ vim program.spec
示例(仅供参考):
Name:
Version:
Release: 1%{?dist}
Summary:
Group:
License:
URL:
Source0:
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
BuildRequires:
Requires:
%description
%prep
%setup -q
%build
%configure
make %{?_smp_mflags}
%install
rm -rf %{buildroot}
make install DESTDIR=%{buildroot}
%clean
rm -rf %{buildroot}
%files
%defattr(-,root,root,-)
%doc
%changelog
您可以使用 $RPM_BUILD_ROOT 代替 %{buildroot},两者都可以使用。 您也可以使用 rpmdev-newspec 命令来创建 SPEC 文件。rpmdev-newspec 软件包名 可以创建一个初始 SPEC 文件,该工具从软件包名判断使用哪个模板,支持指定模板。 /etc/rpmdevtools/spectemplate-*.spec 包含所有可用的模板,使用 rpmdev-newspec --help 命令了解更多信息。例如,为 python 模块创建 SPEC 文件:
cd ~/rpmbuild/SPECS
rpmdev-newspec python-antigravity
vi python-antigravity.spec
SPEC 文件综述
您需要遵守这些规定:软件包命名规定,打包规定 和 软件包审核规定。
"#" 字符表示注释,但需要避免注释宏(以 % 开头),因为它们会首先被替换展开。使用 %% 注释宏。另外,还要避免在脚本命令的相同行中使用行内注释。
以下介绍了主要的标签。注意 %{name},%{version} 和 %{release} 代表 Name, Version 和 Release 这三个标签。只要更改标签,宏就会使用新值。
SPEC 文件剖析
-
%prep部分
描述了解压源码包的方法。一般而言,其中包含 "%autosetup" 命令。另外,还可以使用 "%setup" 和 "%patch" 命令来指定操作 Source0 等标签的文件。
-
%prep 部分:%autosetup 命令
"%autosetup" 命令用于解压源码包。可用选项包括:
-n name : 如果源码包解压后的目录名称与 RPM 名称不同,此选项用于指定正确的目录名称。例如,如果 tarball 解压目录为 FOO,则使用 "%autosetup -n FOO"。
-c name : 如果源码包解压后包含多个目录,而不是单个目录时,此选项可以创建名为 name 的目录,并在其中解压。
如果使用 "%setup" 命令,通常使用 -q' 抑止不必要的输出。 -
%build 部分
"%build" 部分有时会有点复杂;在这里你可以配置,并编译用于安装的文件。
许多程序使用 GNU configure 进行配置。默认情况下,文件会安装到前缀为 "/usr/local" 的路径下,对于手动安装很合理。然而,打包时需要修改前缀为 "/usr"。共享库路径视架构而定,安装至 /usr/lib 或 /usr/lib64 目录。
由于 GNU configure 很常见,可使用 "%configure" 宏来自动设置正确选项(例如,设置前缀为 /usr)。一般用法如下:%configure make %{?_smp_mflags}
若需要覆盖 makefile 变量,请将变量作为参数传递给 make:
make %{?_smp_mflags} CFLAGS="%{optflags}" BINDIR=%{_bindir}
-
%install 部分
此部分包含安装阶段需要执行的命令,即从 %{_builddir} 复制相关文件到 %{buildroot} 目录(通常表示从 ~/rpmbuild/BUILD 复制到 ~/rpmbuild/BUILDROOT) 目录,并根据需要在 %{buildroot} 中创建必要目录。
容易混淆的术语:
"build 目录",也称为 %{_builddir},实际上与 "build root",又称为 %{buildroot},是不同的目录。在前者中进行编译,并将需要打包的文件从前者复制到后者。
在 %build 阶段,当前目录为 %{buildsubdir},是 %prep 阶段中在 %{_builddir} 下创建的子目录。这些目录通常名为 ~/rpmbuild/BUILD/%{name}-%{version}。
%install 阶段的命令不会在用户安装 RPM 包时执行,此阶段仅在打包时执行。 一般,这里执行 "make install" 之类的命令:%install rm -rf %{buildroot} # 仅用于 RHEL 5 %make_install
理想情况下,对于支持的程序,你应该使用 %make_install,它等同于 DESTDIR=%{buildroot},它会将文件安装到 %{buildroot} 目录中。
Scriptlets
当用户安装 RPM 时,您可能想要执行一些命令。这可以通过 scriptlets 完成。请查看 Packaging/ScriptletSnippets。
脚本片段可以:
- 在软体包安装之前 (%pre) 或之后 (%post) 执行
- 在软体包卸载之前 (%preun) 或之后 (%postun) 执行
- 在事务开始 (%pretrans) 或结束 (%posttrans) 时执行
test-1453381.rpm包的制作过程
-
开始前的准备
安装rpmbuild软件包
yum -y install rpm-build
Linux RedHat 7.4已经安装了。
-
生成相关目录
mkdir -p $(rpmDir)/SOURCES $(rpmDir)/SPECS $(rpmDir)/BUILD $(rpmDir)/RPMS $(rpmDir)/SRPMS
目录结构如下:
rpmbuild/ ├── BUILD ├── BUILDROOT ├── RPMS ├── SOURCES ├── SPECS └── SRPMS
-
编写.spec文件
Name: test-1453381 Version: 1.0 Release: 1%{?dist} Summary: test-rpm Group: none License: none URL: none Source0: test-1453381-1.0.tar.gz %description test-1453381-rpm %prep %setup -q %pre echo "准备安装test-1453381" %post echo "完成安装test-1453381" %build make %install make install DESTDIR=%{buildroot} %preun echo "准备卸载test-1453381" %postun cd %{_builddir}/%{name}-%{version}/ make uninstall echo "完成卸载test-1453381" %files %doc %changelog
-
拷贝相关文件到指定目录
mkdir $(releaseName) cp $(rpmSrcFile) $(releaseName)/ tar -zcvf $(rpmDir)/SOURCES/$(rpmGz) $(releaseName) rm -rf $(releaseName) cp $(rpmSpec) $(rpmDir)/SPECS
-
生成rpm包
rpmbuild -bb $(rpmDir)/SPECS/$(rpmSpec) cp $(rpmDir)/RPMS/x86_64/$(releaseName)-1.el7.x86_64.rpm $(binFinal).rpm
-
测试
可供参考:链接