If statement 带子字符串的rpm条件?

If statement 带子字符串的rpm条件?,if-statement,conditional,rpm,rpmbuild,rpm-spec,If Statement,Conditional,Rpm,Rpmbuild,Rpm Spec,我有一个spec文件,它使用条件 %if "%{pkgname}" = "wobble" Requires: extra-thing .... %endif 现在需要将抖动对象,抖动其他对象和任何其他抖动*视为满足相同条件。你会觉得很简单 我无法找到任何方法来做到这一点,而不放弃规范文件和预处理文件的可怕之处 不幸的是,在这种情况下,预处理文件将无法运行,它将启动一个完整的构建链,该链期望能够仅rpmbuild规范 在rpm和rpmbuild中有很多未记录的魔法,比如${error:b

我有一个spec文件,它使用条件

%if "%{pkgname}" = "wobble"
  Requires: extra-thing
  ....
%endif
现在需要将
抖动对象
抖动其他对象
和任何其他
抖动*
视为满足相同条件。你会觉得很简单

我无法找到任何方法来做到这一点,而不放弃规范文件和预处理文件的可怕之处

不幸的是,在这种情况下,预处理文件将无法运行,它将启动一个完整的构建链,该链期望能够仅rpmbuild规范

rpm
rpmbuild
中有很多未记录的魔法,比如
${error:blah}
%{expand:…othermacros…}
%global
之类的东西。即使是像
%if%{value}<42
这样的简单关系操作似乎也没有在任何地方被记录下来

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

我正在寻找bash的
if[[“${VAR}”==*“substring”*]的规范等价物;然后
构造

编辑:很清楚,我不只是使用shell条件的原因是我需要影响rpm元数据。我认为很明显,如果这是一个选项,我会使用shell
if
。我已经编辑,以更清楚地显示上述内容


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

不能使用regexp或通配符。但你可以用“或”

也可以在shell中进行评估

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

其中,
/usr/bin/perl…
可以是任何脚本,
您的宏
设置为该脚本的stdout值。

以下是在规范中使用
%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

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

#使用我们想要公开的函数定义Lua start_
%{lua:
函数以(str,start)开头
返回str:sub(1,#start)==start
结束
}
#定义rpm参数化宏以(str,前缀)开头
#调用Lua并映射“false”=>“0”和“true”=>“1”
#
#请注意,我们需要将参数%1和%2注入到
#字符串引用Lua宏的版本,然后展开整个
#事情。
#
%用(str,前缀)定义起始字符({expand:%%{lua:print(起始字符(%1,%2)和“1”或“0”)})
#最后,我们可以使用参数宏
#
%如果%{以“摆动boo”“摆动”}
要求:摆动
%恩迪夫

这里发生的是:

%{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")}
扩展到

%{expand:%%{lua:print(starts_with("wobble-boo", "wobble") and "1" or "0")}}
%{lua:print(starts_with("wobble-boo", "wobble") and "1" or "0")}
它执行Lua函数
开始,它测试与“start”长度相同的“str”的左锚点子串是否等于“start”。如果这是真的,则返回“1”;如果为false,则返回“0”。这是因为rpm不能将
false
识别为false

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


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

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

为了说明如何使用,让我们看看我使用的
tmux
RPM的specfile的头部分。它必须在运行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实际上有两个版本!
libevent2
RPM有2.0.21版,这是最新的版本,足以用于
tmux
。但我不能仅仅将
libevent2-devel
列为构建依赖项;该软件包不适用于RHEL 7或8,因为它们的默认
libevent
RPM已经是版本2。我也不能将
libevent-devel
列为构建依赖项,因为
libevent
libevent2
软件包可以并排安装,而
libevent-devel
libevent2-devel
RPM冲突

正如您在上面的specfile中所看到的,我的解决方案是使用RPM宏将字符串
libevent-devel
libevent2-devel
注入
BuildRequires:
头值,该值基于对
%{rhel}
宏的基于BASH的比较(其中
/etc/rpm/macros.dist
分别为RHEL 6、7或8分配
6
7
8
)的值。对于RHEL6(理论上,之前的RHEL5是死的,RHEL4和更早的是超级复制器死的!),使用后一个值,而前一个值用于RHEL7和RHEL8

我还添加了两个精心设计的字符串匹配宏调用,只是为了说明它工作正常。我的实际specfile既不包含第一行
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
d