rpm的制作 spec文件写法
rpm的制作 spec文件写法
RPM使用笔记
Table of Contents
1 spec文件
1.1 spec文件的语法
TagName: value
比如
Version: 2.1.0
tag名大小写不敏感。
1.2 宏
spec支持定义宏,要定义宏,使用:
%define testMacro 2
这里定义了一个宏,名称为testMacro,值为2,要使用这个宏,使用%{testMacro}
或者%testMacro。
1.3 注释
注释使用#开头,如果注释里面出现了%,这需要转义,使用%%就可以了
2 定义包的信息
包的信息中最重要的是NVR,也就是name、version、release,最后生成的rpm包的名称为:name-version-release-architecture.rpm
2.1 定义包的名称
使用:
name: tair
包的名称不能含有空白字符,比如空格、Tab和回车等。
2.2 版本号
版本号用于做版本的比较,rpm的版本比较算法很复杂,最好使用统一的一种版本命名方法,比如2.1.0,要定义包的版本号,使用:
version: 2.1.0
在包的版本号中不能使用’-‘,因为rpm使用它来分隔name、version、release。
2.3 release number
release number在特定版本的第一次build时应该以1开始,之后每次build加1,比如
release: 1
2.4 说明
包括摘要(summary)和描述(description)
2.4.1 摘要
摘要包含一行介绍包的文字,不要超过50个字符,例如:
summary: A distribution key/value storage system
2.4.2 描述
描述允许更详细的介绍,描述支持少量的格式化,空行用于分割段落,以空白开头(比如空格或者Tab)的行通常会以等宽字体显示。例如:
%description Tair is a distribution, hign performance key/value storage system. TairManager tairManager = new TairManager(configServers, groupName);
2.5 平台
spec文件可以指定一个包可以运行在多个平台上,还是必须运行在一个特定的平台上。
2.5.1 排除平台
可以使用excludeArch来表示不构建这些平台的rpm包,比如
excludeArch: sparc
这表示不build在sparc平台下的包
2.5.2 exclusiveArch
可以使用exclusiveArch来指定只build这些平台的rpm包,比如:
exclusiveArch: i386 x86-64
这表示只build i386和x8664平台的包
2.5.3 excludeOs和exclusiveOs
这两个指令用于指定特定的操作系统,比如:
excludeOs: windows
表示不build windows的包
2.6 指定build的路径
和rpm build相关的有两个目录: build和buildroot
build是RPM构建包的地方,编译、配置等操作都在这个目录下执行
buildroot和安装的路径差不多,在安装的时候,包会被安装在相对buildroot的子目录下,要设置buildroot,使用:
buildroot: %{_tmppath}/%{name}-%{version}-root
这将buildroot设定太tmp下的一个子目录,这个子目录类似:tair-2.1.0-root
在设置了Buildroot后,在spec中可以通过RPMBUILDROOT变量来访问这个目录,也可以通过–;buildroot选项来覆盖这个变量
2.7 指定源代码
可以通过source来指定构建需要的源代码,比如:
source: tair-2.1.0-src.tar.gz
如果有多个源代码包,那么使用source和数字混合的tagName,比如:
source0: tbsys-src.tar.gz source1: tbnet-src.tar.gz source2: tair-2.1.0-src.tar.gz
source指定的路径可以是网络路径,比如http://192.168.208.97/packages/%{name}-%{version}-src.tar.gz
3 构建
在指定了包的信息后,spec文件还应该包含构建的命令,rpm将使用这些命令来构建。构建通常由其他工具来完成,比如make。RPM不负责构建包,而是只负责打包。
构建一个包可以分为4步:
- 构建前的准备,包括解压缩代码包等
- 构建
- 安装程序和库
- 清理
3.1 构建前的准备
%prep中定义了构建前要做的准备工作,通常是要包括%setup就可以了
%prep %setup -q
它将切换到构建所在的目录,通常是/usr/src/redhat/BUILD,然后解压源文件,使用以包名命令的子目录。
如果源代码是tar包,那么目标路径下的子目录会自动创建,如果不是,那么可以通过-c选项指定创建。
3.2 构建
构建的步骤在%build中指定,比如
%build ./bootstrap.sh ./configurate make -j 6
3.3 安装
安装由%install表示,如果你的Makefile包含安装命令,那么只要
%install make install PREFIX=$RPM_BUILD_ROOT/usr/local
就可以了。
也可以用makeinstall宏来执行安装,和make install的效果是一样的。
3.4 清理
在安装完成后,可以指定清理工作,通常删除整个构建路径就可以了,比如
%clean rm -rf $RPM_BUILD_ROOT
4 指定安装的文件列表
%file用于指定安装时需要安装的文件列表,可以指定文件、目录,也可以使用通配符,比如
%file /usr/local/sbin/tairserver # 一个可指定文件 /usr/local/sbin/taircfgsvr /usr/local/etc/*.conf # 使用通配符 /usr/local/lib # 使用目录
4.1 文档和配置文件
rpm中会区分文档和配置文件,分别使用%doc和%config来表示,比如
%doc README # 文档 %config /usr/local/etc/*.conf # 配置文件
4.2 设置文件的属性
设置文件属性的格式是:
%attr(mode, user, group) filename
比如:
%config %attr(0644, admin, admin) /usr/local/etc/*.conf
这将etc目录下的配置文件的mode都设置为644,用户和组都设置为admin
5 添加changelog
changelog通常位于spec文件的末尾,使用%changelog开头
6 依赖关系
依赖关系定义了一个包正常工作需要依赖的其他包,RPM在升级、安装和删除的时候会确保依赖关系得到满足。rpm支持4种依赖:
- Requirements, 包依赖其他包所提供的功能
- Provides, 这个包能提供的功能
- Conflicts, 一个包和其他包冲突的功能
- Obsoletes, 其他包提供的功能已经不推荐使用了,这通常是其他包的功能修改了,老版本不推荐使用了,可以在以后的版本中会被废弃。
6.1 定义依赖关系
定义依赖关系的语法是:
Requires: capability Provides: capability Obsoletes: capability Conflicts: capability
大部分时候,capability应该是所依赖的包的名称。一行中也可以定义多个依赖,比如:
Requires: tbsys tbnet
6.2 指定依赖的版本号
在指定依赖关系的时候还可以指定版本号,比如:
Requires: tbsys >= 2.0
rpm支持的比较如下:
比较符 | 含义 |
---|---|
package < version | 小于version的包 |
package > version | 大于version的包 |
package >= version | 大于等于version的包 |
package <= version | 小于等于version的包 |
package = version | 等于version的包 |
package | 任意版本 |
6.3 先决依赖
先决(prerequisites)依赖和依赖类似,但是只有在该先决依赖安装的前提下,依赖它的包才会被安装。比如Tair依赖tbsys:
prereq: tbsys >= 2.0
6.4 构建依赖
有些依赖在构建的时候就需要满足,比如构建tbnet依赖tbsys,这可以使用buildRequires来指定,比如:
buildRequires: tbsys >= 2.0
和requires一样,还可以指定:
- buildConflicts
- buildPreReq
7 淘宝build定制化
ABS对rpmbuild进行了一些简单的封装,这里讲一下我在添加Tair的rpmbuild方式的时候遇到的一些问题。
7.1 需要的文件
由于是公司内部使用,所以做了一些约定,这些约定本身和rpm无关。
7.1.1 rpm目录
首先需要在源代码的目录下添加一个子目录,名称为rpm,比如在Tair中添加之后的目录结构为:
tair_src/ |-- AUTHORS |-- ChangeLog |-- Makefile.am |-- NEWS |-- README |-- bootstrap.sh |-- configure.ac |-- doc |-- etc |-- rpm ==================== 添加的rpm目录 `-- src
rpm目录通常包含以下文件:
tair_src/rpm/ |-- rpm_create |-- t-csrd-tair-VER.txt |-- t-csrd-tair-build.sh `-- t-csrd-tair.spec
文件 | 含义 |
---|---|
rpmcreate | 其中rpm_create是一个shell脚本,在写好配置文件后,运行它就可以执行build过程 |
t-csrd-tair-VER.txt | 版本写在这个目录中(不过我没有发现这个文件起作用) |
t-csrd-tair-build.sh | 可以将项目的build命令集中写在这里,但这个是可选的,如果不需要,不用管它 |
t-csrd-tair.spec | 这个便是spec文件了,是最重要的文件 |
7.2 一些特殊的地方
rpm_create脚本本身很简单,只是定义了一些变量,这些变量可以在spec文件中引用。
执行过后,rpm_create脚本会在用户的根目录下生成一个.rpmmacros文件,里面保留着这些变量。但是再次执行的时候却不会读取这个文件,Orz。
rpm_调用rpmbuild -bb $target –buildroot $BUILD_ROOT $i来最终生成rpm包。然后将包移动到rpm目录下。
spec文件本身还是一个标准的spec文件,只是这里会使用rpm_create定义的一些变量。例如:
Version: %{version} #使用rpm_create中定义的version变量
%description Tair is a high performance, distribution key/value storage system. %{_svn_path} %{_svn_revision}
这里的”svnpath”和”svnrevision”用于和hudson平台的配合。
找了相关资料
http://www.linuxsir.org/bbs/showthread.php?t=54788
介绍了 rpmbuild 和相关的制作工具
首先 sudo yum install rpmdevtools
依赖性会自动装上 rpmbuild
然后就是写 spec文件了
进入 ~/rpmbuild/SPEC
用 rpmdev-newspec 建立一个 newpackage.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 $RPM_BUILD_ROOT
make install DESTDIR=$RPM_BUILD_ROOT
%clean
rm -rf $RPM_BUILD_ROOT
%files
%defattr(-,root,root,-)
%doc
%changelog
────────────────────────────────────
简单的介绍一下 填写相关信息就可以了 制作了一个 conky.spec
────────────────────────────────────
Name: conky
Version: 1.4.2
Release: 1%{?dist}
Summary: conky
Group: User Interface/X
License: GPLv2
URL: www.conky.org
Source0: %{name}-%{version}.tar.bz2
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
BuildRequires: fontconfig
Requires: fontconfig
%description
%prep
%setup -q
%build
%configure
make %{?_smp_mflags}
%install
rm -rf $RPM_BUILD_ROOT
make install DESTDIR=$RPM_BUILD_ROOT
%clean
rm -rf $RPM_BUILD_ROOT
%files
%defattr(-,root,root,-)
%doc
%{_bindir}/*
%changelog
──────────────────────────────────────────
开始的时候主要是一些语法错误 后来更正之后 发现 打包出来的rpm 是空的 郁闷死了 弄了好长时间也没发现什么错误 一行行的看 最后才发现 原来 %doc下面少了要打包的文件
加上 %{_bindir}/* 就好了 同样 可以加上
%{_infodir}/*
%{_mandir}/*
%{_datadir}/×
不然打出来的就是空包了 我郁闷了好久
中间遇到了 error: Installed (but unpackaged) file(s) found: 解决的办法是
找到 /usr/lib/rpm/macros 中
%__check_files /usr/lib/rpm/check-files %{buildroot} 注释掉
发现网上讲的 %_unpackaged_files_terminate_build 1 不管用