- Name:
- Nazwa dla pakietu. To było łatwe do przewidzenia :)
Name: mutt
- Version:
- Wersja oprogramowania zawartego w pakiecie.
Version: 1.4i
- Release:
- Wersja, ale tym razem pakietu. Generalnie pakiety numeruje się
poczynając od jedynki, a numer wersji podwyższa się przy każdym
przebudowywaniu pakietu. Tak przynajmniej jest w dystrybucjach. W warunkach
domowych warto też podwyższać te numerki, bo mówią one rpm-owi że pakiet
jest ,,nowszy'', i można ,,gładko'' robić upgrade pakietów zawierających
oprogramowanie w tej samej wersji. Nie żeby to była jedyna możliwość, ale
odrobina porządku nigdy nie zaszkodzi.
Release: 3
- Epoch:
- Jest to bardzo rzadko używany tag, a w hierarchii tagów
,,wersjonujących'' stoi najwyżej, tworząc łańcuch epoch:version-release.
Można go użyć gdy pakiet zmienia system numerowania wersji, np. przechodzi
z układu numerowania za pomocą dat na ,,zwykły'' system numerków. Jako że
tag ten jest naprawdę, naprawdę rzadko używany, to chyba nic złego się nie
stanie jeśli poprzestaniemy na wyjaśnieniu, że Epoch: również
określa wersję i jest bardziej znaczący od Version:, nie
wspominając już o Release:. Nie jest wymagany, domyślnie ma wartość
,,0'', a jego przełączenie na wyższy numerek oznacza jakieś naprawdę
przełomowe zmiany w dotychczasowej numeracji lub właściwościach pakietu.
Muszą to być zmiany, których nie dałoby się jednoznacznie opisać za pomocą
tagów Version: i Release.
Epoch: 1
- License:
- Licencja. Jeśli kod jest na ,,wielokrotnej licencji'' (zdarza się), to
podaje się wszystkie dostępne do wyboru licencje, po przecinku. A, wcześniej
istniał (i nadal istnieje) bliźniaczy tag ,,Copyright:'', ale obecnie jest
on porzucany - wspominam o tym na wypadek, gdyby ktoś natknął się na
,,Copyright:'' w starszych specach.
License: GPL, BSD
- Group:
- Grupa do której ,,należy'' pakiet. Zwyczajowo używa się tutaj notacji
foo/bar, gdzie należy myśleć o foo jako kategorii ,,nadrzędnej'', a bar to
jakaś podkategoria w obrębie foo. Np. ,,Applications/Internet''. Co ważne:
nie ma jednolitego standardu nazewnictwa. Powiem więcej - burdel jest. Każda
dystrybucja używa innych określeń, a ja w swoim QuaTrin używam notacji
,,prostej'', bez podkategorii (które uważam za bzdurne), czyli np. po prostu
,,Internet''. Tag ten nie ma absolutnie żadnego znaczenia :) Jedyna jego
rola, oprócz dostarczania jakiejś tam informacji o zawartości pakietu,
została ukuta z myślą o jakichś nakładkach na rpm - dzięki kategoriom można
dzielić pakiety w gałęzie, podgałęzie itp. Można śmiało tworzyć bzdurne
nazwy dla kategorii, z chwilą zainstalowania takiego pakietu pojawi się nowa
kategoria. Gdy odinstaluje się ostatni pakiet w jakiejś kategorii, to taka
kategoria zniknie. Proste i niepotrzebne jeśli nie korzysta się z nakładek
na rpm które sortują pakiety w grupy.
Group: Aplikacje/Multimedia
- Source:
- Ten tag mówi RPM-owi skąd ma brać źródła programu. Źródła będą
wyszukiwane w podkatalogu SOURCES drzewka ,,budowlanego'' naszego rpm.
W tagu tym baaardzo często używa się URL-i, w formie np.
ftp://foo.bar.com/app/%{name}-%{version}.tar.gz, przy czym rpm
zignoruje wszystko aż do ostatniego ukośnika, więc w tym przykładzie
zrozumie tylko fragment %{name}-%{version}.tgz. Te zmienne których
użyłem w zapisie to wygodny sposób na odwołanie się do zawartości tagów
Name: i Version: - dzięki takiemu odwoływaniu do tagów przy zmianie np.
wersji programu wystarczy gdy zmienię tylko tag Version: - a tag Source:
zmieni się ,,automagicznie''. Tak więc rola tego wpisu jest podwójna
- z jednej strony mówi on, gdzie w sieci można znaleźć pakiet ze źródłami
(choć sam rpm na swoje potrzeby zignoruje wszystko aż do ostatniego
ukośnika), z drugiej strony wskazuje mechanizmowi RPM nazwę pliku ze
źródłami, który ten ma pobrać z katalogu SOURCES przy budowaniu. To oznacza,
że wcale nie trzeba się bawić z notacją URL-ową, można po prostu podać nazwę
pliku... Mam nadzieję, że to zrozumiałe.
Mała uwaga: jeden spec może wykorzystywać więcej niż jedną paczkę ze
źródłami. Używa się wtedy wielu wpisów, numerowanych, np. Source0:,
Source1:, Source2: itp. Source: oznacza to samo,
co Source0:
Źródła powinny być dostarczane w postaci paczek tar skompresowanych
programem gzip lub bzip2.
Source0: ftp://sunsite.unc.edu/pub/Linux/utils/console/%{name}-%{version}-src.tar.gz
Source1: ftp://sunsite.unc.edu/pub/Linux/utils/console/%{name}-%{version}-extra-src.tar.gz
- Patch:
- Tutaj podaje się listę patchy zawartych w pakiecie. Powinny się one
znaleźć w tym samym katalogu co paczka ze źródłami, a listę ich podaje się
podobnie do listy wielokrotnych źródeł, czyli Patch0:,
Patch1: itd. Zrozumiałe?
Patche mogą być skompresowane
programem gzip lub bzip2, w razie potrzeby rpm je sobie automatycznie rozpakuje.
Patch0: foo.patch
Patch1: bar.patch.bz2
- NoSource:
- Tag ten odgrywa rolę tylko przy budowaniu pakietów źródłowych. Jest
swego rodzaju uzupełnieniem dla tagów SourceX:, bo jako argument
NoSource: podaje się właśnie numer ,,X'' któregoś z wymienionych wcześniej
w preambule tagów Source:. Aby włączyć ten tag np. dla źródła z linii
Source3: wpisuje się ,,NoSource: 3''.
Kod źródłowy oznakowany tym tagiem nie zostanie włączony do pakietu
.src.rpm, więc potem do przebudowania takiego pakietu trzeba sobie
będzie ,,zorganizować'' ten brakujący kod z jakiegoś zewnętrznego źródła. Ma
to swoje zastosowanie, np. wyłączenie fragmentów kodu które nie są
OpenSource i nie można ich umieścić/dystrybuować w pakietach rpm, albo gdy
potrzebny do kompilacji kod jest ogólnie dostępny wszystkim ,,adresatom''
pakietu i nie opłaca się go wpychać w paczkę. W zasadzie tak zbudowane
pakiety źródłowe nie są zwykle niczym więcej jak opakowanymi w paczkę rpm
plikami .spec (no, chyba że NoSource: nie wymieni wszystkich
numerów tagów Source:).
NoSource: 0
NoSource: 2
- NoPatch:
- Ma się tak samo do Patch:, jak NoSource: do Source:
NoPatch: 1
NoPatch: 5
- BuildRoot:
- Można tutaj wskazać katalog ,,fake root'', czyli ten do którego będą
,,instalowane'' źródła w sekcji %install.
BuildRoot: /var/tmp/%{name}-%{version}
- BuildArch:
- Określenie architektury. Ma to pewien ;) wpływ na budowany pakiet jeśli
używa się domyślnych ustawień RPM-a, dodatkową rolą jest zadecydowanie
o tym, do jakiego podkatalogu w obrębie katalogu RPMS powędruje gotowy
pakiet. Można używać nazwy architektury, np. ,,i686'', można też użyć
,,noarch'' na określenie pakietu niezależnego od architektury.
BuildArch: i586
- URL:
- A ten tag z kolei ma wskazać zwykle położenie strony domowej lub
dokumentacji spakietowanego oprogramowania. Nie jest obowiązkowy, ale
w dystrybucjach powinno się go używać (aby użytkownik mógł łatwo znaleźć
stronę domową jakiegoś projektu).
URL: http://www.mplayerhq.hu/
- Distribution:
- Nazwa dystrybucji. Fakultatywna.
Distribution: Yesod
- Vendor:
- Ten tag oznacza, hmm, jak by to ująć... osobę lub firmę która
rozprowadza pakiet. To wcale nie jest jednoznaczne z osobą która stworzyła
pakiet ani z konkretną dystrybucją. To spore rozdrobnienie, ale niech
będzie. Ten tag też jest nieobowiązkowy.
Vendor: Yesod Software
- Packager:
- Osoba, która stworzyła pakiet. Nie nazwa dystrybucji, nie dystrybutor
pakietu, nie autor oprogramowania, ale osoba która stworzyła speca oraz
pakiet.
Packager: <wodnik@szuwarek.net>
- Summary:
- Skrótowy, jednolinijkowy opis (a w zasadzie to tylko lakoniczna
charakterystyka) dotycząca zawartości pakietu.
Summary: Prosty klient poczty używający gtk+
- %description
- To nie jest tak w zasadzie ,,zwykły'' tag, bo po pierwsze nie zajmuje
jednej linii, po drugie jego definicja znajduje się pod nim samym, a po
trzecie nie używa się kończącego dwukropka, za to konieczne jest
prefiksowanie znakiem procenta. Tutaj zamieszcza się wielolinijkowy opis
pakietu, rozciąga się on od wpisu %description aż do wystąpienia
następnej sekcji/tagów. A więc nie ma on jasnego końca - kończy się tam,
gdzie zaczyna się coś nowego :) Dawnymi czasy istniał tag
Description:, ale obecny format pozwala na więcej. Dlatego też
wydawać się może, że %description nie pasuje do reszty preambuły,
ale to po prostu dlatego, że jest to ,,wyewoluowany'' tag.
%description
A tutaj umieszcza się jakiś prosty, fikcyjny opis.
Może mieć wiele wierszy tekstu, można też
wstawiać całkowicie puste wiersze. Można tworzyć opisy
zajmujące linijkę, można też ,,popłynąć'' na dziesiątki linii.
- Provides:
- Ten tag pozwala określić czego ,,dostarcza'' budowany pakiet.
Standardowo pakiet może dostarczać różnych rzeczy - programów, bibliotek,
modułów perla, a nawet tzw. ,,wirtualnych'' zasobów, czyli takich które
fizycznie nie mają swojej jednoznacznej reprezentacji. Np. sendmail może
dostarczać zasobu zwanego ,,mail daemon''. I zwykle używa się
Provides: tylko w tym celu właśnie - aby powiedzieć, że pakiet
dostarcza jakiejś ,,wirtualnej'' zależności. Bo wszystkie inne są
automatycznie(!) wykrywane przy budowaniu pakietu. Np. rpm normalnie (w
przypadku standardowego budowania) wylistuje sobie automatycznie wszystkie
biblioteki czy programy zawarte w pakiecie, oraz doda do tego jedną
wirtualną zależność nazwaną tak samo, jak pakiet (czyli po prostu dla
pakietu xmms-1.2.5 ,,dostarczy'' wszystkich bibliotek, pluginów, no
i wirtualnego zasobu ,,xmms''). Bardzo proste, bardzo zautomatyzowane,
bardzo fajne.
Ale wracając do tematu: tag Provides: pozwala nam dodać coś do
listy oferowanych przez pakiet zasobów. Zwykle używa się tego
w dystrybucjach, np. można sprawić by zarówno sendmail, jak i postfix
dostarczały zasobu zwanego ,,mailserver'' - i uzależnić programy klienckie
od właśnie tego zasobu. Sprawi to, że obojętnie czy użytkownik zainstaluje
sendmaila czy postfiksa to program kliencki będzie zadowolony - ale będzie
wymagał obecności któregoś z nich. I to użytkownik będzie miał prawo wyboru
który serwer zainstalować. Jak widać, tag ten nie znajduje pewnie zbyt
często zastosowania. Aha, można podać więcej niż jeden zasób używając listy
rozdzielanej przecinkami lub spacjami (lub nawet jednym i drugim naraz)
Provides: wwwserver
- Requires:
- Tutaj można podać pakiety, od których budowany pakiet ma zależeć. Zwykle
jest tak, że nie ma potrzeby tego robić ręcznie - przy budowaniu pakietu sam
rpm przeskanuje biblioteki i pliki wykonywalne, skrypty shellowe oraz
perlowe i inne takie, po czym samodzielnie zestawi listę wymaganych
bibliotek, interpreterów, czy nawet modułów perla. Dlatego tag
Requires: zwykle używany jest tylko wtedy, gdy chce się wymusić
zależność od konkretnego innego pakietu, albo od wirtualnej zależności.
A więc jest to lustrzane odbicie Provides:, z tym że znajduje
częściej zastosowanie. A dlaczego częściej? Bo uzależnia się często od
siebie pakiety które mają zależność logiczną, ale niekoniecznie
binarno-linkerowo-whateverową ;) Prosty przykład: Program ViM. Zwykle jest
dzielony na kilka paczek - jedną zawierającą dane używane ,,runtime'', czyli
np. zestawy kolorów do podświetlania różnych składni, jedną zawierającą
zwykłego ViM-a i jedną zawierającą gViM-a. Nazwijmy te paczki
,,vim-shared'', ,,vim'' oraz ,,gvim''. Teraz tak: ,,vim-shared'' zawiera
wszystkie dane, oprócz binariów. ,,vim'' zawiera zwykłą wersję vim-a,
a ,,gvim'' jego wersję z GUI. Należy uzależnić pakiety ,,vim'' i ,,gvim'' od
,,vim-shared'', ale RPM nie zrobi tego automatycznie, bo nie posiada
przecież sprawności wróżki :). Dlatego w pakietach ,,vim''/,,gvim'' człowiek
je tworzący powinien zamieścić ,,Requires: vim-shared''.
Tutaj jeszcze jedna sprawa: Można przy zależnościach mówić o numerach
wersji. Np. jeśli powiem, że vim-6.1 wymaga po prostu ,,vim-shared'', to rpm
pozwoli również na zainstalowanie np. dużo starszej (i pewnie
niekompatybilnej) wersji ,,vim-shared-5.0''. Fajnie by było, gdyby można
było jakoś wymusić dozwalony numer wersji. I faktycznie można. Np.
,,Requires: vim-shared = 6.1''. Można też trochę rozluźnić rygor
i powiedzieć np. ,,Requires: vim-shared >= 6.1''. To chyba
zrozumiałe?
Jest jeszcze jedno dosyć częste zastosowanie tej funkcji: Można uzależnić
pakiet nie tylko od biblioteki, ale także od konkretnej nazwy pakietu. O co
mi chodzi? O to, że oprócz tego że program zgv zależy od libvga.so.1 to
można go uzależnić od pakietu tę bibliotekę dostarczającego, czyli svgalib.
Ale po co, mógłby ktoś zapytać? Przecież zależność już istnieje, poprzez
libvga.so.1? To prawda, samemu systemowi RPM nie jest to potrzebne. Ale może
to być wygodne dla użytkownika - jeśli spróbuje zainstalować zgv nie
posiadając svgalib, to zobaczy że zgv wymaga takich to a takich bibliotek,
oraz czegoś zwanego ,,svgalib''. Będzie mu łatwiej znaleźć potrzebne
pakiety. Ale takie praktyki są moim zdaniem na wymarciu. Kiedyś uważało się
je za znak wysokiego dopracowania pakietów, jeśli faktycznie oprócz
wymagania libgtk.so.1 wymagały także ,,gtk+ >= 1.4.10''. Obecnie jednak
takie rzeczy potrafią załatwić za człowieka automaty w stylu programu
,,Poldek'' czy innych. Bo nie wolno zapominać, że wprowadzanie takich
,,fikcyjnych'' zależności zmniejsza przenośność pakietu. Wystarczy, że
w jednej dystrybucji pakiet zawierający libvga.so.1 będzie nazywał się
,,svgalib'', w drugiej ,,SVGAlib'', w trzeciej ,,libsvga'' i już nie będzie
przenośności między nimi, bo pakiet wymaga koniecznie obecności zasobu
,,svgalib''. Warto to wziąć pod rozwagę...
Requires: svgalib >= 1.9.14
- Autoreq:
- Ten tag pozwala wyłączyć automatyczne wyszukiwanie zależności przez RPM.
Wtedy trzeba je wszystkie podać poprzez tag Requires:
Autoreq: 0
- Autoprov:
- Podobnie, z tym że wyłącza się automatyczne wykrywanie tego, co dany
pakiet dostarcza. Wtedy cała robota spada na autora speca i linijkę
Provides:
Autoprov: 0
- Autoreqprov:
- A to po prostu połączenie obydwu powyższych tagów. Wyłącza od razu
wszystkie mechanizmy automagicznego wykrywania zależności.
Autoreqprov: 0
- BuildRequires:
- Ten tag określa pakiety/biblioteki potrzebne do przebudowania pakietu.
Są to zależności które trzeba podać ,,ręcznie''. Jeśli program np. używa
ncurses, to w BuildRequires: należałoby wpisać ,,ncurses-devel''.
Nie ma to wielkiego wpływu na samo budowanie pakietu, ale użytkownik
przynajmniej dowie się od razu, że czegoś mu brakuje do skompilowania
pakietu - jeśli nie będzie posiadał ncurses-devel, to rpm nawet nie zacznie
budowania pakietu, a od razu się poskarży. Tag ten nie ma zastosowania
w ,,domowej'' produkcji pakietów na własne potrzeby, ale przy szerszej
dystrybucji należy uwzględnić tutaj każdy wykorzystywany pakiet - oszczędzaj
ewentualnych odbiorców swoich pakietów ;).
BuildRequires: flex
- BuildConflicts:
- A ten tag z kolei pozwala ,,zablokować'' przebudowywania pakietu jeśli
jest obecny w systemie jakiś konkretny pakiet. Jeśli wiadomo, że obecność
jakiegoś pakietu by nie pozwoliła wyprodukować poprawnych binarek, np. można
się zabezpieczyć w ten sposób przed użyciem jakiejś starej, wadliwej wersji
binutils. Rzadko używany tag, ale z przyzwoitości muszę o nim wspomnieć.
BuildConflicts: gcc = 2.96.1
- Obsoletes:
- Pakiety wymienione tutaj jako argumenty zostaną usunięte przy instalacji
nowo utworzonego pakietu. Tzn. gdy zainstalujesz ten pakiet, to wszystkie
wymienione w Obsoletes: zostaną automatycznie usunięte. Przydatne
jeśli przygotowywany pakiet ma za zadanie całkowicie zastąpić jakichś swoich
poprzedników (np. noszących inne nazwy). Można np. uznać, że pakiet slrn-pl
jest w stanie zastąpić slrn, albo że elinks może zastąpić linksa. Albo że
nowy pakiet fvwm powinien zastępować fvwm2.
Obsoletes: slrn, slrnpull
- PreReq:
- Tag ten działa podobnie do Requires:, z tym że zależność ta
konieczna jest do poprawnej instalacji pakietu. Normalne
Requires: oznacza, że pakiet potrzebuje innego do swojej pracy.
PreReq: oznacza, że pakiet potrzebuje innego pakietu/zasobu nie
tyle do swojej pracy, co do swojej instalacji. Potrzebuje czegoś, aby
w ogóle poprawnie się zainstalować/odinstalować. Chodzi tu głównie
o polecenia shella użyte w sekcjach %pre czy %post
PreReq: /sbin/install-info
- BuildPreReq:
- Dodatek do PreReq:. Działa tak samo jak PreReq:, z tym
że obowiązuje tylko podczas budowania pakietu. Bardzo rzadko używany, pewnie
dlatego, że funkcjonalnie pokrywa się z BuildRequires :)
BuildPreReq: perl
- DistURL:
- Tag jeszcze nie występujący w pakietach. W zamierzeniu miałby wskazywać na
stronę dystrybucji, ale jego standardyzacja nie dobiegła jeszcze końca.
???
- Icon:
- Tutaj określa się ,,namiar'' na plik z ikoną. Jedyne tego zastosowanie
to fakt, że niektóre graficzne package-managers będą w stanie pokazać tę
ikonkę jako ,,ikonkę pakietu''. Ikonka powinna być formatu GIF lub XPM
(zalecany to XPM), z przezroczystym tłem (żeby ikonka porządnie wyglądała
w takim np. ,,gnorpm'')
Icon: czaderska_ikonka_pakietu.xpm
- Conflicts:
- Proste - wskazuje coś, co po prostu nie może koegzystować w systemie
z naszym pakietem. Np. program ,,masqmail'' nie powinien być instalowany
równolegle z sendmailem, bo obydwa robią to samo. No dobra, przykład głupi,
ale nic innego mi do głowy nie przychodzi :)
Conflicts: sendmail
- ExcludeArch:, ExcludeOS:, ExclusiveArch:, ExclusiveOS:
- Wymieniam je hurtem, bo są nieczęsto używane, powiązane ze sobą i mają
w miarę opisowe nazwy. Regulują ,,dostępność'' pakietu w zależności od
architektury lub systemu operacyjnego. Opcje Exclude* zabraniają
budowania pakietu na określonej architekturze/systemie operacyjnym, a opcje
Exclusive* z kolei zezwalają na budowę tylko i wyłącznie na
podanych architekturach/systemach. Te opcje to coś w stylu ,,Nie zbudujesz
tego pakietu na...'' oraz ,,Zbudujesz ten pakiet tylko na...''. Kwestia
architektury jest jasna - można np. zabronić budowania jakiegoś programu
uzależnionego od instrukcji mmx na maszynach które tego nie potrafią, można
też np. wyłączyć całą rodzinę x86 jeśli program jest przeznaczony dla
komputerów Alpha. Zdziwienie może budzić tylko uzależnianie od systemu
operacyjnego - ale to się da łatwo wyjaśnić: RPM ma ambicje stania się
uniwersalnym systemem pakietowania. Jeśli będzie popularny na większej
ilości systemów operacyjnych, to oczywiście konieczne stanie się odróżnianie
pakietów przeznaczonych dla Linuksa od tych zrobionych specjalnie dla
Hurda.
ExcludeOS: irix
- Prefix:
- Definiuje prefiks, czyli początkowy fragment ścieżki, używany przy
instalacji pakietu. Pole to można przedefiniować przy instalacji pakietu, co
spowoduje że pliki wywędrują do innej niż domyślna lokacji. Jeśli program
składa się raptem z kilku binarek i stron manuala, to można stworzyć taki
,,relokowalny'' pakiet, który użytkownik będzie potem mógł zainstalować albo
w /usr, albo w /usr/local, albo w /opt, albo w /usr/X11R6 - wedle życzenia.
Oczywiście nie zawsze da się coś takiego zrobić, niektóre programy szukają
swoich danych w ściśle określonych miejscach.
Prefix: /opt
Pominąłem kilka już zupełnie rzadkich (lub słabo udokumentowanych) tagów...