Portál AbcLinuxu, 28. května 2024 09:43

Rukověť baliče RPM - XIII (Makra, dokončení)

11. 8. 2005 | David Nečas
Články - Rukověť baliče RPM - XIII (Makra, dokončení)  

Temná zákoutí maker: podmínky, funkce, makra s argumenty a odskoky do shellu.

Makra II

Podmínky %if

Bylo by nadmíru zvláštní, kdyby existovaly %ifarch%ifos, a přitom žádné %if. A ono také existuje. Syntaxe je stejná jako u %ifarch a velmi připomíná preprocesor C (část s %else je nepovinná):

%if logický_výraz%else%endif

Logické výrazy vypadají, jak jsme zvyklí z většiny ostatních jazyků. Nula je nepravda, nenulové číslo pravda. Můžeme testovat existenci maker

%if %{?WITH_SELINUX:1}%{!?WITH_SELINUX:0}

porovnávat řetězce

%if "%{with_sasl1}" == "yes" || "%{with_sasl2}" == "yes"

nebo ověřovat platnost elementárních matematických tvrzení

%configure \
%if 2 + 2 == 5
    --with-funny-math \
%endif

Z posledního příkladu také vidíme, že řádky s podmínkami jsou po expansi kompletně vynechány (stejně jako řádky s %define a dalšími direktivami), a tak je můžeme bezpečně vkládat doprostřed čehokoli.

Funkce

Funkce připomínají makra, ale zatímco makro při použití na něco expanduje, funkce něco vykoná. Syntaxe volání funkcí je

%{název_funkce:argument}
%{název_funkce}
%{!název_funkce}

přičemž poslední dva příklady se týkají funkcí bez argumentů, které nastavují nějaký příznak.

K disposici máme následující funkce:

%{echo:…}, %{warn:…}, %{error:…}
Po řadě: vypíše argument na standardní výstup; vypíše argument na standardní chybový výstup a vyvolá fatální chybu s argumentem jako chybovou zprávou.
%{trace}, %{!trace}
Zapne, resp. vypne trasování expanse maker.
%{verbose}, %{!verbose}
Zapne, resp. vypne upovídanost (jako rpm --verbose).
%{dump}
Vypíše tabulku maker (jako rpm --showrc), jak vypadá právě v místě, kde se funkce provede.
%{expand:…}
Expanduje (vykoná) argument. Makra definovaná uvnitř %{expand:…} jsou lokální; mají-li být globální, musíme je definovat %global.
%{lua:…}
Provede Lua skript.
%{basename:…}
Expanduje na argument s odstraněnou cestou, tedy na samotný název souboru.
%{dirname:…}
Expanduje na argument s odstraněným jménem souboru, tedy na samotný název adresáře. Zatím není implementováno.
%{suffix:…}
Expanduje na koncovku argumentu.
%{url2path:…}, %{u2p:…}
Převede URL na cestu a název souboru.
%{uncompress:…}
Expanduje na příkaz, který dekomprimuje argument. Funguje pro soubory komprimované gzipem, bzip2em, zipem a nekomprimované.
%{S:…}, %{P:…}
Expandují na %SOURCEargument%PATCHargument – neexpandované, tj. ne na jejich hodnoty.
%{F:…}
Expanduje na fileargument.file. Pokud někdo tuší, k čemu to může být dobré, docela by mě to zajímalo.

S většinou funkcí se v existujících spec souborech potkáte zřídka, některé se však hodí při ladění.

Odskok do shellu

Odskočit do shellu, tedy vykonat v rámci expanse makra libovolný příkaz shellu, můžeme konstrukcí

%(příkaz_shellu)

Výstup příkazu se stane expansí makra. Lze to využít k ledasčemu, od nevinných konstrukcí

BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)

přes úlety typu

%define vendorstring Unsupported Custom Build by %(whoami)

až po věci, které sem raději nebudu psát, kterých však najdete dost ve spec souborech oblíbené rpmoidní distribuce. Kupříkladu standardní makra pro zjištění perlích adresářů (v nichž je pěkný guláš) vypadají:

%define perl_archlib %(eval "`perl -V:installarchlib`"; echo $installarchlib)

Těla maker se ovšem expandují až při použití. Proto když desetkrát použijeme %perl_archlib, bude se desetkrát spouštět perl a sdělovat nám, kde má jakýsi adresář. Efektivnější by bylo

%{expand:%global perl_archlib %(…)}

Takto však lze definovat makro jen ve spec souboru, nikoli v macros.

Makra s argumenty

Makra %setup%patch, i když to vlastně nejsou makra, mají různé volby, jež řídí jejich chování. Umí tohle náš kečup? Umí, i když nám po zjištění, z čeho se vaří, možná přestane chutnat.

Makro s argumenty definujeme

%define makro(volby) tělo_makra

Volby jsou seznam písmen volitelně následovaných dvojtečkami, jak jsme zvyklí z getopt(3). Makro %nibbler se dvěma volbami, -s bez argumentu a -t s argumentem, tak definujeme

%define nibbler(st:)

Expanse maker s argumenty se liší od obyčejných maker. Nejenže se makro nahradí svým tělem, ale spolkne přitom celý zbytek řádku, který se stává jeho argumenty:

$ rpm --define 'nibbler %%nibbler' --eval 'Makro %nibbler a argumenty'
Makro %nibbler a argumenty
$ rpm --define 'nibbler() %%nibbler' --eval 'Makro %nibbler a argumenty'
Makro %nibbler

Omezit nenažranost makra můžeme jeho uzavřením do funkce %{expand:…} nebo prostě jen složenými závorkami:

$ rpm --define 'nibbler() %%nibbler' --eval 'Makro %{expand:%nibbler} a argumenty'
Makro %nibbler a argumenty
$ rpm --define 'nibbler(s) %%nibbler' --eval 'Makro %{nibbler -s} a argumenty'
Makro %nibbler a argumenty

A teď bychom rádi ty spolykané argumenty z makra zase nějak dostali ven. Hodnotu argumentu -s, případně volbu samu získáme různými variacemi na %{-s}. Volbová makra (začínající pomlčkou) mají hodnotu voleb či argumentů jen uvnitř těla příslušného makra; volbová makra odpovídající nepřítomným či neexistujícím volbám se chovají částečně jako makra s prázdným tělem, částečně jako nedefinovaná.

Uvažujme definici

%define nibbler(prs:t:)

použitou

%nibbler -r -s plit -tall is short

Pak se různá volbová a argumentová makra expandují následovně:

%{-p}
Volba -p se nevyskytuje, proto expanduje na nic – jako prázdné makro.
%{-q}
Volba -q není ani deklarována, ale chová se stejně jako -p a expanduje na nic.
%{?-p:ppp}
Volba -p se nevyskytuje, proto expanduje na nic – jako nedefinované makro.
%{!?-p:ppp}
Volba -p se nevyskytuje, proto expanduje na ppp – jako nedefinované makro.
%{-r}
Expanduje na -r, tedy volbu samu.
%{?-r:rrr}, %{?-r:rrr}
Volba -r je přítomna, makro se tudíž chová jako definované a žádné překvapení se nekoná – první expanduje na rrr, druhé na nic.
%{-s}
Expanduje na -s plit, tedy na celou volbu s argumentem.
%{-t}
Expanduje na -t all, argument byl převeden na standardní tvar, tj. oddělen mezerou.
%{-t*}
Expanduje na all, tedy samotný argument volby -t.
%{*}
Expanduje na seznam zbývajících argumentů, tedy těch, které nejsou součástí žádných voleb: is short.
%{**}
Expanduje na úplný „příkazový řádek“ makra: -r -s plit -tall is short (bez makra samého).
%{#}
Expanduje na 2, tedy počet zbývajících argumentů makra.
%{2}
Expanduje na short, tedy druhý zbývající argument.
%{0}
Expanduje na jméno makra: nibbler.

Makra %defined()%undefined()

V novějších verzích RPM obsahuje standardní soubor macros definice testovacích maker %defined()%undefined() pro jednoduché testování existence makra:

%if %{defined makro1} || %{defined makro2}%endif

Jejich definice by už nyní měly být srozumitelné:

%define defined()   %{expand:%%{?%{1}:1}%%{!?%{1}:0}}
%define undefined() %{expand:%%{?%{1}:0}%%{!?%{1}:1}}

Seriál Rukověť baliče RPM (dílů: 15)

První díl: Rukověť baliče RPM - I (Úvod), poslední díl: Rukověť baliče RPM 15 - XV (Závěr).
Předchozí díl: Rukověť baliče RPM - XII (Makra, úvod)
Následující díl: Rukověť baliče RPM - XIV (Přizpůsobení)

Související články

Rukověť baliče RPM - I (Úvod)
Rukověť baliče RPM - II (Prostředí)
Rukověť baliče RPM - III (Struktura spec souboru)
Rukověť baliče RPM - IV (Fáze balení)
Rukověť baliče RPM - V (Zdrojové soubory)
Rukověť baliče RPM - VI (Makro %setup)
Rukověť baliče RPM - VII (Podepisování, verze)
Rukověť baliče RPM - VIII (Závislosti)
Rukověť baliče RPM - IX (Sekce %files)
Rukověť baliče RPM - X (Skriptíky)
Rukověť baliče RPM - XI (Architektury. systémy, platformy)
Rukověť baliče RPM - XII (Makra, úvod)
Rukověť baliče RPM - XIV (Přizpůsobení)
Rukověť baliče RPM 15 - XV (Závěr)
Na co se často ptáme: Balíčkovací systémy
Nebojíme se kompilace - I (Teorie)
Nebojíme se kompilace - II (GCC, configure, make, checkinstall)
Balíčkovací systém Mandrake Linuxu

Odkazy a zdroje

Doporučené čtení

Další články z této rubriky

VDR a DVB-T2, část 2.
VDR a DVB-T2, část 1.
Šifrovaný Proxmox VE 6: ZFS, LUKS, systemd_boot a Dropbear
MapTiler – proměňte obrázek v zoomovatelnou mapu
Syncthing

Diskuse k tomuto článku

13.8.2005 15:28 Michal Marek (twofish) | skóre: 55 | blog: { display: blog; } | Praha
Rozbalit Rozbalit vše Oprava
Odpovědět | Sbalit | Link | Blokovat | Admin
chybí vykříčník:
%{?-r:rrr}, %{!?-r:rrr}
Volba -r je přítomna, makro se tudíž chová jako definované a žádné překvapení se nekoná – první expanduje na rrr, druhé na nic.

ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.