0%

rpmbuild概要

简要记录如何编写spec文件来打rpm包。

安装 (1)

以CentOS-7为例:

1
2
yum install -y rpmdevtools.noarch rpmlint.noarch
rpmdev-setuptree

Spec文件的结构 (2)

首先,假设要打多个rpm包,例如

  • lua-5.3.6-1.el7.x86_64.rpm
  • lua-devel-5.3.6-1.el7.x86_64.rpm
  • lua-static-5.3.6-1.el7.x86_64.rpm

第一个叫main package。打单个rpm包(main package)是打多个包的特例,不比细说。

Spec文件主要包含:

  • 元信息:
    • Name, Version, Release, License, URL, Source0, Source1, …, Patch0, Patch1, …, BuildRequires
    • Summary, Group, Provides, Requires
    • 每个package的元信息写在%package ${package-name}的下面,main package除外,可以认为默认是main的元信息。
    • 上面我故意把元信息分层2部分(Name开头的一行和Summary开头的一行)。通常,只有main包含第1部分,其它package不须重复,因为一般情况下多个package是一个工程编译构建出来的,源代码(Source)、Patch、编译依赖(BuildRequires)是共同的。
  • 编译前准备(%prep段):一般是解压并进入源代码目录(%setup命令),安装patch(%patch0命令),也可以添加一些自定义操作(用bash写即可);
  • 编译(build段):前一步已经进入源代码目录,现在开始编译。一般linux程序的编译步骤是./configure && make(用bash写即可)。Rpmbuild工具也提供了一个%configure命令,应该是调用./configure
  • 安装到buildroot(%install段):
    • 通常是make install DESTDIR=%{buildroot}
    • 注意,这不是rpm -hiv,也不是在目标机器上执行。从命令make install也可以看出来,是在编译机器上是把编译产生的binaries, headers, libraries, docs, scripts等文件拷贝到buildroot(通常是/root/rpmbuild/BUILDROOT/{name}-{release}.{arch})目录。
  • 定义每个package包含哪些文件(%files段):例如main应该包含binaries和一些libraries, scripts及docs;devel package应该包含headers和libraries等等。注意:上一步install拷贝的文件要被全覆盖,否则报错。
  • 安装前脚本(%pre段):在目标机器上执行。执行rpm -hiv时拷贝文件之前的动作。
  • 安装后脚本(%post段):在目标机器上执行。执行rpm -hiv时拷贝文件之后的动作。例如,安装可执行包之后把binaries的目录添加到PATH;安装devel package之后执行ldconfig建立libraries索引;
  • 删除前脚本(preun段):在目标机器上执行。执行rpm -e时删除文件之前的动作。
  • 删除后脚本(%postun段):在目标机器上执行。执行rpm -e时删除文件之后的动作。通常是%post段的反操作,例如把binaries的目录从PATH删除;删除devel package之后再次执行ldconfig更新索引;
  • 清理(%clean段): 通常是rm -rf ${buildroot}.
  • 修改日志(%changelog段):每个release的更新记录;

Spec skeleton:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#%package foo declaration neglected
Name: foo
Version: 1.0
Release: 1%{?dist}
Summary: Stupid foo
Group: Development
License: MIT
URL: http://www.foo.org/
Source0: foo-%{version}.tar.gz
Patch0: foo-%{version}-bugfix.patch
BuildRequires: bar-devel buz-devel
#package foo provides foo-1.0
Provides: lua = 1.0

#should be "%description foo", but package name ("foo") neglected
%description
Foo is a super stupid foo project.

%prep
%setup -q
%patch0 -p1

%build
./configure
make -j30

%install
make install DESTDIR=%{buildroot}

#should be "%files foo", but package name ("foo") neglected
%files
/usr/local/bin/*
/usr/local/libexec/*
/usr/local/share/*

#should be "%pre foo", but package name ("foo") neglected
%pre

#should be "%post foo", but package name ("foo") neglected
%post

#should be "%preun foo", but package name ("foo") neglected
%preun

#should be "%postun foo", but package name ("foo") neglected
%postun

#package declaration
%package devel
Summary: Development files for %{name}
Group: System Environment/Libraries
Requires: %{name} = %{version}-%{release}
Requires: pkgconfig

%description devel
This package contains development files for %{name}.

%files devel
/usr/local/include/*
/usr/local/lib/lib*.so

%pre devel

%post devel
ldconfig

%preun devel

%postun devel
ldconfig

%clean
rm -rf %{buildroot}

%changelog

案例 (3)

写的不错,有赏!