一个 RPM spec 文件能否“包含”其他文件?

11

在RPM规范中是否有一种"包含"指令?我通过谷歌搜索没有找到答案。

动机: 我有一个RPM规范模板,构建过程会修改版本、修订和其他构建相关数据。目前是通过sed实现的。如果规范可以#include一个特定的生成文件,就不需要在规范中进行搜索和替换,这样可能更加清晰。

如果没有include,那么有没有一种惯用的方法来完成这个任务(我相信这是相当常见的)?

7个回答

20

足够新的rpmbuild版本肯定支持%include:

%include common.inc

不幸的是,它们对此并不十分聪明--例如,没有已知的目录集,可以在其中查找请求的文件。但它确实存在,并且变量会被扩展,例如:

%include %{_topdir}/Common/common.inc

1
谢谢Misha,幸运的是这现在已经交给一个合适的CM处理了 :) - davka
1
如果有人能够评论从哪个版本开始完全支持%include,那将非常感激。 - Daniel Szalay
1
我能找到的最早提到%include的地方是在4.8版本的发布说明中,这意味着修复了一个已经存在的功能。4.4.x、4.6和4.7版本的发布说明根本没有提到%include,这意味着该功能最迟在2005年7月的4.4.2版本中引入。截至2018年,如果您的RPM不支持%include,那么我认为安全地假设它严重需要升级。 - chepner

7

RPM不支持包含操作。

我曾用m4宏处理器或者简单地将spec文件的各个部分连接在一起(当“include”位于开头时)来解决类似的问题。

如果你只需要在构建时传递几个变量,而不是从另一个文件中包含多行内容,可以运行:

rpmbuild --define 'myvar SOMEVALUE' -bb myspec.spec

并且你可以在规格中使用%myvar。


“--define” 是我感觉应该存在的第二个直观解决方案。 - davka
谢谢!在我的rpmbuild(4.9.1.1)版本中,“--define”没有文档记录,但它确实有效。我寻找类似的东西已经好几个小时了!!! - DavidGamba
2
最近的rpm 4.12+支持加载宏文件,例如您可以执行类似于%{?load:%{SOURCE1}}的操作。请参见http://pkgs.fedoraproject.org/cgit/ruby.git/tree/ruby.spec?id=b9da2e689a47e432a4272b43c849a9a818965bbb#n92 - Muayyad Alsadi

5
我最近也遇到了同样的问题。我想定义多个类似但每个都有微小差异(它们是特定于语言的RPM)的子包。我不想为每个子包重复相同的样板内容。

这是我所做的一般化版本:

%define foo_spec() %{expand:%(cat '%{myloc}/main-foo.spec')}
%{foo_spec bar}
%{foo_spec baz}
%{foo_spec qux}

使用%{expand}确保只有在定义宏时执行一次%(cat)。然后,主-foo.spec文件的内容会重复三次,每次%1在主-foo.spec文件中会依次扩展为barbazqux,使我可以将其视为模板。如果需要(我没有需要),您可以轻松扩展到多个参数。

4
对于这个基本问题,我所知道的所有rpm版本中可能还有两个额外的解决方案。
  1. 子包
  2. rpmrc文件。

子包

另一个选择(也许是"RPM方式")是使用子包Maximum RPM 也提供了有关子包的信息和示例。

我认为问题是在尝试构建类似于以下结构的东西:

  • 两个spec文件;比如说rpm_debug.specrpm_production.spec
  • 两者都使用%include common.spec

debugproduction也可以是clientserver,等等。对于重新定义变量的示例,每个子包可以有其自己的变量列表。

限制

子包的主要优点是只进行一次构建;这也可能是一个缺点。 debugproduction的示例可能会强调这一点。可以使用strip来创建变体,或者使用不同输出编译两次;可能要使用Gnu Make中的VPATH)。必须编译大型软件包,然后只有简单的变化,如带/不带开发人员信息,如headers静态库等,才能使您欣赏此方法。

宏和Rpmrc

子包不能解决您希望适用于整个rootfs层次结构或更大的RPM集合的结构性定义问题。我们可以使用rpmbuild --showrc解决这个问题。您可以通过在运行rpmrpmbuild时更改rpmrcmacros来定义大量变量。来自man页面:

   rpmrc Configuration
       /usr/lib/rpm/rpmrc
       /usr/lib/rpm/redhat/rpmrc
       /etc/rpmrc
       ~/.rpmrc

   Macro Configuration
       /usr/lib/rpm/macros
       /usr/lib/rpm/redhat/macros
       /etc/rpm/macros
       ~/.rpmmacros

我认为这两个特性可以解决所有 %include 的问题。然而,%include 是一个熟悉的概念,很可能是为了使 rpm 更加全面和开发者友好而添加的。

3

您可以从SOURCES目录(%_sourcedir)包含*.inc文件:

Source1: common.inc

%include %{SOURCE1}

通过这种方式,它们将自动进入SRPMS


1
这很像МішаDigitalsky的回答。我认为它只适用于较新的rpm版本;所以如果你有一个较新的rpm,问题就解决了。 - artless noise

3
你所说的是哪个版本?我目前在我的spec文件中使用了%include filename.txt,它看起来就像C语言的#include指令一样。
> rpmbuild --version
RPM version 4.8.1

1

我使用脚本(请列出您喜欢的脚本)来从模板创建规范文件。此外,%files标签可以导入由其他进程创建的文件,例如Python的bdist-rpm


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接