openSUSE:构建服务跨分发行方法

跳转到:导航搜索

概述

本指南列出了使用一个 spec 文件处理不同发行版的特殊提示。它不是打包者的入门指南,请访问 构建服务教程 以获取更多信息。此外,本文档不涵盖使用 Debian 包 的发行版。

构建服务可以可靠地为 openSUSE 以及最新的 SLES、CentOS、Fedora、Red Hat Enterprise Linux、Ubuntu、Debian 和 Mandriva/Mageia 发行版打包 rpm。

有哪些限制? 实际的唯一限制是 Fedora 或 Mandriva 缺少某些依赖项,而这些依赖项可以轻松地通过链接或聚合到另一个构建服务项目来满足 SUSE 发行版。例如:构建需要最新版本 Qt4 或 GTK2 的 SUSE 包很容易,因为这些依赖项可以通过构建服务上其他仓库提供的为较旧的 SUSE 版本提供较新 Qt4 包的 backport 来满足,以及 SLES。只有通过在您自己的项目中打包所需的依赖项才能克服这一点。即使这样,只有当您希望支持尽可能多的发行版时,才会出现此问题。

您需要注意的发行版之间的差异

  • 安装桌面文件。这五个发行版中的每一个都使用略有不同的机制来安装桌面文件,然后创建菜单项。Mandriva 甚至有一个特殊的 rpm 宏 %update_menus 来完成此操作,它使用类似 Debian 的设置,与 SUSE 或 Fedora 不同。示例
%post
%update_menus

%postun
%clean_menus
  • 依赖项的包命名。请参阅下文有关如何在您的 spec 文件中实现此操作的更多具体提示和技巧。
  • rpm 宏的细微差别。使用下表显示的变化进行链接。

您能告诉我一个跨平台包的良好示例吗?

Amilcar 的 KDevelop 包

检测用于特殊代码的分发版风味

您可以添加

%if %{defined suse_version}
%if %{undefined suse_version}

或者更可移植的

%if 0%{?suse_version}
  <suse stuff here>
%else
  <other distros>
%endif

来检查当前构建是否针对 SUSE 发行版。请注意,[在同一级别上没有 '%elseif' 来链接多个测试]。请注意,Fedora 使用%{fedora}没有_version”。您还可以使用

%if 0%{?suse_version} > 1130

例如,在 SUSE Linux 11.3 之后执行某些操作。其他发行版也存在类似的检查。

%if %{defined fedora}
%if %{defined mdkversion}
%if 0%{?fedora} < 5
%if 0%{?mdkversion} > 2006

请注意,rpm 优先使用

>= 

而不是

=>

您还可以排除特定版本

%if 0%{?rhel_version} != 406

您可以将多个发行版组合到一个 if 块中,如下所示

%if 0%{?fedora} || 0%{?rhel_version} || 0%{?centos_version}
 <yourstuff>
%endif

要对条件进行分组,请将条件拆分为多行,如下所示

# mono:  only on suse, sle only from sle10
%if 0%{?suse_version}
%if 0%{?suse_version} >= 1010
BuildRequires:  mono-core
%endif
%endif

另一种方法是使用括号,例如

# mono:  only on suse, sle only from sle10
%if 0%{?suse_version} && ( 0%{?suse_version} == 0 || 0%{?suse_version} >= 1010 )
BuildRequires:  mono-core
%endif

在较旧的基于 RHEL 的发行版(如 Fedora、RHEL 和 CentOS)上,使用括号进行分组可能会失败。任何基于 RHEL-5 或更高版本的发行版都应支持分组。对于较旧的版本,请将条件拆分并正确嵌套。

您可以使用例如

%if 0%{?suse_version} == 1310
%ifarch x86_64
 <yourstuff>
%endif
%endif

警告:以下列出的版本可能会更改!要检查最新版本,请转到项目页面并检查配置文件(例如,对于 RHEL 5,请查看内容 "%rhel_version": https://build.opensuse.org/project/prjconf?project=RedHat%3ARHEL-5)。如果版本不匹配,请更新此页面。

注意:“sles_version”宏已 不再设置 在 SLE 12 中。


openSUSE:Packaging_for_Leap#RPM_Distro_Version_Macros 有助于选择 openSUSE/SUSE 的正确设置。您还可以使用 osc buildconfig 来检查特定构建配置的宏定义。

在本地,您还可以运行以下命令来获取您的值

 grep suse_version /usr/lib/rpm/suse/macros

否则,下表可能有助于选择正确的设置,包括非 (open)SUSE 发行版

发行版 变量 评论
openSUSE Tumbleweed %if 0%{?suse_version} > 1600 当前即将发布的版本(正在更改)
openSUSE Leap 16.0 %if 0%{?suse_version} == 1600 && 0%{?is_opensuse} SLES 16 目前不使用 sle_version 宏。
openSUSE Leap 15.6 %if 0%{?sle_version} == 150600 && 0%{?is_opensuse}
openSUSE Leap 15.5 %if 0%{?sle_version} == 150500 && 0%{?is_opensuse}
openSUSE Leap 15.4 %if 0%{?sle_version} == 150400 && 0%{?is_opensuse}
openSUSE Leap 15.3 %if 0%{?sle_version} == 150300 && 0%{?is_opensuse}
openSUSE Leap 15.2 %if 0%{?sle_version} == 150200 && 0%{?is_opensuse}
openSUSE Leap 15.1 %if 0%{?sle_version} == 150100 && 0%{?is_opensuse}
openSUSE Leap 15.0 %if 0%{?sle_version} == 150000 && 0%{?is_opensuse} 也可以是 Backports:SLE-15¹
openSUSE Leap 42.3 %if 0%{?sle_version} == 120300 && 0%{?is_opensuse} "leap_version" 已弃用,请参阅下文
openSUSE Leap 42.2 %if 0%{?sle_version} == 120200 && 0%{?is_opensuse} "leap_version" 已弃用,请参阅下文
openSUSE Leap 42.1 %if 0%{?sle_version} == 120100 && 0%{?is_opensuse}
openSUSE Leap 42.x %if 0%{?suse_version} == 1315 && 0%{?is_opensuse} 使用上面的比较来区分特定版本
openSUSE 13.2 %if 0%{?suse_version} == 1320
openSUSE 13.1 %if 0%{?suse_version} == 1310
openSUSE 12.3 %if 0%{?suse_version} == 1230
openSUSE 12.2 %if 0%{?suse_version} == 1220
openSUSE 12.1 %if 0%{?suse_version} == 1210
openSUSE 11.4 %if 0%{?suse_version} == 1140
openSUSE 11.3 %if 0%{?suse_version} == 1130
openSUSE 11.2 %if 0%{?suse_version} == 1120
openSUSE 11.1 %if 0%{?suse_version} == 1110 也可以是 SLE11*
openSUSE 11.0 %if 0%{?suse_version} == 1100
openSUSE 10.3 %if 0%{?suse_version} == 1030
openSUSE 10.2 %if 0%{?suse_version} == 1020
SUSE Linux 10.1 %if 0%{?suse_version} == 1010 也可以是 SLE10*
SUSE Linux 10.0 %if 0%{?suse_version} == 1000
SUSE Linux 9.3 %if 0%{?suse_version} == 930
Backports:SLE-15 %if 0%{?sle_version} == 150000 && 0%{?is_backports}
Backports:SLE-12-SP5 %if 0%{?sle_version} == 120500 && 0%{?is_backports}
Backports:SLE-12-SP4 %if 0%{?sle_version} == 120400 && 0%{?is_backports}
Backports:SLE-12-SP3 %if 0%{?sle_version} == 120300 && 0%{?is_backports}
Backports:SLE-12-SP2 %if 0%{?sle_version} == 120200 && 0%{?is_backports}
Backports:SLE-12-SP1 %if 0%{?sle_version} == 120100 && 0%{?is_backports}
Backports:SLE-12 %if 0%{?sle_version} == 120000 && 0%{?is_backports}
SLE 15 SP4 %if 0%{?sle_version} == 150400 && !0%{?is_opensuse}
SLE 15 SP3 %if 0%{?sle_version} == 150300 && !0%{?is_opensuse}
SLE 15 SP2 %if 0%{?sle_version} == 150200 && !0%{?is_opensuse}
SLE 15 SP1 %if 0%{?sle_version} == 150100 && !0%{?is_opensuse}
SLE 15 GA %if 0%{?sle_version} == 150000 && !0%{?is_opensuse}
SLE 12 SP5 %if 0%{?sle_version} == 120500 && !0%{?is_opensuse}
SLE 12 SP4 %if 0%{?sle_version} == 120400 && !0%{?is_opensuse}
SLE 12 SP3 %if 0%{?sle_version} == 120300 && !0%{?is_opensuse}
SLE 12 SP2 %if 0%{?sle_version} == 120200 && !0%{?is_opensuse}
SLE 12 SP1 %if 0%{?sle_version} == 120100 && !0%{?is_opensuse}
SLE 12 GA %if 0%{?sle_version} == 120000 && !0%{?is_opensuse}
SLE 12 %if 0%{?suse_version} == 1315 && !0%{?is_opensuse} 删除 "is_opensuse" 检查以获取 Leap 42 和 SLE 12
SLE 11 %if 0%{?sles_version} == 11 也可以检查 "suse_version" 是否为 1110
SLE 10 %if 0%{?sles_version} == 10 也可以检查 "suse_version" 是否为 1010
SLES 9 %if 0%{?sles_version} == 9 也可以检查 "suse_version" 是否为 910
CentOS 5 %if 0%{?centos_version} == 505
CentOS 6 %if 0%{?centos_version} == 600
CentOS 7 %if 0%{?centos_version} == 700
RHEL 4 %if 0%{?rhel_version} == 406
RHEL 5 %if 0%{?rhel_version} == 505
RHEL 6 %if 0%{?rhel_version} == 600
RHEL 7 %if 0%{?rhel_version} == 700
RHEL 8 %if 0%{?rhel} == 8
Scientific Linux 6 %if 0%{?scientificlinux_version} == 600
Scientific Linux 7 %if 0%{?scientificlinux_version} == 700
Fedora 6 with Extras %if 0%{?fedora_version} == 6
Fedora 7 with Extras %if 0%{?fedora_version} == 7
Fedora 8 with Extras %if 0%{?fedora_version} == 8
Fedora 9 with Extras %if 0%{?fedora_version} == 9
Fedora 10 with Extras %if 0%{?fedora_version} == 10
Fedora 11 with Extras %if 0%{?fedora_version} == 11
Fedora 15 %if 0%{?fedora_version} == 15
Fedora 16 %if 0%{?fedora_version} == 16
Fedora 17 %if 0%{?fedora_version} == 17
Fedora 18 %if 0%{?fedora_version} == 18
Fedora 19 %if 0%{?fedora_version} == 19
Fedora 20 %if 0%{?fedora_version} == 20
Fedora 21 %if 0%{?fedora_version} == 21
Fedora 36 %if 0%{?fedora} == 36 fedora_version 宏不可用。
Mandriva 2006 %if 0%{?mdkversion} == 2006
Mandriva 2007 %if 0%{?mdkversion} == 2007
Mandriva 2008 %if 0%{?mdkversion} == 2008
Mandriva 2009.0 %if 0%{?mdkversion} == 2009
Mandriva 2009.1 %if 0%{?mdkversion} == 200910
Mandriva 2010.0 %if 0%{?mdkversion} == 201000
Arch Linux %if 0%{?arch_linux} 仅在项目配置中有效
Debian %if 0%{?debian} 仅在项目配置中有效

* 使用 0%{?is_opensuse} 以避免与 SLE 版本冲突

¹ 使用 %if !0%{?is_backports} 来区分 Leap 15 和 Backports:SLE-15

leap_version 宏(已弃用)

"leap_version" 宏现已弃用,并且已被 Leap 15.0 删除。

不应将此宏用于新的 RPM spec 文件:而是同时使用 "sle_version" 和 "is_opensuse" 宏。

请参阅下表以获取可能的值。如果未列出发行版,则未定义该宏。

发行版
openSUSE Leap 42.1 未定义
openSUSE Leap 42.2 420200
openSUSE Leap 42.3 420300
openSUSE Leap 15.0 未定义

ServicePacks 只能区分 SLES12。SLES11 SP1 设置完全相同的变量,如 SLES11。

您还应该查看 Leap/SLES 这里:openSUSE:How_to_contribute_to_Leap

安装信息文件

信息文件应该使用 %info_add 和 %info_del 宏来安装。例如

%post
%info_add %{name}.info
%preun
%info_del %{name}.info

请注意,在某些发行版中,信息文件会被压缩为 .gz、.bz2 甚至 .lzma (最近的 Mandriva/Mageia)。您可以使用 %ext_info 来指定文件列表中的文件后缀。

安装 man 文件

在某些发行版中,man 文件会被压缩为 .gz、.bz2 甚至 .lzma (最近的 Mandriva/Mageia)。您可以使用 %ext_man 来指定文件列表中的文件后缀。

对于 Mageia 或 Fedora,ext_info 和 ext_man 宏未定义,因此您需要将它们添加到 prjconf 中。

%if 0%{?mageia} == 6
Macros:
%ext_info .xz
%ext_man .xz

:Macros
%endif

%if 0%{?fedora_version} && 0%{?fedora_version} >= 25
Macros:
%ext_info .gz
%ext_man .gz

:Macros
%endif

处理依赖关系

不同的发行版通常使用不同的软件包名称,因此 Requires: 和 BuildRequires: 标签可能需要从仓库到仓库进行更改。可以在项目的配置中指定软件包名称替换,例如:

%if 0%{?fedora_version}
  Substitute: libnetcdf-devel netcdf
%endif

这将“替换” libnetcdf-devel 为 netcdf 在所有受影响的 spec 文件中。

为了更改您的项目配置,请使用 osc meta prjconf <project-name> -e,这将启动 $EDITOR。在 Web 客户端中,这隐藏在中央项目菜单的高级部分。

如果您在 build.opensuse.org 上执行此操作,并且认为您的替换对其他人也有用处(并且可能添加到中央配置中),请发送消息到 opensuse-buildservice@opensuse.org。

如果您想查看针对特定发行版已存在的替换项,请查看该发行版的项目配置,例如 https://build.opensuse.org/project/prjconf?project=CentOS%3ACentOS-6

推荐 (Recommends):建议 (Suggests):

Suggests: 是 SUSE (>=10) 和 Fedora (>=24) 中可用的一项功能。这是 "Requires:" 的一个弱版本。

# the package does not need vi or graphviz to run.
%if 0%{?suse_version} >= 1000
Suggests:       vim graphviz
%endif

同样适用于 推荐 (Recommends):

update-alternatives 包仅适用于 SUSE

update-alternatives 是 SUSE 包,但 Fedora/RHEL 上不可用,后者提供由 chkconfig 包提供的功能。解决方案:只需使用指向二进制文件的完整路径

Requires(post):   /usr/sbin/update-alternatives
Requires(postun): /usr/sbin/update-alternatives

代替

# Requires(post):   update-alternatives
# Requires(postun): update-alternatives

另一种解决方案是将以下宏添加到 构建配置

%if ! 0%{?suse_version}
Substitute: update-alternatives chkconfig
%endif

在 Fedora/RHEL 上查找 Qt 3.x

Redhat/Fedora 使用不同的命名方案和构建设置来使用 Qt 构建其他应用程序。以下是一个 spec 文件示例,用于在 SUSE 和 Fedora 上使用一个 spec 文件构建基于 Qt 的应用程序

BuildRequires:  cups cups-devel python-devel shared-mime-info libart_lgpl-devel libtiff-devel libxml2-devel
BuildRequires:  fontconfig-devel openssl-devel pkgconfig desktop-file-utils qt-devel

%if 0%{?fedora} >= 5
BuildRequires:  libstdc++-devel gcc-c++ lcms-devel >= 1.12 qt
%endif

%if 0%{?suse_version} > 910
BuildRequires:  update-desktop-files 
%endif

然后

%if 0%{?fedora} >= 5
source "%{_sysconfdir}/profile.d/qt.sh"
%endif
%configure \
%if 0%{?fedora} >= 5
--with-xinerama \
--with-extra-libs=%{_libdir} \
%endif
%if 0%{?suse_version} > 910
--with-qt-libraries=/usr/%_lib/qt3/%_lib \
--with-docdir=%{prefix}/share/doc/packages/scribus \
%ifarch x86_64 ppc64 s390x
 --enable-libsuffix=64 \ 
%endif
%endif
<programoptions>

在 Mandriva 上查找 Qt4

默认情况下,Qt3 将在 Qt4 之前被找到,因此只需将以下内容添加到 spec 文件的 %build 部分

%build  
 
%if 0%{?mandriva_version} > 2006  
export PATH=/usr/lib/qt4/bin:$PATH  
export QTDIR=%{_prefix}/lib/qt4/  
%endif  
  • 这可能在 Mdv 2008 上已更改

处理 Mandriva Provides/Obsoletes

处理 Mandriva 时需要特别注意,因为与 CentOS、RHEL、Fedora 或 SUSE 不同,它们通常为许多私下使用这些库的应用程序创建单独的库 rpm。应用程序 foo 可能还依赖于 libfoo 或 libfoo-0。因此,您需要检查 Mandriva 原始 spec 文件,看看它们是否有明确的 Provides 和 Obsoletes,以防止安装时的冲突。即使 RPM 会自动处理依赖关系,您可能仍然需要像下面这样显式地添加它们

%if 0%{?mandriva_version}
Provides: foo libfoo-0
Obsoletes: foo libfoo-0
%endif

在较旧的发行版上构建

虽然软件包中的源代码可以在较旧的发行版上构建,但软件包的构建方式有时会以不兼容的方式演变。

例如,某些 spec 文件有时会调用 `autoreconf -fi`, 有可能 tarball 的版本config.sub, config.guessltmain.sh文件会被构建主机的 autoconf 包中的副本替换,这是-i选项的结果。当构建主机的软件足够旧,而要构建的软件足够新时,这可能会导致 config 文件的降级,这可能会产生负面影响,甚至导致错误编译,例如在 SLE10 上构建 libapr1 时。

因此,最好甚至需要您手动调用autoheader, autoconf或者其他需要的命令,而不是autoreconf在早于 Factory 的目标上。一个例子是

%if 0%{?suse_version} > 1010
  autoreconf -fi
%else
  autoheader
  autoconf
%endif

Debian 和 xUbuntu 包

对于这些类型的软件包,请阅读 debian builds 页面。

CentOS 和 RHEL EPEL 仓库

对于 CentOS 和 RHEL,您可能需要使用 EPEL 仓库。它们在 OBS 中可用,地址为 Fedora:EPEL:7

Arch Linux 软件包指南

创建软件包Arch 软件包标准

发行版 RPM 宏和文档

openSUSE 软件包约定

Fedora 包装者指南

ROSA 的构建 RPM - 快速入门指南

Mageia 的初学者包装指南