openSUSE:Build Service prjconf
| 本文关于开放构建服务的文档已过时! 你可以在 https://openbuildservice.org/help/manuals/obs-user-guide/cha-obs-prjconfig 上找到最新的信息 |
描述
prjconf 表示一个项目的(构建)配置。该文件(/usr/lib/build/configs/$distro.conf)的主要部分是构建环境的定义。对于简单的项目,它可能为空。但是,通常需要用户决策(例如提供相同内容的软件包)或构建环境中特殊宏/软件包/标志的内容都定义在这里。
语法与 rpm 规范文件基本相同,只是标签不同。条件语句(如 %if、%ifarch 等)也有效。
从 Web 界面,你可以进入“高级”选项卡,然后选择“项目配置”。使用 OSC,你可以执行
一个非常相似的列表可以通过以下命令查看:
查看 openSUSE:Factory 项目的配置,可以了解可能实现的功能。有关详细用法,请参阅 osc help meta。
Preinstall + Required + Support + Packages from dependency expansion.
支持的标签
冲突
如果 pkg A 提供 pkg1 pkg2 pkg3,例如用于引导,如果你设置 Prefer: pkg1,pkg1 将在 pkg 之前安装,但由于需要 pkg2,pkg 将被安装,并且它将与 pk1 冲突。解决方案是从一开始就安装 pkg,直到 pkg1、pkg2、pkg3 完全构建完成。OBS 求解器尚未支持此功能。作为解决方法,你可以显式定义冲突。
Conflict:<pkg> <pkg1> ...
预安装
需要在构建环境设置中解包的软件包。基本上,这是运行 rpm/dpkg 所需的一切,例如 glibc 等。
Preinstall: filesystem fillup glibc
"安装" chroot 环境中的文件系统软件包,以便 rpm/dpkg 能够工作。如果用 ! 前缀一个软件包名称,它将取消选择 Preinstall: 中的软件包,并防止其安装。
运行脚本
预安装软件包的一个子集。它描述了哪些软件包需要运行其 postinstall 脚本。
Runscripts: aaa_base
必需
这些软件包构成“正常”构建环境,例如 gcc、autoconf、automake 等。
Required: autoconf automake binutils
通过正常的包管理器(rpm/dpkg)安装 autoconf - 这是完成的方式。
支持
方便的软件包,例如“vim”或“strace”。与“必需”的区别在于,自动重建检测不会查看支持软件包,也就是说,如果“strace”发生更改,你不会获得自动重建。
此列表还包括一些“-devel”软件包和“必需”软件包的其他子软件包,以保持“必需”列表较小。(例如,我们不需要在“必需”中同时使用“zlib”和“zlib-devel”,因为两者都是从同一个源代码构建的)。
Support: vim strace glibc-devel
要从继承的配置(例如 openSUSE:11.3)中删除支持软件包,请使用
Support: !build-compare
保留
我们确实需要这些软件包。通常,我们想要构建的软件包的子软件包不会被安装。但是,即使我们想要构建“patch”软件包,我们也需要一个可用的 patch 程序来应用规范文件中的补丁。因此,我们有“保留:patch”。预安装的软件包会自动添加到此列表中。
Keep: gdbm glibc-devel glibc-locale
偏好
此信息用于打破歧义。
忽略一个软件包(存在“have choice”问题)
Prefer: -suse-build-key
选择一个软件包
Prefer: openSUSE-build-key
这也可以在软件包级别完成
Prefer: tomboy:gconf-sharp
对于来自二进制软件包 tomboy 的依赖项,选择 gconf-sharp。以下错误消息会告诉你,这来自二进制软件包 tomboy:have choice for gconf needed by tomboy: gconf gconf-sharp gconf-blunt;类似的错误消息,但没有“needed by ...”部分,表明问题来自你的规范文件。
BuildRequires: openSUSE-Build-key #!BuildIgnore: suse-build-key
一个 BuildRequires: java-devel >= 1.7.0 也可以触发 have-choice-error(例如,在 java-1_7_0-openjdk-devel 和 java-1_7_0-ibm-devel 之间)。这可以通过项目范围内的
Prefer: java-1_7_0-openjdk-devel
但不能通过
Prefer: PACKAGENAME:java-1_7_0-openjdk-devel
对于特定于软件包的解决方案,你必须完善规范文件中的 BuildRequires:
替换
软件包在不同的发行版中可能会被重命名或命名不同。你可以为每个仓库指定依赖项重写规则。
%if 0%{?fedora_version}
Substitute: pwdutils shadow-utils
%endif
一个简单的替换就像这样Requires: libkde4-devel >= 4.4行转换为Requires: kdelibs-devel >= 4.4,需要为替换软件包指定尾随等号
%if 0%{?suse_version}
Substitute: libkde4-devel kdelibs-devel=
%endif
%if 0%{?fedora_version}
Substitute: kdelibs-devel libkde4-devel=
%endif
在 openSUSE 上,软件包名为“libkde4-devel”,因此将所有对“kdelibs-devel”的要求替换为“libkde4-devel”——反之亦然,对于 Fedora。
如果“替换”只带一个参数使用,则对给定软件包的依赖项将被完全忽略
Substitute: glibc-devel-32bit
忽略
这会破坏软件包扩展步骤的依赖项。这意味着,如果另一个软件包通常需要(Requires)它,我们不需要安装一个软件包。
Ignore: portmap:syslogd
如果我们必须安装 portmap 软件包,我们不需要安装 syslogd。
#!BuildIgnore: syslogd
导出过滤器
将构建的二进制软件包从一个架构复制到另一个架构。这主要用于仅在一个架构上可用,但其他架构至少可以模拟该软件包架构的软件包。
ExportFilter: ^wine.*\.i586.rpm$ . x86_64
将构建的 wine 软件包复制到 i586 和 x86_64。点表示构建它的“当前”架构。默认情况下,软件包始终至少复制到它们自己的架构,即
ExportFilter: .+ .
除非被 ExportFilter 行覆盖,否则会隐式生效。指定没有目标在正则表达式之后的效果是完全不向工作站提供文件,例如使用
ExportFilter: -debuginfo-.*\.rpm$ ExportFilter: -debugsource-.*\.rpm$
发布过滤器
与 ExportFilter 类似,PublishFilter 控制将构建的软件包复制到仓库空间(例如 /srv/obs/repos)。
顺序
某些发行版在 chroot 设置期间遇到循环依赖项时可能会出现问题,例如 A 依赖于 B,而 B 依赖于 A。在这种情况下,安装程序无法知道先安装哪个,需要手动干预。使用此“顺序”标签,你可以指定安装顺序。
你可能会看到如下消息
cycle: libgtk2.0-0 -> libgtk2.0-bin breaking dependency libgtk2.0-0 -> libgtk2.0-bin
如果先安装 libgtk2.0-bin 之前安装 libgtk2.0-0 时出现错误,则
Order: libgtk2.0-0:libgtk2.0-bin
将导致 libgtk2.0-0 在 libgtk2.0-bin 之前安装
请注意,循环可能更长 A->B->C->D->A,你可能需要说
Order C:D A B Order D:A B
这表示 D、A 和 B 依赖于 C,但它没有说明 A 和 B 的安装顺序。这需要另一个规则。
另一个例子
Order: libopenssl0_9_8:openssl-certs
如果需要安装 openssl-certs,请先安装 libopenssl0_9_8。
VM安装
就像 支持 一样:如果你在虚拟机中“构建”,则添加这些软件包。
VMinstall: util-linux perl-base libdb-4_5 libvolume_id1 libsepol1
优化标志
默认编译器标志。(可以被规范文件覆盖。)
Optflags: i586 -march=i586 -mtune=i686 -fmessage-length=0
版本
构建服务会自动在规范文件中设置 Release 标签。Release 标签的格式可以在 prjconf 中定义。识别两个魔术字符串
- CI_CNT 是提交的数量
- B_CNT 是重建的数量(当触发重建时)。
默认设置是
Release: <CI_CNT>.<B_CNT>
假设 rpm 宏 %{release_prefix} 在规范文件中定义了一个自定义格式,如下所示
Release: %%{?release_prefix}.<CI_CNT>.<B_CNT>
相同的语法也可以直接在你的规范文件中使用。要插入一个硬编码的 release-prefix 'j123',你可以说
Release: j123.<CI_CNT>.<B_CNT>
文件提供者
构建服务出于性能原因会忽略 rpm 文件依赖项。由于这可能会破坏某些软件包,因此可以通过 prjconf 手动添加文件提供者。
示例:要让构建服务相信 '/usr/bin/perl' 由软件包 'camel' 提供,请使用以下行
FileProvides: /usr/bin/perl camel
宏
宏定义在 prjconf 的末尾(以避免误解)或在宏部分(在宏标签之间)
prjconf 文件中可以使用两种宏定义选项
- 以 %define 开头的宏定义行用于 prjconf 本身以及计算规范文件的构建依赖项。它们在构建根目录中不可用。
- Macros: 标签后的宏定义被导出到构建环境中用于构建软件包的用户 rpmmacros 文件中。也就是说,它们可用于规范文件中的常规用途。
%define Tag
像 rpm 一样使用 %define,用户可以定义变量及其关联值。
支持 rpm 语法提供的所有功能,但不包括
- 无法定义函数。
- 无法调用外部命令。
%define _with_pulseaudio 1
定义一个宏 %{_with_pulseaudio},其值为 1。例如,这对于在你的项目中启用 pulseaudio 非常有用。在这种情况下,你需要在你的脚本中测试变量的值。
%bcond
如果规范文件使用以下结构来启用条件构建
%bcond_with pulseaudio
%if %{with pulseaudio}
BuildRequires: pulseaudio-devel
%endif
那么你可以通过将以下内容放入 prjconf 来启用该选项
Macros: %_with_pulseaudio 1 :Macros
要实现相反的效果,不要将其设置为 0。相反
Macros: %_without_pulseaudio 1 :Macros
警告:该选项已启用,因为已定义该变量,而与变量的实际值无关。%define _with_pulseaudio 0 不会禁用 构建选项。
Macros: 标签后的宏
在宏部分或 prjconf 末尾定义的宏在构建过程中进行评估,与使用 %defined 定义的宏不同,后者由 OBS 用于在 rpm 构建之前计算依赖项。
Macros:
... 一些宏 ...
:Macros
在宏部分和/或 prjconf 末尾包含一个宏定义块,这些块被导出到构建环境。你基本上可以在这里定义任何内容,包括函数或调用外部命令的宏,因为这些宏实际上是由 rpmbuild 评估的。这里不需要 define 语句,所以只需从 %macroname 开始。
以简单的示例为例,不仅要告诉构建服务安装 pulseaudio-devel 软件包,还要让 rpmbuild 知道使用 pulseaudio 构建,需要将以下定义也放在宏块中
%_with_pulseaudio 1
警告
rpm 应该遵循共同商定的规则,这些规则不会测试给定变量的值,而是测试变量的存在。我建议使用与 %bcond 和 rpm 命令行值相同的值。
我还会添加将变量设置为“0”、“no”或“--without-xxx”仍然会激活该选项。
# To deactivate that option comment the following line (changing variable value will have no effect) %_with_pulseaudio --with-pulseaudio