openSUSE:Build Service prjconf

跳转到:导航搜索
Icon-obsolete.png 本文关于开放构建服务的文档已过时!
你可以在 https://openbuildservice.org/help/manuals/obs-user-guide/cha-obs-prjconfig 上找到最新的信息

描述

prjconf 表示一个项目的(构建)配置。该文件(/usr/lib/build/configs/$distro.conf)的主要部分是构建环境的定义。对于简单的项目,它可能为空。但是,通常需要用户决策(例如提供相同内容的软件包)或构建环境中特殊宏/软件包/标志的内容都定义在这里。

语法与 rpm 规范文件基本相同,只是标签不同。条件语句(如 %if%ifarch 等)也有效。

从 Web 界面,你可以进入“高级”选项卡,然后选择“项目配置”。使用 OSC,你可以执行

osc meta prjconf <项目名称>

一个非常相似的列表可以通过以下命令查看:

osc buildconfig <项目名称> <仓库名称>

查看 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”/“#!BuildIgnore”完成
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”行添加到规范文件
#!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 中定义。识别两个魔术字符串

  1. CI_CNT 是提交的数量
  2. 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 文件中可以使用两种宏定义选项

  1. 以 %define 开头的宏定义行用于 prjconf 本身以及计算规范文件的构建依赖项。它们在构建根目录中不可用。
  2. 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
目前,这些宏定义只能添加到 prjconf 的末尾。