Czym jest mutt - chyba wszyscy zainteresowani wiedzą. Więc bez zbędnych ceregieli przejdźmy do owieczki, jak zwykle oznacza to próbną instalację "zapoznawczą".
1. Konfiguracja źródeł. Po "./configure --help" wybieram sobie taki zestaw opcji:
./configure --prefix=/usr --with-curses --disable-pop \ --disable-imap --disable-nls
Po pierwsze, wybieram "siłowo" używanie ncurses zamiast libslang (na wszelki wypadek, mam obydwie te biblioteki w systemie ale wolę ncurses), poza tym wyłączam obsługę skrzynek pop/imap (bo do obsługi zewnętrznych skrzynek i tak używam fetchmaila, więc muttowa obsługa pop/imap mi się nie przyda). No i wyłączam nls. Znowu. Po prostu gdy ostatni raz widziałem tłumaczenie Mutta, to na górze ekranu widziałem polskie "Wyjdź", "Usuń", ale na dole tego samego ekranu były już ,Msgs:", "threads/date" i "all" - a takie połowiczne tłumaczenia mnie irytują. Więc wolę mieć całego Mutta po angielsku niż 70% po polsku.
2. Kompilacja. Udaje się :)
3. Testowa instalacja. "make install DESTDIR=/shm" podziałało. To dobrze.
4. Ogląd plików. Po "make install" powstało w /shm drzewko:
usr/
|-bin/
| |-flea
| |-mutt
| |-muttbug
| |-pgpewrap
| \-pgpring
|-doc/
| \-mutt/
| |-COPYRIGHT
| |-ChangeLog
| |-GPL
| |-INSTALL
| |-NEWS
| |-PGP-Notes.txt
| |-README
| |-README.SECURITY
| |-README.SSL
| |-TODO
| |-applying-patches.txt
| |-devel-notes.txt
| |-manual.txt
| |-patch-notes.txt
| |-samples/
| | |-Mush.rc
| | |-Pine.rc
| | |-Tin.rc
| | |-gpg.rc
| | |-pgp2.rc
| | |-pgp5.rc
| | |-pgp6.rc
| | |-sample.mailcap
| | |-sample.muttrc
| | |-sample.muttrc-tlr
| | \-iconv/
| | |-iconv.aix-3.2.5.rc
| | |-iconv.aix-4.1.5.rc
| | |-iconv.aix-4.2.0.rc
| | |-iconv.aix-4.3.2.rc
| | |-iconv.freebsd-3.3.rc
| | |-iconv.glibc-2.1.3.rc
| | |-iconv.glibc-2.1.90.rc
| | |-iconv.hpux-10.01.rc
| | |-iconv.hpux-10.20.rc
| | |-iconv.hpux-11.00.rc
| | |-iconv.irix-6.5.rc
| | |-iconv.osf1-4.0a.rc
| | |-iconv.osf1-4.0d.rc
| | |-iconv.solaris-2.4.rc
| | |-iconv.solaris-2.5.1.rc
| | |-iconv.solaris-2.6-cjk.rc
| | |-iconv.solaris-2.6.rc
| | \-iconv.solaris-2.7.rc
| \-html/
| |-manual-1.html
| |-manual-2.html
| |-manual-3.html
| |-manual-4.html
| |-manual-5.html
| |-manual-6.html
| |-manual-7.html
| \-manual.html
|-etc/
| |-Muttrc
| \-mime.types
\-man/
|-man1/
| |-flea.1
| |-mutt.1
| |-mutt_dotlock.1
| \-muttbug.1
\-man5/
|-mbox.5
\-muttrc.5
W zasadzie wygląda normalnie - katalog bin/, etc/, man/ - wszystko w porządku, pomijając drobne felery dotyczące lokacji etc/ (nie powinno się znajdować w usr/) oraz man/ (powinien być w podkatalogu share/) - ale to zostanie automatycznie skorygowane przez rpm-owe makro %configure. To co mnie zastanawia, to katalog doc/, a konkretnie to jego zawartość. Jest tam 1.2MB danych, z czego blisko pół megabajta to ChangeLog mutta, oraz dosyć rozległy podręcznik mutta, w wersji tekstowej i html. W zasadzie to jest mi to pewnie niepotrzebne, mutt ma całkiem niezłe strony manuala... chociaż może tę dokumentację w html-u warto by sobie zachować... tak, chyba tak zrobię. W trakcie budowania pakietu przeniosę podkatalog doc/mutt/html/ do katalogu doc/%{name}-%{version}/, a sam katalog doc/mutt/ usunę. Takie machlojki nie przystoją dystrybucjom, ale "osobom prywatnym" - czemu nie? W sumie mógłbym nawet w ogóle zrezygnować z dokumentacji innej od stron manuala, ale ta w html-u mi się podoba.
5. Pisanie pliku spec. Zaczynam z wymienionym już szkieletem pliku .spec. Po wstępnych przemyśleniach mam taki plik .spec:
Summary: Klient poczty pracujący w trybie tekstowym i obsługujący MIME. Name: mutt Version: 1.4.1i Release: 1 License: GPL Group: Internet Source: %{name}-%{version}.tar.gz BuildRoot: /var/tmp/%{name}-%{version} %description Mutt jest wysoce konfigurowalny. Ze swoimi zaawansowanymi funkcjami, jak mapowanie klawiatury, możliwość używania makr, wątkowanie wiadomości, wyszukiwania bazujące na wyrażeniach regularnych itp. jest jednym z najczęściej wybieranych przez PU klientów poczty. %clean rm -rf %{buildroot} %{_builddir}/%{name}-%{version} %prep %setup -q %build %configure -with-curses --disable-pop --disable-imap --disable-nls make %install rm -rf %{buildroot} make install DESTDIR=%{buildroot} mv %{buildroot}%{_docdir}/mutt/html %{buildroot}%{_docdir}/%{name}-%{version} rm -rf %{buildroot}%{_docdir}/mutt %files %defattr(0644,root,root,0755) %attr(0755,root,root)%{_bindir}/* %{_mandir}/man*/*.gz %config(noreplace) %verify(not size mtime md5) %{_sysconfdir}/* %{_docdir}/%{name}-%{version}
Wszystko jest w sumie jasne, omówić warto tylko sekcje %install i %files. W sekcji %install, po tym jak zainstaluję pliki, "koryguję" ułożenie dokumentacji - przenoszę podkatalog html/ do /var/tmp/mutt-1.4.1i/usr/share/doc/, nadając mu od razu nazwę "mutt-1.4.1i" (tyle że wyrażoną za pomocą makr - w razie upgrade-u "samo" się zmieni). A potem wywalam katalog /var/tmp/mutt-1.4.1i/usr/share/doc/mutt/. Tak to przynajmniej ma wyglądać w teorii.
Sekcja %files wygląda normalnie - wychwycić binarki, manuale, oznaczyć pliki w %{_sysconfdir}/ jako "trwałą" konfigurację i nakazać rpm-owi ignorować zmiany wywołane edycją tejże konfiguracji. No i w katalogu %{_docdir}/ wychwytuję tę moją nową dokumentację w html-u, razem z jej katalogiem. Teraz tylko sprawdzić, czy to zadziała :P
6. Budowanie pakietu. Dobra, kopiuję źródła mutt-1.4.1i.tar.gz do ~/rpm/SOURCES/, swój .spec mam zapisany w ~/rpm/SPECS/mutt.spec, wchodzę do katalogu ze specami, uruchamiam "rpmbuild -bb mutt.spec". I... błąd.
Executing(%prep): /bin/sh -e /tmp/rpm-tmp.9265
+ umask 022
+ cd /home/grzegorz/rpm/BUILD
+ cd /home/grzegorz/rpm/BUILD
+ rm -rf mutt-1.4.1i
+ /bin/gzip -dc /home/grzegorz/rpm/SOURCES/mutt-1.4.1i.tar.gz
+ tar -xf -
+ STATUS=0
+ [ 0 -ne 0 ]
+ cd mutt-1.4.1i
/tmp/rpm-tmp.9265[28]: cd: /home/grzegorz/rpm/BUILD/mutt-1.4.1i - No such file or directory
error: Bad exit status from /tmp/rpm-tmp.9265 (%prep)
RPM build errors:
Bad exit status from /tmp/rpm-tmp.9265 (%prep)
Uuu... coś poszło źle. Wygląda na to, że po rozpakowaniu źródeł nie mógł wejść do katalogu /home/grzegorz/rpm/BUILD/mutt-1.4.1i. Zaglądam do ~/rpm/BUILD/ i faktycznie - nie ma tam takiego podkatalogu. Jest za to mutt-1.4.1. Bez tego "i" na końcu. No tak, paczka nazywa się inaczej, a katalog który rozpakowuje inaczej. Dobra, usuwam ~/rpm/BUILD/mutt-1.4.1, no i muszę skorygować plik .spec...
7. Korygowanie speca. Dobra, więc rozpakowywane źródła lądują w katalogu innym niż %{name}-%{version} (bo w %{version} brakuje "i" na końcu). Mogę to rozwiązać na kilka sposobów, ale najlepiej będzie po prostu poprawić wywołanie makra %setup w sekcji %prep na coś takiego:
%prep
%setup -q -n %{name}-1.4.1
Do tego od razu zmieniam sekcję %clean, bo ona ma usunąć potem katalog ze źródłami, więc też musi znać jego nazwę:
%clean
rm -rf %{buildroot} %{_builddir}/%{name}-1.4.1
I będzie działać. Tyle tylko, że przy zmianie wersji źródeł oprócz poprawienia tagu Version: trzeba będzie też poprawić wersję wpisaną w linii %setup i w sekcji %clean. Ale jest inne wyjście :) Można wypchnąć "główną" wersję pakietu (1.4.1) do specjalnej zmiennej, a później używać tej zmiennej, ewentualnie dolepiając na jej koniec literkę "i". Ale to może innym razem. Sprawdźmy, czy po zmianie makra %setup pakiet się zbuduje...
8. Ponowna próba zbudowania pakietu. OK, wpisuję jeszcze raz "rpmbuild -bb mutt.spec". Sukces! Źródła zaczęły się kompilować! Teraz tylko instalacja i... znowu błąd. Ech:
make[2]: Leaving directory `/home/grzegorz/rpm/BUILD/mutt-1.4.1'
make[1]: Leaving directory `/home/grzegorz/rpm/BUILD/mutt-1.4.1'
+ mv %{buildroot}/usr/share/doc/mutt/html /var/tmp/mutt-1.4.1i/usr/share/doc/mutt-1.4.1i
mv: cannot stat `%{buildroot}/usr/share/doc/mutt/html': Nie ma takiego pliku ani katalogu
error: Bad exit status from /tmp/rpm-tmp.9411 (%install)
RPM build errors:
Bad exit status from /tmp/rpm-tmp.9411 (%install)
Czytam i widzę, że błąd dotyczy mojej korekty położenia plików z dokumentacją. Ale nie rozumiem o co chodzi... zaglądam do /var/tmp/mutt-1.4.1i... no tak. Katalog doc/ znajduje się bezpośrednio w usr/, a nie w usr/share/. Ale dlaczego? Przecież makro %configure przekazało na 100% poprawny argument "--docdir=%{_docdir}". Czyżby mutt go zignorował? Wchodzę do ~/rpm/BUILD/mutt-1.4.1/, jeszcze raz uruchamiam "./configure --help" - i faktycznie, mutt po prostu nie obsługuje opcji "--docdir". Zamiast niej ma "--with-docdir". Ręce opadają. Spec idzie jeszcze raz do poprawki.
9. I kolejna poprawka pliku .spec... No dobra, więc dodaję do wywołania ./configure jeszcze jeden argument, "--with-docdir=", przy okazji wprowadzam wspomnianą poprawkę dotyczącą wersji - wypycham wersję do osobnej zmiennej. Teraz cały spec wygląda tak:
%define wersja 1.4.1 Summary: Obsługujący MIME i pracujący w trybie tekstowym klient poczty. Name: mutt Version: %{wersja}i Release: 1 License: GPL Group: Internet Source: %{name}-%{version}.tar.gz BuildRoot: /var/tmp/%{name}-%{version} %description Mutt jest wysoce konfigurowalny. Ze swoimi zaawansowanymi funkcjami, jak mapowanie klawiatury, możliwość używania makr, wątkowanie wiadomości, wyszukiwania bazujące na wyrażeniach regularnych itp. jest jednym z najczęściej wybieranych przez PU klientów poczty. %clean rm -rf %{buildroot} %{_builddir}/%{name}-%{wersja} %prep %setup -q -n %{name}-%{wersja} %build %configure --with-curses --disable-pop --disable-imap --disable-nls \ --with-docdir=%{_docdir}/mutt make %install rm -rf %{buildroot} make install DESTDIR=%{buildroot} mv %{buildroot}%{_docdir}/mutt/html %{buildroot}%{_docdir}/%{name}-%{version} rm -rf %{buildroot}%{_docdir}/mutt %files %defattr(0644,root,root,0755) %attr(0755,root,root)%{_bindir}/* %{_mandir}/man*/*.gz %config %{_sysconfdir}/* %{_docdir}/%{name}-%{version}
Tutaj wyjaśnienia wymagają tylko dwie rzeczy - jedna to dodatkowa opcja do %configure, ale to zależy od samego mutta więc nie ma co wyjaśniać :), a druga rzecz to wprowadzenie nowej zmiennej, %{wersja}, w pierwszej linijce speca. Za pomocą polecenia %define. Nie chciałem tego pokazywać już na tym etapie, no ale tak jakoś wyszło. Składnia jest prosta - dwa argumenty - pierwszy to nazwa zmiennej do zdefiniowania/przedefiniowania, a drugi argument to wartość dla zmiennej. Za pomocą %define można zmienić wartość praktycznie każdej zmiennej używanej przez RPM, można też, jak ja tutaj, zdefiniować sobie jakąś nową zmienną. Teraz w przypadku uaktualniania paczki ze źródłami wystarczy pewnie zmienić numer wersji w tej linijce z %define i przebudować pakiet. Ale najpierw sprawdźmy, czy w ogóle da się ten pakiet zbudować...
10. Któreś tam z rzędu podejście do budowania pakietu. Nieco zrezygnowany wpisuję "rpmbuild -bb mutt.spec" i... udało się :) Mam pakiet binarny. Instaluję go, uruchamiam mutta - działa. W /usr/share/doc/mutt-1.4.1i/ mam dokumentację w formie html - czyli pełen sukces. Teraz tylko buduję sobie źródłowy pakiet RPM ("rpmbuild -bs mutt.spec --rmsource --rmspec") i kopiuję go w bezpieczne miejsce - może się kiedyś jeszcze przydać.
Tym razem było trudniej, niż z gqview - po pierwsze zechciało mi się zmienić domyślny skład pakietu, potem jeszcze musiałem walczyć z różnymi nazwami pakietu mutta i katalogu, który rozpakowywał się ze źródeł, a przeoczona muttowa niestandardowość (--with-docdir) kosztowała mnie jedną kompilację. Ale nie było to coś strasznego i mam swój własny plik .spec oraz źródłowy pakiet .rpm. Jest dobrze.