- předchozí článek - následující článek - obsah - úvodní stránka - - předchozí část - následující část - první část -

Linuxové noviny 07/98

Další sekce spec-souboru

Jan Kasprzak, 17. července 1998

V minulém čísle našeho seriálu o systému RPM jsem začal detailně popisovat formát spec-souboru, který řídí vytváření RPM balíku. Vysvětlil jsem, jaký význam mají jednotlivé tagy v hlavičce souboru, a nyní budu pokračovat výkladem o dalších sekcích spec-souboru. Některé sekce jsou povinné, jiné nepovinné. Sekce začíná znakem % a svým názvem na začátku řádku. Pořadí sekcí ve spec-souboru není definováno - zde budou jednotlivé sekce uvedeny v jakémsi logickém uspořádání.

Se sekcí %description jsme se už setkali. Tato sekce je povinná a obsahuje textovou informaci o určení a použití balíku. Tuto sekci využívá například instalační program Red Hat Linuxu, když se klávesou F1 dotážeme na podrobnější informace o balíku.

Další sekce je nazvaná %changelog a jak již její název praví, zachycuje protokol o změnách ve spec-souboru (nikoli tedy v softwaru samotném. Jednotlivé záznamy začínají hvězdičkou na první pozici řádku, následuje datum a jméno člověka, který změnu provedl. Na dalších řádcích pak může být popis změny. Příklad části sekce %changelog z balíku ssh je na výpisu Příklad sekce changelog.


* Thu Jun 11 1998 Jan "Yenya" Kasprzak <kas@fi.muni.cz>
- updated to 1.2.25.
- fixed truncated .pam patch.
- built on RedHat 5.1 (and tested upgrade on 5.0 too).

* Wed May 20 1998 Jan "Yenya" Kasprzak <kas@fi.muni.cz>
- Updated to 1.2.23:
- removed the -NYP patch (no longer necessary).
- removed the -tmpfile patch (no longer necessary).
- added %post scripts linking the ssh*1 binaries and manpages as ssh*
        if no such links exist. This will allow a coexistence of
        ssh1 and ssh2 RPMs on one system.

Výpis č. 5: Příklad sekce changelog

Sekce %prep

Tato sekce již není jen pouhý text, ale je to shellový skript. Úkolem tohoto skriptu je rozbalit příslušné zdrojové archivy a nainstalovat potřebné záplaty. Tento skript (stejně jako skripty z dalších sekcí) je spuštěn shellem s parametrem -e, který říká, že shell má ukončit provádění skriptu s chybou, skončí-li libovolný z příkazů ve skriptu s chybou (s nenulovou návratovou hodnotou). Na tuto skutečnost je potřeba pamatovat při psaní skriptů. Není například možné používat konstrukce typu

test -r /etc/ssh/ssh_host_key && ssh-keygen blabla

Namísto toho je nutné použít následující ekvivalent:

if test -r /etc/ssh/ssh_host_key;
	then ssh-keygen blabla; fi

Skript z této sekce, stejně jako ostatní skripty, má k dispozici některé speciální proměnné prostředí. Uvádím je zde spolu s příklady hodnot nebo s implicitními hodnotami:

  • RPM_SOURCE_DIR=/usr/src/redhat/SOURCES - adresář, ve kterém jsou uloženy zdrojové archivy a záplaty. Skript %prep odsud může rozbalovat tyto archivy a aplikovat záplaty.
  • RPM_BUILD_DIR=/usr/src/redhat/BUILD - adresář, ze kterého je skript spuštěn. Sem se pak rozbalí jednotlivé zdrojové archivy a zde probíhá kompilace.
  • RPM_DOC_DIR=/usr/doc - adresář, do kterého se ukládá dokumentace k balíku.
  • RPM_ARCH=i386 - architektura, pro kterou se aktuální balík vytváří.
  • RPM_OS=Linux - operační systém, pro který se aktuální balík vytváří.
  • RPM_OPT_FLAGS="-O2 -fno-strength-reduce -m486" - optimalizační přepínače pro kompilátor jazyka C.
  • RPM_BUILD_ROOT=/tmp/ssh-root - specifikace adresáře BuildRoot.
  • RPM_PACKAGE_NAME=ssh - jméno balíku.
  • RPM_PACKAGE_VERSION=1.2.25 - verze softwaru.
  • RPM_PACKAGE_RELEASE=1i - verze RPM balíku.

Makra

Skript %prep vykonává ve většině balíků podobnou činnost - vezme soubor SourceN a rozbalí jej v příslušném adresáři, měl by nastavit správně vlastníka a přístupová práva vůbec, a dále aplikuje záplaty. Tato činnost se opakuje natolik často, že pro ni systém RPM poskytuje makra - tedy zkratky pro více příkazů. Takový typický %prep-skript s jedním zdrojovým archivem a jednou záplatou pak vypadá asi takto:

  %prep
  %setup
  %patch -p1

Makro %setup vezme zdrojový archiv, uvedený v hlavičce jako Source, resp. Source0, rozbalí jej do adresáře BUILD, změní vlastníka všech souborů na superuživatele (to pouze v případě, že balík vytváří superuživatel) a nastaví bity r a x pro všechny uživatele.

Makro %patch aplikuje záplatu, uvedenou v hlavičce jako patch, resp. patch0. Přepínač -p1 z našeho příkladu je předán programu patch(1).

Skript %prep samozřejmě nemusí sestávat pouze z volání maker %setup a %patch. Může obsahovat i další příkazy, například je-li program konfigurován pomocí systému GNU autoconf a modifikujeme-li konfigurační soubor configure.in, můžeme v této sekci přegenerovat skript configure příkazem autoreconf (tuto konstrukci naleznete mimo jiné i ve spec-souboru Secure Shellu - tam se přidává podpora pro PAM do configure.in, a musí se tedy přegenerovat configure. Kromě toho makra mohou mít i parametry, kterými se specifikují další vlastnosti. K těmto vlastnostem se vrátíme v dalším díle našeho seriálu.

Sekce %build - kompilace softwaru

Tato sekce, stejně jako předchozí, je interpretována jako shellovský skript. Tento skript by měl provést vlastní kompilaci softwaru. Ve většině případů si vystačíme s následující formou:

  %build
  ./configure
  make CFLAGS="$RPM_OPT_FLAGS" all

Příkazu configure, pokud jej program podporuje, můžeme samozřejmě dávat i další parametry (třeba --with-gcc --prefix=/usr). Tohle je vůbec dost diskutabilní věc: podle Linux Filesystem Hierarchy Standard (FHS, dříve FSSTND) by lokálně instalovaný software měl být instalován do adresáře /usr/local, zatímco software, který patří k systému samotnému by měl být v /usr. Ovšem je software, který zabalíte do RPM a distribuujete, součástí systému, nebo je spíš blíže lokální instalaci? Můj názor na tuto problematiku je ten, že /usr/local bylo zavedeno proto, aby bylo možné ty lokálně instalované věci odlišit. Ale máme-li RPM, máme na odlišení jiné a lepší prostředky (například položku Distribution nebo Packager v hlavičce RPM balíku). Moje RPM balíky se tedy instalují přímo do systémových adresářů, nikoliv do /usr/local.

Sekce %install - instalace softwaru

Instalační sekce je také shellovský skript. Účelem tohoto skriptu je přemístit konfigurační soubory, zkompilované binární soubory, dokumentaci a různé další soubory na místo jejich použití. Úplně nejjednodušší formou této sekce je příkaz make install. Ale chceme-li umožnit rekompilaci RPM balíku i uživateli, který není superuživatelem, měli bychom spec-soubor navrhovat tak, aby používal tag BuildRoot. Pak instalace probíhá do adresáře $RPM_BUILD_ROOT místo kořenového adresáře. Většina Makefile-souborů předpokládá, že bude k dispozici aspoň základní struktura adresářů a souborů v systému. Proto většinou v této sekci musíme potřebný strom adresářů předem vytvořit. Sekce pak může vypadat takto:

  %install
 mkdir -p ${RPM_BUILD_ROOT}/usr/{bin,lib,man/man1}
 make prefix="${RPM_BUILD_ROOT}/usr" install

Je dobré vědět, že ne všechny programy jsou schopny být kompilovány s jiným prefixem, než se kterým jsou pak instalovány. V takových případech nezbude než ručně zjistit, co přesně dělá příkaz make install, a jeho činnost pak nasimulovat v sekci %install s příslušným BuildRoot. U některých balíků je i tento postup příliš náročný, a proto se instalují přímo na místo určení. Takovýto balík pak ovšem může rekompilovat jen superuživatel. Příkladem takového balíku je například tetex.

Pokud balík nepoužívá BuildRoot, je podstatně náročnější jej odladit. Takovéto ladění a pokusná instalace by měly probíhat na jiném počítači, než vlastní kompilace. Může se totiž stát (a je těžké to odhalit), že do balíku zapomeneme přibalit některý důležitý soubor. Na původním počítači vše funguje, protože tento soubor tam zbyl po make install. Jinde balík ale selže.

Sekce %clean - smazání meziproduktů

Pokud při kompilaci vznikají nějaké meziprodukty mimo adresář BUILD, například v /tmp, je na sekci %clean, aby tyto meziprodukty promazala.

V příští části tohoto seriálu se dozvíme, jak specifikovat soubory patřící k balíku a jaké další skripty mohou ve spec-souboru být. *


- předchozí část - následující část - první část - - předchozí článek - následující článek - obsah - úvodní stránka -