我有一个规范文件,它使用类似条件的条件
%if "%{pkgname}" = "wobble"
Requires: extra-thing
....
%endif
,现在需要将wobble-thing
,wobble-otherthing
和任何其他wobble*
视为满足相同条件。很容易,您会认为。
在不放弃规范文件和对文件进行预处理的情况下,我找不到任何方法。
不幸的是,在这种情况下无法对文件进行预处理,它将使整个构建链望尘莫及,而整个构建链有望仅通过rpm构建规范。
rpm
和rpmbuild
中有许多未公开的魔法,例如${error:blah}
和%{expand:..othermacros...}
和%global
之类的东西。甚至%if %{value} < 42
之类的简单关系操作似乎也没有实际记录在任何地方。
有人知道字符串前缀或字符串前缀模式匹配运算符吗?
我正在寻找与bash的if [[ "${VAR}" == *"substring"* ]]; then
构造等效的规范。
编辑:需要明确的是,我不仅仅使用shell条件语句的原因是,我需要影响rpm元数据。我认为很明显,如果可以的话,我会使用shell if
。我进行了编辑,以使上面的内容更加清晰。
编辑:为了帮助其他人找到它,这与rpm中的字符串模式匹配有关。 rpm的复杂条件。规格文件中的条件部分。字符串前缀,后缀或后缀运算符以及rpmbuild中的测试。
答案 0 :(得分:2)
您不能使用正则表达式或通配符。但是您可以使用“或”。
%if "%{pkgname}" == "wobble" || "%{pkgname}" == "wobble-thing"
..
%endif
或者您可以在外壳中进行评估
%global yourmacro %(/usr/bin/perl ...%{pkgname}... )
其中/usr/bin/perl ...
可以是任何脚本,并且yourmacro
设置为此脚本的stdout值。
答案 1 :(得分:0)
这是在规范中使用%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
答案 2 :(得分:0)
您确实可以使用Lua脚本,尽管它需要一些奇特的技巧。以下是向您的rpm规范文件中添加uniqueConstraints
式宏的方法,您可以在starts_with
条件下使用该宏。
%if
这里发生的是:
# 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函数%{lua:print(starts_with("wobble-boo", "wobble") and "1" or "0")}
,该函数测试长度与“ start”相同的“ str”的左锚子字符串是否等于“ start”。如果是这样,则返回“ 1”;如果为假,则返回“ 0”。这是因为rpm无法识别starts_with
为假。
所以我们在这里要做的是从参数rpm宏调用Lua函数并调整返回值。
好。令人痛苦的是,rpm需要这种技巧来完成这样的简单任务,而且几乎完全没有记录在案。但是很漂亮。
答案 3 :(得分:0)
实际上,您无需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实际上具有两个版本! libevent2
RPM的版本为2.0.21,最新版本足以用于tmux
。但是我不能仅仅将libevent2-devel
列为我的构建依赖项。该软件包不适用于RHEL 7或8,因为它们的默认libevent
RPM已经是版本2。我也不能将libevent-devel
列为构建依赖项,因为虽然libevent
和libevent2
软件包可以并排安装,但libevent-devel
和libevent2-devel
RPM冲突。
正如您在上面的规格文件中所看到的那样,我针对此挑战的解决方案是使用RPM宏根据以下内容将字符串libevent-devel
或libevent2-devel
注入到BuildRequires:
标头值中基于BASH的%{rhel}
宏值的比较(/etc/rpm/macros.dist
在RHEL 6、7上向其分配6
,7
或8
的值,或分别为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
依赖项(在末尾为,为2
)显示在RHEL6 RPM中;另一方面,RHEL8 RPM再次正确显示libevent >= 2.0
(末尾为 2
)。另外,在两个SRPM中都显示了对make
的构建依赖性,并且nomake
和wobble
均不存在,证明了模式与tmux*
和{{1}上的条件匹配}发挥了应有的作用。