Rpm Creating Subpackages
Spec File Changes For Subpackages
The creation of subpackages is based strictly on the contents of the spec file. This doesn't mean that you'll have to learn an entirely new set of tags, conditionals, and directives in order to create subpackages. In fact, you'll only need to learn one.
The primary change to a spec file is structural and starts with the definition of a preamble for each subpackage.
The Subpackage's "Preamble"
When we introduced RPM package building in Chapter 10, we said that every spec file contains a preamble. The preamble contains a variety of tags that define all sorts of information about the package. In a single package situation, the preamble must be at the start of the spec file. The spec file we're creating will have one there, too.
When creating a spec file that will build subpackages, each subpackage also needs a preamble of its own. These "sub-preambles" need only define information for the subpackage when that information differs from what is defined in the main preamble. For example, if we wanted to define an installation prefix for a subpackage, we would add the appropriate prefix tag to that subpackage's preamble. That subpackage would then be relocatable.
In a single-package spec file, there is nothing that explicitly identifies the preamble, other than its position at the top of the file. For subpackages, however, we need to be a bit more explicit. So we use the %package directive to identify the preamble for each subpackage.
The %package Directive
The %package directive actually performs two functions. As we mentioned above, it is used to denote the start of a subpackage's preamble. It also plays a role in forming the subpackage's name. As an example, let's say the main preamble contains the following name tag:
name: foo
|
Later in the spec file, there is a %package directive:
%package bar
|
This would result in the name of the subpackage being foo-bar.
In this way, it's easy to see the relationship of the subpackage to the main package (or other subpackages, for that matter). Of course, this naming convention might not be appropriate in every case. So there is an option to the %package directive for just this circumstance.
Adding -n To the %package directive
The -n option is used to change the final name of a subpackage from <mainpackage>-<subpackage> to <subpackage>. Let's modify the %package directive in our example above to be:
%package -n bar
|
The result is that the subpackage name would then be bar instead of foo-bar.
Updating Our Spec File
Let's apply some of our newly found knowledge to the spec file we're writing. Here's the list of subpackages that we need to create:
- The server subpackage, to be called foo-server.
- The client subpackage, to be called foo-client.
- The baz development library subpackage, to be called bazlib.
Since our package name is foo, and since the %package directive creates subpackage names by prepending the package name, the %package directives for the foo-server and foo-client subpackages would be written as:
%package server |
Since the baz library's package name is not to start with foo, we need to use the -n option on its %package directive:
%package -n bazlib
|
Our requirements further state that foo-server and foo-client are to have the same version as the main package.
One of the time-saving aspects of using subpackages is that there is no need to duplicate information for each subpackage if it is already defined in the main package. Therefore, since the main package's preamble has a version tag defining the version as 2.7, the two subpackages that lack a version tag in their preambles will simply inherit the main package's version definition.
Since the bazlib subpackage's preamble contains a version tag, it must have its own unique version.
In addition, each subpackage must have its own summary tag.
So based on these requirements, our spec file now looks like this:
Name: foo |
We can see the subpackage structure starting to appear now.
Required Tags In Subpackages
There are a few more tags we should add to the subpackages in our example spec file. In fact, if these tags are not present, RPM will issue a most impressive warning:
# rpmbuild -ba foo-2.7.spec* Package: foo |
Our spec file is incomplete. The bottom line is that each subpackage must have these three tags:
- The %description tag.
- The group tag.
- The summary tag.
It's easy to see that the first two tags are required, but what about summary? Well, we lucked out on that one: we already included a summary for each subpackage in our example spec file.
Let's take a look at the %description tag first.
The %description Tag
As you've probably noticed, the %description tag differs from other tags. First of all, it starts with a percent sign. Secondly, its data can span multiple lines. The third difference is that the %description tag must include the name of the subpackage it describes. This is done by appending the subpackage name to the %description tag itself. So given these %package directives:
%package server |
our %description tags would start with:
%description server |
Notice that we've included the -n option in the %description tag for bazlib. This was intentional, as it makes the name completely unambiguous.
Our Spec File So Far…
OK, let's take a look at the spec file after we've added the appropriate %descriptions, along with group tags for each subpackage:
Name: foo |
Let's take a look at what we've done. We've created a main preamble as we normally would. We then created three additional preambles, each starting with a %package directive. Finally, we added a few tags to the subpackage preambles.
But what about version tags? Aren't the server and client subpackages missing them?
Not really. Remember that if a subpackage is missing a given tag, it will inherit the value of that tag from the main preamble. We're well on our way to having a complete spec file, but we aren't quite there yet.
Let's continue by looking at the next part of the spec file that changes when building subpackages.
The %files List
In an ordinary single-package spec file, the %files list is used to determine which files are actually going to be packaged. It is no different when building subpackages. What is different, is that there must be a %files list for each subpackage.
Since each %files list must be associated with a particular %package directive, we simply label each %files list with the name of the subpackage, as specified by each %package directive. Going back to our example, our %package lines were:
%package server |
Therefore, our %files lists should start with:
%files server |
In addition, we need the main package's %files list, which remains unnamed:
%files
|
The contents of each %files list is dictated entirely by the software's requirements. If, for example, a certain file needs to be packaged in more than one package, it's perfectly all right to include the filename in more than one list.
Controlling Packages With the %files List
The %files list wields considerable power over subpackages. It's even possible to prevent a package from being created by using the %files list. But is there a reason why you'd want to go to the trouble of setting up subpackages, only to keep one from being created?
Actually, there is. Take, for example, the case where client/server-based software is to be packaged. Certainly, it makes sense to create two subpackages: one for the client and one for the server. But what about the main package? Is there any need for it?
Quite often there's no need for a main package. In those cases, removing the main %files list entirely will result in no main package being built.
A Point Worth Noting
Please keep in mind that an empty %files list (ie, a %files list that contains no files) is not the same as not having a %files list at all. As we noted above, entirely removing a %files list results in RPM not creating that package. However, if RPM comes across a %files list with no files, it will happily create an empty package file.
This feature (which also works with subpackage %files lists) comes in handy when used in concert with conditionals. If a %files list is enclosed by a conditional, the package will be created (or not) based on the evaluation of the conditional.
Our Spec File So Far…
Ok, let's update our example spec file. Here's what it looks like after adding each of the subpackages' %files lists:
Name: foo |
As you can see we've added %files lists for:
- The main foo package.
- The foo-server subpackage.
- The foo-client subpackage.
- The bazlib subpackage.
Each package contains a single file. [1] If there was no need for a main package, we could simply remove the unnamed %files list. Keep in mind that even if you do not create a main package, the tags defined in the main package's preamble will appear somewhere — specifically, in the source package file.
Let's look at the last subpackage-specific part of the spec file: the install- and erase-time scripts.
Install- and Erase-time Scripts
The install- and erase-time scripts, %pre, %preun, %post, and %postun, can all be named using exactly the same method as was used for the other subpackage-specific sections of the spec file. The script used during package verification, %verifyscript, can be made package-specific as well. Using the subpackage structure from our example spec file, we would end up with script definitions like:
- %pre server
- %postun client
- %preun -n bazlib
- %verifyscript client
Other than the change in naming, there's only one thing to be aware of when creating scripts for subpackages. It's important that you consider the possibility of scripts from various subpackages interacting with each other. Of course, this is simply good script-writing practice, even if the packages involved are not related.
Back At the Spec File…
Here we've added some scripts to our spec file. So that our example doesn't get too complex, we've just added preinstall scripts for each package:
Name: foo |
As pre-install scripts go, these don't do very much. But they will allow us to see how subpackage-specific scripts can be defined.
Those of you that have built packages before probably realize that our spec file is missing something. Let's add that part now.
Building Subpackages
Now it's time to give our example spec file a try. The build process is not that much different from a single-package spec file:
# rpmbuild -ba foo-2.7.spec* Package: foo |
Starting at the top, we start the build with the usual command. Immediately following the command, RPM indicates that four packages are to be built from this spec file. The %prep, %build, and %install scripts then execute as usual.
Next, RPM executes its "special doc" internal script, even though we haven't declared any files to be documentation. It's worth noting, however, that the DOCDIR environment variables show that if the spec file had declared some of the files as documentation, RPM would have created the appropriate documentation directories for each of the packages.
At this point, RPM creates the binary packages. As we can see, each package contains the file defined in its %files list.
Finally, the source package file is created. It contains the spec file and the original sources, just like any other source package.
One spec file. One set of sources. One build command. Four packages. [1] All in all, a pretty good deal, isn't it?
Giving Subpackages the Once-Over
Let's take a look at our newly created packages. As with any other package, each subpackage should be tested by installing it on a system that has not had that software installed before. In this section, we'll just snoop around the subpackages and point out how they differ from packages built one to a spec file.
First, let's just look at each package's information:
# rpm -qip foo-2.7-1.i386.rpmName : foo Distribution: (none) |
Here we've used RPM's query capability to display a list of summary information for each package. A few points are worth noting.
First, each package lists foo-2.7-1.src.rpm as its source package file. This is the only way to tell if two package files were created from the same set of sources. Trying to use a package's name as an indicator is futile, as the bazlib package shows us.
The next thing to notice is that the summaries and descriptions for each package are specific to that package. Since these tags were placed and named according to each package, that should be no surprise.
Finally, we can see that each package's version has been either "inherited" from the main package's preamble, or, as in the case of the bazlib package, the main package's version has been overridden by a version tag added to bazlib's preamble.
If we look at the source package's information, we see that its information has been taken entirely from the main package's set of tags:
# rpm -qip foo-2.7-1.src.rpmName : foo Distribution: (none) |
It's easy to see that if there was no %files list for the main package, and therefore, no main package, the tags in the main preamble would still be used in the source package. This is why RPM enforces the requirement that the main preamble contain copyright, %description, and group tags. So, here's a word to the wise: Don't put something stupid in the main preamble's %description just to satisfy RPM. Your witty saying will be immortalized for all time in every source package you distribute. [2]
Verifying Subpackage-specific Install and Erase Scripts
The easiest way to verify that the %pre scripts we defined for each package were actually used is to simply install each package:
# rpm -Uvh foo-2.7-1.i386.rpmfoo This is the foo package preinstall script |
As expected, the unique %pre script for each package has been included. Of course, if we hadn't wanted to actually install the packages, we could have used RPM's --scripts option to display the scripts:
# rpm -qp --scripts foo-2.7-1.i386.rpmpreinstall script: |
This approach might be a bit safer, particularly if installing the newly built package would disrupt operations on your build system.
Rpm Creating Subpackages的更多相关文章
- s3-sftp-proxy goreleaser rpm &&deb 包制作
上次写过简单的s3-sftp-proxy基于容器构建以及使用goreleaser构建跨平台二进制文件的,下边演示下关于 rpm&&deb 包的制作,我们只需要简单的配置就可以生成方便安 ...
- docker- 构建 oracle2c-r2(12.2.0.1) 的镜像
需求 由于公司要数据库需要使用新的oracle版本(12c-r2 ->12.2.0.1),需要从之前的oracle11g迁移到12c.所以,我们今天就先来介绍一下如何构建oracle12c的镜像 ...
- Elasticsearch 及 Kibana 安装篇
简介 官网-安装介绍 这里记载了各个软件包的安装方法,Linux Mac Windows-- 本文记载的是在 CentOS 系统安装 Elasticsearch 7.0.0 版本的步骤. 安装 Jav ...
- Creating a Mono 3 RPM on CentOS
Creating a Mono 3 RPM on CentOS A quick guide to creating an rpm of mono 3 from source, starting wit ...
- OpenStack RPM Sample 解析
目录 文章目录 目录 前言 RPM 打包环境安装 RPM 打包流程 OpenStack RPM SPEC Sample RPM 升级/回退 前言 软件功能升级,尤其是 Python 这类解析型语言的软 ...
- 制作nginx和php的rpm包
rpm包的制作真几把烦,制作php的rpm花了我3天时间,因为是根据线上环境来做的,依赖的第三方库太多,本来想把所有的第三方库做进php包,后来发现在rpmbuild -bb的时候非常耗时,而且乱七八 ...
- RPM软件包管理的查询功能
以后大家升级rpm包的时候,不要用Uvh了! 我推荐用Fvh 前者会把没有安装过得包也给装上,后者只会更新已经安装的包 总结:未安装的加上小写p,已安装的不需要加p 查询q rpm {- ...
- linux 下 安装 rpm 格式 的 mysql
在Linux操作系统下,安装MYSQL有两种方式: 一种tar安装方式, 另外一种是rpm安装方式. 这两种安装方式有什么区别呢?尽管我们在Linux下常用tar来压缩/解压缩文件,但MYSQL的ta ...
- centos7.2下安装mysql5.7,使用rpm包安装
0.环境 本文操作系统: CentOS 7.2.1511 x86_64 MySQL 版本: 5.7.16 1.卸载系统自带的 mariadb-lib[root@centos-linux ~]# rpm ...
随机推荐
- 刷完欧拉计划中难度系数为5%的所有63道题,我学会了Rust中的哪些知识点?
我为什么学Rust? 2019年6月18日,Facebook发布了数字货币Libra的技术白皮书,我也第一时间体验了一下它的智能合约编程语言MOVE,发现这个MOVE是用Rust编写的,看来想准确理解 ...
- server 2012 r2 配置
filezilla的问题还是让人摸不着头脑,配置和别的机器上一样就是报STL权限错误,最后换了个端口就连上了. 服务器,填远端IP,被动模式打开,生成一个证书,被动模式的商品一定要在入站规则里 客户端 ...
- mac os 使用 from scipy.misc import imread ImportError: cannot import name 'imread'
mac os 使用 from scipy.misc import imread ImportError: cannot import name 'imread' 问题1: 我原先安装了 pillow ...
- Loj #3102. 「JSOI2019」神经网络
Loj #3102. 「JSOI2019」神经网络 题目背景 火星探险队发现,火星人的思维方式与人类非常不同,是因为他们拥有与人类很不一样的神经网络结构.为了更好地理解火星人的行为模式,JYY 对小镇 ...
- Intellij IDEA的安装教程
一.下载安装 1.打开官网:http://www.jetbrains.com/idea/,点击页面中的“DOWNLOAD” 2.根据自己的需要选择下载的IntelliJ IDEA版本,此处我的电脑是W ...
- Spring Boot 一个依赖搞定 session 共享,没有比这更简单的方案了!
有的人可能会觉得题目有点夸张,其实不夸张,题目没有使用任何修辞手法!认真读完本文,你就知道松哥说的是对的了! 在传统的单服务架构中,一般来说,只有一个服务器,那么不存在 Session 共享问题,但是 ...
- WPF 精修篇 获取系统颜色和字体样式
原文:WPF 精修篇 获取系统颜色和字体样式 看效果 <Grid> <Rectangle Fill="{DynamicResource {x:Static SystemCo ...
- Client 客户端AspNetCore.SignalR 通讯服务器 Quartz 执行任务
背景 需要Client跑服务在终端间隔执行任务,我的目标是运行在树莓派上 Client代码 如果未连接成功时隔3秒重新连接服务器 public static void Reconnect() { va ...
- PIE 插件式开发小笔记__PIESDK学习体会
基于PIE.NET-SDK插件式二次开发文档笔记: PIE 插件式开发配置文件: 它里面一行如下: 理解上一行'Item'关系-> library:为插件类名(程序集名称+后缀 ...
- PIE截图方法的优化
因为我们组的项目要通过截图获取数据,所以要经常使用截图工具,之前截图都是根据教程(https://www.cnblogs.com/PIESat/p/10243308.html)用的地图显示范围截图,而 ...