RPM:使用带有参数

时间:2017-03-15 10:22:06

标签: linux macros rpm packaging

我想从另一个宏调用一个RPM宏。在m4中,这可以像这样简单地完成(只是一个例子,而不是我真正想做的事):

define(`path', `/mnt/$1/lib')
define(`mkd', `mkdir path($1)/stuff')
mkd(`usr')
=> mkdir /mnt/usr/lib/stuff

CPP语法:

#define path(x) /mnt/x/lib
#define mkd(x) mkdir path(x)/stuff
mkd(usr)
=> mkdir /mnt/usr/lib/stuff

RPM中的明显等价物(破碎!)将是:

# THIS IS BROKEN
%define path() /mnt/%1/lib
%define mkd() mkdir %{path %1}/stuff
%mkd usr

但是没有工作,RPM打印" 错误:宏扩展中的递归级别太多。它可能是由递归宏声明引起的。"

我已经做到了"工作"使用以下代码:

%define path() /mnt/%1/lib
%define mkd() mkdir %{expand:%%{path %1}}/stuff
%mkd usr

但是,我无法相信这种笨拙的代码是推荐的方法。另一种似乎有用的方法是使用选项参数:

%define path(d:) /mnt/%{-d*}/lib
%define mkd(p:) mkdir %{path -d%{-p*}}/stuff
%mkd -p usr

但这只是因为我使用了不同的选项字符;如果我使用' -d'对于这两个宏,它都像上面的例子一样失败。我也不喜欢这个解决方案,因为在这里使用选项似乎不直观。

达到预期效果的首选方法是什么?

3 个答案:

答案 0 :(得分:1)

我找到了更优雅的解决方案。我不明白为什么它有效,我不确定它是否普遍适用:

...
login() {
    this.authService.loginWithGoogle().then((data) => {
        this.router.navigate(['']);
    }).catch((error) => {
        this.error = error;
    });
}

仅当%define path() /mnt/%1/lib %global mkd() mkdir %{path %%1}/stuff %mkd usr => mkdir /mnt/usr/lib/stuff 定义为mkd时才有效。可以使用%globalpath来定义%define。同时节点引用的百分比字符。

答案 1 :(得分:1)

递归宏的RPM处理被破坏。据我所知,没有“推荐”的方式;这根本不起作用,你列出的变通方法就像你将要获得的那样接近。

在我看到的RPM宏集中(包括RPM本身内部的一些),这通常通过条件参数来解决:如果提供,则使用-p选项,否则为%1

%define path(p:) /mnt/%{-p:%{-p*}}%{!-p:%1}/lib
%define mkd(d:)  mkdir %{path -p %1}/stuff
echo "making path at %{path hello}"
%{mkd hello}

您还可以使用“非功能”定义 - 这是%define / %global案例中发生的事情。

%define _path /mnt/%1/lib
# note no parentheses at end of `_path`
%define path() %_path
%define mkd()  mkdir %{_path}/stuff

这样,%_path宏内联到path()mkd()定义中,并且没有发生递归。

如果您想使用%2作为路径,这将无效,但由于这是一个不同的名称,您可以使用旧方式......... o_O

%define maketwo() mkdir %1; mkdir %{path %2}/stuff

答案 2 :(得分:0)

似乎该问题中报告的问题已在最新版本的rpm(4.11和4.14之间)中解决。

~> rpm --version
RPM version 4.14.1
~> rpm --eval '
%define path() /mnt/%1/lib
%define mkd() mkdir %{path %1}/stuff
%define foo bar
%mkd %foo'

=> mkdir /mnt/bar/lib/stuff

在rpm 4.11下,由于“递归级别过多”而失败,因此必须解决上一个答案(%global mkd() mkdir %{path %%1}/stuff)。