2.10. 转换一个一致的 Spec 文件
本节讨论将传统 spec 文件转换为 Software Collection spec 文件,以便在传统软件包和 Software Collection 中使用转换的 spec 文件。
2.10.1. 转换的 Spec 文件示例 复制链接链接已复制到粘贴板!
复制链接链接已复制到粘贴板!
要查看 diff 文件将传统 spec 文件与转换的 spec 文件进行比较,请参考以下示例:
2.10.2. 转换标签和 Macro 定义 复制链接链接已复制到粘贴板!
复制链接链接已复制到粘贴板!
以下步骤演示了如何将传统 spec 文件中的标签和宏定义转换为 Software Collection spec 文件。
过程 2.1. 转换标签和宏定义
- 您可以通过在
%_scl_prefix之上定义%scl_package macro宏来更改根目录的位置:%{?scl:%global _scl_prefix /opt/provider}%{?scl:%global _scl_prefix /opt/provider}Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 在 spec 文件中添加
%scl_package宏。将宏放在 spec 文件前,如下所示:%{?scl:%scl_package package_name}%{?scl:%scl_package package_name}Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 当没有为 Software Collection 构建软件包时,建议您在 spec 文件中定义
%pkg_name宏:%{!?scl:%global pkg_name %{name}}%{!?scl:%global pkg_name %{name}}Copy to Clipboard Copied! Toggle word wrap Toggle overflow 因此,您可以使用%pkg_name宏定义在 spec 文件中需要的软件包的原始名称,然后可用于构建传统软件包和 Software Collection。 - 更改 spec 文件中的
Name标签,如下所示:Name: %{?scl_prefix}package_nameName: %{?scl_prefix}package_nameCopy to Clipboard Copied! Toggle word wrap Toggle overflow - 如果您要与其他 Software Collection 软件包构建或链接,请为
Requires和BuildRequires标签中的软件集合软件包名称添加前缀,如下所示:%{?scl_prefix}Requires: %{?scl_prefix}ifconfigRequires: %{?scl_prefix}ifconfigCopy to Clipboard Copied! Toggle word wrap Toggle overflow 当取决于软件包的系统版本时,您应该避免使用版本化的Requires或BuildRequires。如果您需要依赖于系统更新的软件包,请考虑在 Software Collection 中包含该软件包,或者在系统软件包更新时记住重建您的 Software Collection。 - 要检查所有基本 Software Collection 的软件包是否为主 metapackage 的依赖项,请在 spec 文件中的
BuildRequires或Requires标签中添加以下宏:%{?scl:Requires: %scl_runtime}%{?scl:Requires: %scl_runtime}Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 使用
Obsoletes为Conflicts、BuildConflicts、%{?scl_prefix}和 标签添加前缀。这是为了确保 Software Collection 可用于将新软件包部署到旧的系统中,而无需指定软件包,例如Obsolete从基本系统安装中删除。例如:Obsoletes: %{?scl_prefix}lesspipe < 1.0Obsoletes: %{?scl_prefix}lesspipe < 1.0Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 为
Provides标签添加前缀%{?scl_prefix},如下例所示:Provides: %{?scl_prefix}moreProvides: %{?scl_prefix}moreCopy to Clipboard Copied! Toggle word wrap Toggle overflow
2.10.3. 转换子软件包 复制链接链接已复制到粘贴板!
复制链接链接已复制到粘贴板!
对于使用
-n 选项定义它们名称的任何子软件包,使用 %{?scl_prefix} 前缀,如下例所示:
%package -n %{?scl_prefix}more
%package -n %{?scl_prefix}more
前缀不仅适用于
%package 宏,也适用于 %description 和 %files。例如:
%description -n %{?scl_prefix}rubygems
RubyGems is the Ruby standard for publishing and managing third party
libraries.
%description -n %{?scl_prefix}rubygems
RubyGems is the Ruby standard for publishing and managing third party
libraries.
如果子软件包需要主软件包,请确保也调整该子软件包中的
Requires 标签,以便标签使用 %{?scl_prefix}%{pkg_name}。例如:
Requires: %{?scl_prefix}%{pkg_name} = %{version}-%{release}
Requires: %{?scl_prefix}%{pkg_name} = %{version}-%{release}
2.10.4. 转换 RPM 脚本 复制链接链接已复制到粘贴板!
复制链接链接已复制到粘贴板!
这部分论述了转换 RPM 脚本的常规规则,它们通常可在传统 spec 文件的
%prep、%build、%install、%check、%pre 和 %post 部分找到。
- 将所有出现的
%name替换为%pkg_name。最重要的是,这包括调整%setup宏。- 调整 spec 文件的
%setup部分中的%prep宏,以便宏可以在 Software Collection 环境中处理不同的软件包名称:%setup -q -n %{pkg_name}-%{version}%setup -q -n %{pkg_name}-%{version}Copy to Clipboard Copied! Toggle word wrap Toggle overflow 请注意,%setup宏是必需的,且您必须始终使用带有-n选项的宏才能成功构建软件集合。
- 如果您使用任何
%_root_宏指向系统文件系统层次结构,则必须使用这些宏的条件,以便您可以使用 spec 文件来构建传统软件包和 Software Collection。编辑宏,如下例所示:mkdir -p %{?scl:%_root_sysconfdir}%{?!scl:%_sysconfdir}mkdir -p %{?scl:%_root_sysconfdir}%{?!scl:%_sysconfdir}Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 当构建依赖于其他 Software Collection 软件包的软件集合软件包时,务必要确保 scl 启用 功能链接或运行正确的二进制文件等。需要此示例之一是针对 Software Collection 库进行编译,或使用 Software Collection 中的解释器运行解释脚本。使用
%{?scl:前缀嵌套脚本,如下例所示:Copy to Clipboard Copied! Toggle word wrap Toggle overflow 在脚本中指定set -e非常重要,无论脚本是否在 rpm shell 还是 scl 环境中执行,脚本的行为都是一致的。 - 请注意 Software Collection 软件包安装过程中执行的任何脚本,例如:
%pretrans,%pre,%post,%postun,%posttrans,%triggerin、%triggerun和%triggerpostun。
如果您在这些脚本中使用 scl 启用 功能,建议您从空环境开始,以避免与基本系统安装有任何意外冲突。要做到这一点,在启用 Software Collection 前使用env -i -,如下例所示:%posttrans %{?scl:env -i - scl enable %{scl} - << \EOF} %vagrant_plugin_register %{vagrant_plugin_name} %{?scl:EOF}%posttrans %{?scl:env -i - scl enable %{scl} - << \EOF} %vagrant_plugin_register %{vagrant_plugin_name} %{?scl:EOF}Copy to Clipboard Copied! Toggle word wrap Toggle overflow - RPM 脚本中找到的所有硬编码路径都必须替换为正确的宏。例如:将所有出现的
/usr/share替换为%{_datadir}。这是必要的,因为$RPM_BUILD_ROOT变量和%{build_root}宏不会被scl宏重新定位。
重要
本节中描述的功能在 Red Hat Enterprise Linux 6 中不提供。
Red Hat Enterprise Linux 7 中的 RPM 支持自动
Provides 和 Requires 和过滤。例如,对于所有 Python 库,RPM 会自动添加以下 Requires :
Requires: python(abi) = (version)
Requires: python(abi) = (version)
Requires: %{?scl_prefix}python(abi) = (version))
Requires: %{?scl_prefix}python(abi) = (version))
请记住,搜索这些依赖项的脚本有时必须为您的 Software Collection 进行重写,因为原始 RPM 脚本不足可扩展,因此在某些情况下,过滤不可用。例如,要重写自动 Python
Provides 和 Requires,请在 macros.%{scl}-config 宏文件中添加以下行:
%__python_provides /usr/lib/rpm/pythondeps-scl.sh --provides %{_scl_root} %{scl_prefix}
%__python_requires /usr/lib/rpm/pythondeps-scl.sh --requires %{_scl_root} %{scl_prefix}
%__python_provides /usr/lib/rpm/pythondeps-scl.sh --provides %{_scl_root} %{scl_prefix}
%__python_requires /usr/lib/rpm/pythondeps-scl.sh --requires %{_scl_root} %{scl_prefix}
/usr/lib/rpm/pythondeps-scl.sh 文件基于传统软件包中的 pythondeps.sh 文件并调整搜索路径。
如果您有需要调整的
Provides 或 Requires,例如 pkg_config Provides,则有两种方法:
- 在
macros.%{scl}-config宏中添加以下几行,使其适用于 Software Collection 中的所有软件包:Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 或者,在您要过滤
Provides或Requires的每个 spec 文件中的标签定义后添加以下行:%{?scl:%filter_from_provides s|pkgconfig|%{?scl_prefix}pkgconfig|g} %{?scl:%filter_from_requires s|pkgconfig|%{?scl_prefix}pkgconfig|g} %{?scl:%filter_setup}%{?scl:%filter_from_provides s|pkgconfig|%{?scl_prefix}pkgconfig|g} %{?scl:%filter_from_requires s|pkgconfig|%{?scl_prefix}pkgconfig|g} %{?scl:%filter_setup}Copy to Clipboard Copied! Toggle word wrap Toggle overflow
重要
在使用过滤器时,您需要注意您更改的自动依赖项。例如,如果传统软件包包含
Requires: pkgconfig(package_1) 和 Requires: pkgconfig(package_2),且软件集合中仅包含 package_2,请确保不要为 package_1 过滤 Requires 标签。
2.10.6. Software Collection Macro 文件支持 复制链接链接已复制到粘贴板!
复制链接链接已复制到粘贴板!
在某些情况下,您可能需要通过 Software Collection 软件包提供宏文件。它们位于
%{?scl:%{_root_sysconfdir}}%{!?scl:%{_sysconfdir}}/rpm/ 目录中,对应于传统软件包的 /etc/rpm/ 目录。在提供宏文件时,请确保:
- 通过将
.%{scl}附加到其名称来重命名宏文件,以便它们不会与基本系统安装中的文件冲突。 - 宏文件中的宏不能扩展,或者它们正在使用条件,如下例所示:
%__python2 %{_bindir}/python %python2_sitelib %(%{?scl:scl enable %scl '}%{__python2} -c "from distutils.sysconfig import get_python_lib; print(get_python_lib())"%{?scl:'})%__python2 %{_bindir}/python %python2_sitelib %(%{?scl:scl enable %scl '}%{__python2} -c "from distutils.sysconfig import get_python_lib; print(get_python_lib())"%{?scl:'})Copy to Clipboard Copied! Toggle word wrap Toggle overflow
再如,在有些情况下,您可能需要创建依赖于 Software Collection python26 的 Software Collection mypython。python26 Software Collection 定义
%{__python2} 宏,如上例中所示。此宏将评估为 /opt/provider/mypython/root/usr/bin/python2,但 python2 二进制文件仅在 python26 Software Collection (/opt/provider/python26/root/usr/bin/python2)中提供。
要在 mypython Software Collection 环境中构建软件,请确保:
macros.python.python26宏文件,它是 python26-python-devel 软件包的一部分,包含以下行:%__python26_python2 /opt/provider/python26/root/usr/bin/python2
%__python26_python2 /opt/provider/python26/root/usr/bin/python2Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 以及 python26-build 子软件包中的宏文件,以及任何基于 Software Collection 的 build 子软件包包含以下行:
%scl_package_override() {%global __python2 %__python26_python2}%scl_package_override() {%global __python2 %__python26_python2}Copy to Clipboard Copied! Toggle word wrap Toggle overflow
只有在存在来自相应 Software Collection 的构建子软件包时才重新定义
%{__python2} 宏,这通常意味着您要为该 Software Collection 构建软件。
2.10.7. Software Collection Shebang 支持 复制链接链接已复制到粘贴板!
复制链接链接已复制到粘贴板!
shebang 是脚本开头的一系列字符,用作解释器指令。shebang 由自动依赖项生成器处理,指向某个位置,可能在系统根文件系统中。
当自动依赖关系生成器处理 shebang 时,它会根据它们所指向的解释器添加依赖项。在 Software Collection 的角度来看,有两种 shebangs 类型:
#!/usr/bin/env example- 这个 shebang 指示
/usr/bin/env程序运行解释器。自动依赖关系生成器将如预期对 /usr/bin/env 程序创建一个依赖项。如果在enablescriptlet 中正确定义了$PATH环境变量,则在 Software Collection 文件系统层次结构中找到 示例 解释器,如预期。建议您重写 Software Collection 软件包中的 shebang,以便 shebang 指定软件集合文件系统层次结构中的解释器的完整路径。 #!/usr/bin/example- 这个 shebang 指定解释器的直接路径。自动依赖关系生成器将对位于 Software Collection 文件系统层次结构之外的
/usr/bin/example解释器创建一个依赖项。但是,在为 Software Collection 构建软件包时,您通常希望对位于 Software Collection 文件系统层次结构中的%{?_scl_root}/usr/bin/example解释器创建依赖项。请记住,即使您正确重新定义$PATH环境变量,这不会影响使用哪个解释器。始终使用软件集合文件系统层次结构之外的解释器的系统版本。在大多数情况下,这并不是必需的。如果您使用这种类型的 shebang,并且您希望 shebang 在构建软件集合软件包时指向 Software Collection 文件系统层次结构,请使用类似如下的命令:find %{buildroot} -type f | \ xargs sed -i -e '1 s"^#!/usr/bin/example"#!%{?_scl_root}/usr/bin/example"'find %{buildroot} -type f | \ xargs sed -i -e '1 s"^#!/usr/bin/example"#!%{?_scl_root}/usr/bin/example"'Copy to Clipboard Copied! Toggle word wrap Toggle overflow 其中 /usr/bin/example 是您要使用的解释器。
2.10.8. 在另一软件集合上制作 Software Collection Depend 复制链接链接已复制到粘贴板!
复制链接链接已复制到粘贴板!
要使一个 Software Collection 依赖于另一个 Software Collection 中的软件包,您需要调整依赖 Software Collection 的 spec 文件中的
BuildRequires 和 Requires 标签,以便这些标签正确定义依赖项。
例如,要定义两个名为 software_collection_1 和 software_collection_2 的 Software Collections 的依赖项,请将以下三行添加到应用程序的 spec 文件中:
BuildRequires: scl-utils-build Requires: %scl_require software_collection_1 Requires: %scl_require software_collection_2
BuildRequires: scl-utils-build
Requires: %scl_require software_collection_1
Requires: %scl_require software_collection_2
确保 spec 文件还包含 spec 文件前的
%scl_package 宏,例如:
%{?scl:%scl_package less}
%{?scl:%scl_package less}
请注意,
%scl_package 宏必须包含在您的软件集合的每个 spec 文件中。
您还可以使用
%scl_require_package 宏定义特定软件集合中特定软件包的依赖项,如下例所示:
BuildRequires: scl-utils-build Requires: %scl_require_package software_collection_1 package_name
BuildRequires: scl-utils-build
Requires: %scl_require_package software_collection_1 package_name