【问题标题】:rpm conditional with substring?rpm 有条件的子字符串?
【发布时间】:2018-09-21 13:38:01
【问题描述】:

我有一个使用类似条件的规范文件

%if "%{pkgname}" = "wobble"
  Requires: extra-thing
  ....
%endif

现在需要将wobble-thingwobble-otherthing 和任何其他wobble* 视为满足相同条件。简单,你会想的。

如果不放弃规范文件和预处理文件的可怕之处,我找不到任何方法。

不幸的是,在这种情况下对文件进行预处理是行不通的,它会颠覆整个构建链,期望能够仅 rpm 构建规范。

rpmrpmbuild 中有很多未记录的魔法,例如 ${error:blah}%{expand:..othermacros...}%global 的东西。甚至像 %if %{value} < 42 这样的简单关系操作似乎也没有真正记录在任何地方。

有人知道字符串前缀或字符串中缀模式匹配运算符吗?

我正在寻找与 bash 的 if [[ "${VAR}" == *"substring"* ]]; then 构造等效的规范。

编辑:明确地说,我不只是使用 shell 条件的原因是我需要影响 rpm 元数据。我认为如果可以选择的话,我会使用 shell if 是很明显的。我在上面进行了编辑以更清楚地显示。

编辑:为了帮助其他人找到这个,这是关于 rpm 中的字符串模式匹配。 rpm 中的复杂条件。规范文件中的条件部分。 rpmbuild 中的字符串前缀、中缀或后缀运算符和测试。

【问题讨论】:

标签: if-statement conditional rpm rpmbuild rpm-spec


【解决方案1】:

您不能使用正则表达式或通配符。但你可以使用“或”。

%if "%{pkgname}" == "wobble" || "%{pkgname}" == "wobble-thing"
..
%endif

或者你可以在 shell 中进行评估

%global yourmacro   %(/usr/bin/perl ...%{pkgname}... )

其中/usr/bin/perl ... 可以是任何脚本,yourmacro 设置为此脚本的标准输出值。

【讨论】:

  • 谢谢。很高兴看到基本条件起作用。在 shell 中执行此操作不适用于 Requires 等。
  • 添加了一个答案,展示了如何使用 rpm lua 脚本来完成。
【解决方案2】:

您确实可以使用 Lua 脚本,尽管它需要一些奇怪的咒语。以下是如何将starts_with 类似函数的宏添加到您可以在%if 条件下使用的rpm 规范文件。

# Define the Lua starts_with function we want to expose
%{lua:
  function starts_with(str, start)
   return str:sub(1, #start) == start
  end
}

# Define the rpm parametric macro starts_with(str,prefix) that
# calls Lua and maps "false"=>"0" and "true"=>"1"
#
# Note that we need to inject the parameters %1 and %2 to a
# string-quoted version of the Lua macro, then expand the whole
# thing.
#
%define starts_with(str,prefix) (%{expand:%%{lua:print(starts_with(%1, %2) and "1" or "0")}})

# Finally we can use the parametric macro
#
%if %{starts_with "wobble-boo" "wobble"}
  Requires: wobble
%endif

这里发生的是:

%{starts_with "wobble-boo", "wobble}

扩展到

%{expand:%%{lua:print(starts_with("wobble-boo", "wobble") and "1" or "0")}}

扩展为

%{lua:print(starts_with("wobble-boo", "wobble") and "1" or "0")}

执行 Lua 函数starts_with,它测试与“start”长度相同的“str”的左锚子字符串是否等于“start”。如果为真,则返回“1”;如果为假,则返回“0”。那是因为 rpm 无法将 false 识别为 false。

所以我们在这里所做的是从参数 rpm 宏调用 Lua 函数并调整返回值。

漂亮。痛苦的是 rpm 需要这种 hack 来完成这样一个简单的任务,而且它几乎完全没有文档记录。但是很漂亮。

【讨论】:

    【解决方案3】:

    这是在规范中使用%define 的一种方法。

    %global original_string  SomeLongStringHere
    %global matching_string  LongString
    %global nomatch_string   NoMatchHere
    
    %define matchTwoStrings(n:) \
    string_one=%1 \
    string_two=%2 \
    if [[ "${string_one}" = *"${string_two}"* ]]; then \
       echo "It matches" \
    else \
         echo "It doesn't match" \
    fi \
    %{nil}
    

    # 然后在.spec 后面的某个地方,例如,我使用了%post 部分

    %post
    %matchTwoStrings "%{original_string}" "%{matching_string}"
    %matchTwoStrings "%{original_string}" "%{nomatch_string}"
    

    因为这是在%post 部分,所以它会在.rpm 安装过程中打印出来。

    It matches
    It doesn't match
    

    【讨论】:

    • 这不适用于Requires 等。我的问题在这方面不够清楚;它需要适用于 rpm 元数据。
    【解决方案4】:

    实际上,您可以在不需要 Lua 的情况下做到这一点,并且您可以在 BASH 中使用您在原始问题中提到想要使用的 if [[ ... ]] 构造。

    为了说明如何,让我们看一下我使用的tmux RPM 的规范文件的标题部分。它必须在运行 RHEL/CentOS 版本 6、7 和 8(和/或任何其他重建,如 Oracle 的)的任何主机上未经修改地构建。这就是我所拥有的:

    %global name tmux
    %global version 3.1b
    %global release 1%{?dist}
    
    %global _hardened_build 1
    
    Summary:        A terminal multiplexer
    Name:           %{name}
    Version:        %{version}
    Release:        %{release}
    # Mostly ISC-licensed, but some files in compat/ are 2-/3-clause BSD.
    License:        ISC/BSD
    URL:            https://tmux.github.io/
    Source0:        https://github.com/tmux/%{name}/releases/download/%{version}/%{name}-%{version}.tar.gz
    Source1:        bash_completion_tmux.sh
    BuildRequires:  %(/bin/bash -fc 'if [[ %{name} == tmux* ]]; then echo make ; else echo nomake ; fi') %(/bin/bash -fc 'if [[ %{name} == wobble* ]]; then echo wobble ; fi')
    BuildRequires:  gcc, ncurses-devel, %{expand:%(/bin/bash -c 'if [[ %{?rhel}%{!?rhel:9} -le 6 ]]; then echo libevent2-devel ; else echo libevent-devel ; fi')}
    Requires:       %{expand:%(/bin/bash -c 'if [[ %{?rhel}%{!?rhel:9} -le 6 ]]; then echo libevent2 ; else echo libevent ; fi')} >= 2.0
    

    这个 RPM 的棘手之处在于 RHEL6 提供了 libevent 包,但它是 1.4.13 版,对于 tmux 来说太旧了,无法成功构建。 (它需要 libevent 2.x。)不过,好消息是 RHEL6 实际上有 both 版本! libevent2 RPM 的版本为 2.0.21,该版本足够新,可用于 tmux。但我不能只列出libevent2-devel 作为我的构建依赖项;该软件包不适用于 RHEL 7 或 8,因为它们的默认 libevent RPM 已经是版本 2。我也不能将libevent-devel 列为构建依赖项,因为虽然libeventlibevent2 软件包可以并排安装,但libevent-devellibevent2-devel RPM 存在冲突。

    正如您在上面的规范文件中看到的,我对这个挑战的解决方案是使用 RPM 宏将字符串 libevent-devellibevent2-devel 注入到 BuildRequires: 标头值中,基于 BASH 的比较%{rhel} 宏的值(在 RHEL 6、7 或 8 上,/etc/rpm/macros.dist 分别为其分配了 678 的值)。对于 RHEL6(和以前的,理论上...RHEL5 已死,而 RHEL4 及更早版本是超级死的!),使用后一个值,而前一个值用于 RHEL7 和 RHEL8。

    我还添加了几个人为的字符串匹配宏调用,只是为了说明它可以正常工作。我的实际规范文件既不包含第一行 BuildRequires: 也不包含最后一行 Requires: (因为它是不必要的/冗余的);我专门为此练习添加了它们,以证明条件适用于构建时和运行时依赖项。

    我怎么知道它们有效?我检查了:

    $ rpm -qp --qf '[%|SOURCERPM?{%25{=NEVRA}}:{%21{=NEVR}.src}|.rpm:  %{REQUIREFLAGS:deptype}: %{REQUIRENEVRS}\n]' tmux-3.1b-1.el6.x86_64.rpm tmux-3.1b-1.el6.src.rpm tmux-3.1b-1.el8.x86_64.rpm tmux-3.1b-1.el8.src.rpm | fgrep 'manual:'
       tmux-3.1b-1.el6.x86_64.rpm:  manual: libevent2 >= 2.0
          tmux-3.1b-1.el6.src.rpm:  manual: make
          tmux-3.1b-1.el6.src.rpm:  manual: gcc
          tmux-3.1b-1.el6.src.rpm:  manual: ncurses-devel
          tmux-3.1b-1.el6.src.rpm:  manual: libevent2-devel
       tmux-3.1b-1.el8.x86_64.rpm:  manual: libevent >= 2.0
          tmux-3.1b-1.el8.src.rpm:  manual: gcc
          tmux-3.1b-1.el8.src.rpm:  manual: libevent-devel
          tmux-3.1b-1.el8.src.rpm:  manual: make
          tmux-3.1b-1.el8.src.rpm:  manual: ncurses-devel
    

    请注意,正确的 libevent2 >= 2.0 依赖项(带有 2 在末尾)显示在 RHEL6 RPM 中;另一方面,RHEL8 RPM 显示libevent >= 2.0没有最后的2),再次完全按照它应该的方式显示。此外,在两个 SRPM 中都显示了对 make 的构建依赖,并且 nomakewobble 都不存在,这证明了 tmux*wobble* 上的模式匹配条件完全可以正常工作。

    【讨论】:

      猜你喜欢
      • 2018-11-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-18
      • 1970-01-01
      • 2017-12-07
      • 2021-12-06
      相关资源
      最近更新 更多