标签 RPM打包step by step(1) 下的文章 - 酷游博客
首页
关于
友链
Search
1
阿里的简历多久可以投递一次?次数多了有没有影响?可以同时进行吗?
46 阅读
2
Java中泛型的理解
41 阅读
3
Java 14 发布了,再也不怕 NullPointerException 了!
38 阅读
4
Java中的可变参数
37 阅读
5
该如何创建字符串,使用" "还是构造函数?
30 阅读
技术
登录
/
注册
找到
1
篇与
RPM打包step by step(1)
相关的结果
2025-01-22
[转]RPM打包step by step
原文地址:http://www.worldhello.net/2011/04/02/2405.html 最近学习rpm打包,参考ibm文档库里rpm打包的文章,结合自己的实践,总结如下,一来备忘,二来和大家交流。 和deb打包不同,rpm打包需要特定的目录及结构。查看rpm打包目录,以下为在CentOS5.5下的输出结果: $ rpm --showrc|grep _topdir -14: _builddir %{_topdir}/BUILD -14: _rpmdir %{_topdir}/RPMS -14: _sourcedir %{_topdir}/SOURCES -14: _specdir %{_topdir}/SPECS -14: _srcrpmdir %{_topdir}/SRPMS -14: _topdir %{_usrsrc}/redhat $ rpm --showrc|grep _usrsrc -14: _topdir %{_usrsrc}/redhat -14: _usrsrc %{_usr}/src $ rpm --showrc|grep _usr -14: _defaultdocdir %{_usr}/share/doc -14: _topdir %{_usrsrc}/redhat -14: _usr /usr -14: _usrsrc %{_usr}/src 经过层层寻找,最终发现打包目录在/usr/src/redhat目录下,看看目录结构: $ tree /usr/src/redhat /usr/src/redhat |-- BUILD |-- RPMS | |-- athlon | |-- geode | |-- i386 | |-- i486 | |-- i586 | |-- i686 | `-- noarch |-- SOURCES |-- SPECS `-- SRPMS 其中BUILD存放编译生成的临时文件,RPMS存放根据各种构架生成的rpm包,SOURCES存放源码包,SPECS存放spec文件,SRPMS存放生成的SRPM包。 最简单例子 下面以hello world为例,构建一个最小化打包过程。 首先需要写一个SPEC文件hello.spce: Summary: hello world rpm package Name: hello Version: 0.1 Release: 1 Source: hello-0.1.tar.gz License: GPL Packager: amoblin Group: Application URL: http://www.ossxp.com %description This is a software for making your life more beautiful! %prep %setup -q %build gcc -o hello hello.c %install install -m 755 hello /usr/local/bin/hello %files /usr/local/bin/hello 放到上述SPECS目录下。 然后一个源程序hello.c: #include int main() { printf("Hello, World!\n"); return 0; } 存放在hello-0.1目录,然后打包放到SOURCES目录: $ tar zcvf hello-0.1.tar.gz hello-0.1 hello-0.1/ hello-0.1/hello.c $ sudo mv hello-0.1.tar.gz /usr/src/redhat/SOURCES 在SPECS目录下使用rpmbuild进行打包: $ cd /usr/src/redhat $ sudo rpmbuild -ba hello.spec ... Wrote: /usr/src/redhat/SRPMS/hello-0.1-1.src.rpm Wrote: /usr/src/redhat/RPMS/i386/hello-0.1-1.i386.rpm 这时会逐个运行hello.spec文件的内容,最终生成两个文件,一个包含源码的rpm包和一个二进制rpm包。 使用 -bs 选项只生成源码rpm包;使用 -bb 选项只生成rpm包。 查看rpm包信息和包内容: $ rpm -qpi ../RPMS/i386/hello-0.1-1.i386.rpm $ rpm -qpl ../RPMS/i386/hello-0.1-1.i386.rpm 第一个命令的输出是spec文件的序言部分的内容,第二个命令的输出是%files部分的文件列表。 现在有个问题,打包目录在/usr/src/redhat下,需要root权限才能操作,太不方便了,能不能在用户自定义目录下打包呢? 自定义打包目录 我们可以通过修改topdir宏的值来自定义打包路径: $ echo %_topdir $HOME/rpmbuild > ~/.rpmmacros 这样再查看topdir的值会发现已变为用户主目录下rpm子目录了。这时修改文件就方便多了。 但在执行rpmbuild时仍会出问题: $ rpmbuild -ba hello.spec ... install: 无法删除 “/usr/local/bin/hello”: 权限不够 error: Bad exit status from /var/tmp/rpm-tmp.65773 (%install) ... 这是因为rpmbuild在构建rpm包时会将程序安装一遍,然后再提取安装文件。由于需要复制二进制文件hello到系统目录/usr/local/bin/下,所以普通用户执行就报错了。 那么怎么办呢?这里需要使用虚拟根了。 修改spec文件,在Description段落前,URL字段之后增加一行: BuildRoot: %{_builddir}/%{name}-root 修改install段落,将绝对安装路径改为使用构建根的方式:: %install mkdir -p $RPM_BUILD_ROOT/usr/local/bin install -m 755 hello $RPM_BUILD_ROOT/usr/local/bin/hello 通过BuildRoot的值告诉rpmbuild,我们的构建根是builddir下的hello-root目录。其中以%{}括起来的是RPM宏,_builddir代表~/rpmbuild/BUILD目录;name代表spec文件开头的Name字段值。 以下划线开头的builddir是系统RPM宏,我们可以通过rpm --showrc看到,可以在.rpmmacros中自定义。 RPM_BUILD_ROOT和前面的宏不同,这里没有{}括起来,是为了在以后安装生成的rpm时不至于也去寻找传说中的构建根。 如果喜欢的话,可以修改Source字段如下:: Source: %{name}-%{version}.tar.gz 好,继续回到构建根。现在执行rpmbuild,会在BUILD下创建hello-root目录作为虚拟根,hello安装在其中的usr/local/bin目录下。使用Makefile 一般源程序都使用Makefile的,因此我们再进一步,添加一个Makefile文件,在spec里使用make来编译。 简单的Makefile文件如下: SRC = hello.c hello: $(SRC) gcc $^ -o $@ clean: rm -f hello install: -mkdir -p $(RPM_INSTALL_ROOT)/usr/local/bin/ install -m 755 hello $(RPM_INSTALL_ROOT)/usr/local/bin/hello 由于使用了Makefile,我们最好升级一下版本号,将原先的hello-0.1目录复制为hello-0.2目录,放入Makefile文件。 修改spec文件,更新版本号,同时将build和install部分用make替换:: Version: 0.2 ... %build make %install RPM_INSTALL_ROOT=$RPM_BUILD_ROOT make install ... 这里将构建根参数传递给Makefile,从而将程序安装在指定的根目录下。 如果喜欢做事不留痕的话,可以在install段落后面增加clean段,清理生成的虚拟根: %clean rm -rf $RPM_BUILD_ROOT 使用补丁文件 有很多源码包里都有补丁文件,在打包时要先打补丁,这也要在spec文件里告诉rpmbuild一声才行。 复制hello-0.2一份,随便修改一个hello.c,和原目录做比较,生成补丁文件: $ cp -r hello-0.2 hello-0.2.my $ vi hello-0.2.my/hello.c $ diff -uNr hello-0.1 hello-0.2 > hello-0.1.patch 然后修改spec文件,增加Patch字段,以及在prep段落增加打补丁动作:: ... Patch0: %{name}-%{version}.patch ... %prep %setup -q %patch -p1 ... Patch0告诉rpmbuild这是一个补丁,如果补丁不止一个的话,可以通过Patch1,Patch2增加。 再次执行rpmbuild,生成rpm包。 查看SRPM包内容: $ rpm -qpl ../SRPMS/hello-0.2-1.src.rpm hello-0.2.patch hello-0.2.tar.gz hello.spec 补丁果然被打包进来了!在安装过程中使用脚本 可以使用%pre,%post,%preun,%postun段落来定义安装前后,卸载前后的脚本动作:: %pre echo This is pre for %{version}-%{release}: arg=$1 %post echo This is post for %{version}-%{release}: arg=$1 %preun echo This is preun for %{version}-%{release}: arg=$1 %postun echo This is postun for %{version}-%{release}: arg=$1 具体的脚本内容可自行替换。 打包rpm的过程就这么简单! 但上面这些方法一般都是针对打包者的,打包者不管以什么手段从任何地方得到了源代码包,然后保持一颗虔诚的心,恭恭敬敬地将之安放在rpmbuild/SOURCES目录下,然后天马行空,随意发挥或挥发,写下一篇洋洋洒洒的spec文件,对号入座到SPECS目录下,然后rpmbuild隆重出场,进行一系列生产加工,最终产生出来了传说中的rpm包和src.rpm包。 但,有时我们不总是打包者,更多时候我们是开发者,使用某种版本控制系统,比如Git,进行开发,最后的产品希望打包发布,还用上面的方式吗?不行,太麻烦了~ 那怎么办呢?欲知结果,敬请期待,清明之后见分晓~Related
技术
# RPM打包step by step(1)
酷游
1月22日
0
21
0
易航博客