2011-04-08

RPM打包step by step(2)

在源代码中打包

仍拿前面的helloworld举例,把spec文件放到开发目录下,修改去掉补丁文件,然后打包:
$ ls hello-0.2
hello.c  hello.spec  Makefile
$ tar zcvf hello-0.2.tar.gz hello-0.2
hello-0.2/
hello-0.2/Makefile
hello-0.2/hello.spec
hello-0.2/hello.c
接下来就要用到rpmbuild另一个很有用的参数了:-t,可以看一个rpmbuild的man:
$ man rpmbuild
NAME
       rpmbuild - Build RPM Package(s)

SYNOPSIS
   BUILDING PACKAGES:
       rpmbuild {-ba|-bb|-bp|-bc|-bi|-bl|-bs} [rpmbuild-options] SPECFILE ...

       rpmbuild {-ta|-tb|-tp|-tc|-ti|-tl|-ts} [rpmbuild-options] TARBALL ...

       rpmbuild {--rebuild|--recompile} SOURCEPKG ...

   MISCELLANEOUS:
       rpmbuild --showrc

...
rpmbuild通过-t参数来构建打包过的源程序。-ta就是构建rpm包和srpm包,-tb就是只构建二进制rpm包,-tp是只构建打过补丁的包,-ts是只构建srpm包。 好了,现在可以生成rpm包了:
$ rpmbuild -ta hello-0.2.tar.gz
如果使用git的话,就更方便了,因为Git提供了对任意分支打包的命令:git-archive。下面我们先使用git初始化我们的开发目录,然后使用git-archive来生成压缩包。
$ cd hello-0.2
$ git init
Initialized empty Git repository in /home/admin/work/hello-0.2/.git/
$ git add -A
$ git ci -m init
 3 files changed, 73 insertions(+), 0 deletions(-)
 create mode 100644 Makefile
 create mode 100644 hello.c
 create mode 100644 hello.spec
$ git archive --prefix=hello-0.2/ master|gzip > hello-0.2.tar.gz
$ ls
hello-0.2.tar.gz  hello.c  hello.spec  Makefile
通过 --prefix参数使当前master分支下文件打包到hello-0.2目录下,注意在文件夹名后面一定要有一个斜扛,否则就变成一般的文件名前缀了。 生成压缩包以后,就可以像之前一样使用rpmbuild来生成rpm包了。 使用这种方式编译rpm包,无疑给开发者带来了很多方便,尤其是使用git做版本控制的开发者。而且也比debian打包简单,debian打包需要一个debian目录,里面一大堆文件,而rpm打包,一切尽在一个spec文件中,经典! 接下来说说python程序包的制作,这个比较特殊。

python应用程序的RPM包制作

正如前面所见的,rpmbuild内置了很多宏,使得在写rpm包时方便很多。所有这些宏都在/usr/lib/rpm/macros中定义。 查看python相关的宏:
$ cat /usr/lib/rpm/macros | grep python
%__python               /usr/bin/python
%__python_provides      /usr/lib/rpm/pythondeps.sh --provides
%__python_requires      /usr/lib/rpm/pythondeps.sh --requires
#       at the python prompt for example, after "import rpm".
如上,在spec文件里可以使用%{__python}来调用系统python。 这里没有定义sitelib,我们一般在spec文件开头自定义:
%{!?python_sitelib: %define python_sitelib %(%{__python} -c "from distutils.sysconfig import get_python_lib; print get_python_lib()")}
可以看出,%()里面是shell命令,通过python的get_python_lib函数得到python的site lib路径。 此外,还有安装要求:
BuildRequires:  python-devel
%if 0%{?fedora} >= 8
BuildRequires: python-setuptools-devel
%else
BuildRequires: python-setuptools
%endif
在安装部分,可以使用%{__python}宏来进行安装:
%install
rm -rf $RPM_BUILD_ROOT
%{__python} setup.py install --root $RPM_BUILD_ROOT
--root $RPM_BUILD_ROOT的作用就是告诉setup.py安装到虚拟根上,类似前面的 RPM_INSTALL_ROOT=$RPM_BUILD_ROOT。 此外,这里还有一个INSTALLED_FILES标志可以使用,用来标记安装到系统中的文件,但来自fedoraproject的建议是,不提倡使用 INSTALLED_FILES,因为它只会标记文件,而不会标记目录,所以有可能遗漏。 打包文件列表部分写法如下:
%files
%defattr(-,root,root,-)
%attr(755,root,root) %{_bindir}/gistore
%{python_sitelib}/*
%doc /usr/share/doc/gistore/README
%doc /usr/share/doc/gistore/COPYING
%doc /usr/share/doc/gistore/CHANGELOG
%files部分列出要打包的文件和目录,可以使用前面的标记安装文件,但最好的方法就是把文件或目录手动列出来。 %defattr(-,root,root,-)代表使用默认的文件和目录权限 %{_bindir}是系统bin目录,具体为/usr/bin/,这个目录下的文件一般是可执行的。 %doc 代表文档,可以这样写::
%doc README COPYING CHANGELOG
这样的话,rpmbuild会从源码根目录下复制上述文件到/usr/share/doc/%{name}-%{version}/目录下,而按照前面的那种三行的写法的话,是自定义doc文件夹的位置,可以看出,自定义的doc文件夹名称没有版本号。 写完了以后就可以打包了,打包过程和前面无异。 下次有时间的话,会讲如何进行多个子包的打包~
blog comments powered by Disqus