2017-03-15 12 views
0

別のマクロから引数を取ってRPMマクロを呼びたいと思います。RPM:引数を持つ別のマクロの引数を持つマクロを呼び出す

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で明らか同等(m4では、これは自明この(ちょうど例ではなく、私は本当に何をしたいのか)のように行われます!)壊れて次のようになります。

# 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」を使用している場合、それはexamplのように失敗します上記のe。オプションを使うのはここでは直感的ではないようだから、私はこの解決策が大好きではありません。

希望する効果を得るには、どのような方法が良いでしょうか?

答えて

1

もっと洗練されたソリューションが見つかりました。それが動作する理由私は理解していない、と私はそれが一般的に適用可能かどうかわからない:それはmkd%globalと定義している場合にのみ機能します

%define path() /mnt/%1/lib 
%global mkd() mkdir %{path %%1}/stuff 
%mkd usr 
=> mkdir /mnt/usr/lib/stuff 

pathは、%defineまたは%globalのいずれかで定義できます。引用符で囲まれたパーセント記号もノードします。

+1

それを%globalは、(%defineとして)解析されたときではなく、呼び出された時点で評価されるためです。基本的に%を書くときは、いつも%globalを使いたいと思っています。 – msuchy

+0

@msuchyそれは逆です。 '%define'マクロは使用すると評価され、定義されているときは'%global'が評価されます。そのため、これはうまくいきます: 'mkd'の定義は、既に展開された' path 'で凍結されるので、引数が代入されると再帰は起こりません。 – matejcik

1

再帰マクロのRPM処理が壊れています。私が知ることができた限り、「推奨」方法はありません。これは単に機能しませんし、あなたがリストした回避策は、あなたが得ようとしているほど近くにあります。

RPMマクロセットの中では(RPM自体の中にはいくつか含まれています)、これは通常条件付き引数によって解決されます:オプションを指定した場合は%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 
関連する問題