Tworzenie własnych pakietów z oprogramowaniem w dystrybucji GNU/Linux Debian
Pracując na Linuksie, niezależnie od dystrybucji prędzej czy później zaczniemy własne tworzyć narzędzia sprowadzające wiele czynności wykonywanych w systemie do uruchomienia jednego polecenia. Mogą to być zarówno skrypty języków interpretowanych lub kompilowane programy. Chcąc korzystać z naszych narzędzi na innych urządzeniach niż nasz komputer powinniśmy zapewnić im jakiś system dystrybucji. Przychodzącym na myśl rozwiązaniem wydaje się system kontroli wersji Git, jednak ten system został opracowanym z myślą o zarządzniu kodem źródłowym i utrzymaniu w nim porządku. Sposobem jaki możemy wykorzystać na rozpowszechnienie naszego oprogramowania lub ułatwnienie dostępu do niego jest ten wbudowany w nasz system (dystrybucję). Repozytoria Git często zawierą kod źródłowy, który musi zostać skompilowany a do tego mogą być wymagane dodatkowe biblioteki. Skrypty również mogą wymagać dostępności oprogramowania, które trzeba dodatkowo zainstalować. Pakiety oprogramowania posiadają zależności, które powodują wymóg na programie zarządzającym pakietami zainstalowanie wymaganych bibliotek/programów przed instalacją. Pakiety oprogramowania zapewniają środowisko do uruchomienia aplikacji, dla której zostały zbudowane.
W tym materiale poruszymy proces przygotowania pakietów dla skryptów języków interpretowanych, a nie programów kompilowanych. Przygotowanie pakietów dla tego rodzaju oprogramowania jest bardziej złożonym zagadnieniem, do którego odsyłam do źródeł (link nr. 2). Uruchomienie programu odpowiedzialnego za złożenie pakietu w przypadku programów kompilowanych rozpoczyna proces kompilacji, dlatego też potocznie używa się zwrotu "budowanie pakietów" na określenie przygotowywania pakietów. Tutaj również takie wyrażenie może się pojawić.
Na początek potrzebujemy pakietu, który nazywa się lintian - on będzie weryfikować poprawność utworzonego pakietu. Utworzenie pakietu dystrybucji Debiana sprowadza się do operacji na plikach, katalogach oraz uruchomieniu jednego ewentualnie dwóch programów. Dlatego też na początku instalujemy pakiet lintian.
xf0r3m@debian:~$ sudo apt install -y lintian
Po zainstalowaniu tego programu to tak naprawdę mamy gotowe środowisko do tworzenia pakietów. Być może będziemy potrzebować dodatkowego pakietu ale o tym poźniej. Proces budowania pakietu najlepiej rozpocząć od utworzenia odpowiedniej struktury katalogowej.
Na początku tworzymy katalog z nazwą skryptu/pakietu. Wewnątrz niego tworzymy katalogi dla skryptu, informacji o zmianach oraz prawach autorskich i stronie podręcznika.
xf0r3m@debian:~/helloworld$ mkdir -p usr/{bin,share/{doc/helloworld,man/man1}}
Pakiety Debiania nie instalują programów w katalogu
/usr/local/bin.
Struktura katalogowa /usr/local służy wyłącznie użytkownikowi i
jest przeznaczona dla lokalnie przez niego instalowanych programów.
Inaczej jest w przypadku katalogu /usr/bin. Nasze narzędzia będą
zazwyczaj poleceniami użytkownika stąd też odpowiedni rozdział
podręcznika man1.
Następnym katalogiem do utworzenia jest katalog o nazwie DEBIAN. Przechowywał on będzie wszelkie informacje o pakiecie i nie wchodzi on w skład środowiska aplikacji w katalogu usr. Pełni on jedynie funkcje konfiguracyno-informacyjną.
xf0r3m@debian:~/helloworld$ mkdir DEBIAN
Pliki oraz katalogi w pakietach muszą mieć odpowiednie uprawnienia. Katalogi, pliki wykonywalne - 755, a pliki regularne - 644. Oczywiście zmiany uprawnień możemy dokonać przed samym budowaniem, jednak będzie to uciążliwe, ponieważ dla każdego z elementów będziemy musieli wydać jedno polecenie. Jeśli zrobimy to teraz, wówczas wydamy jedno polecenie dla całej struktury katalogów.
xf0r3m@debian:~/helloworld$ chmod -R 755 .
Po utworzeniu struktury, możemy skopiować nasz skrypt do katalogu usr/bin pomijając jego rozszerzenie, jeśli takowe posiada. Pliki w usr/bin nie posiadają rozszerzeń. Pliki wykonywalne powinny mieć również ustawione uprawnienia na 755, więc należy na to zwrócić uwagę.
xf0r3m@debian:~/helloworld$ cp ~/helloworld.sh usr/bin/helloworld xf0r3m@debian:~/helloworld/usr/bin$ chmod 755 helloworld
Następnie możemy przjeść do plików dokumentacji naszego skryptu. Debian wymaga, aby każdy pakiet posiadał opis zmian oraz informacje na temat praw autorskich zawartych w nim plików. Tego rodzaju informacje są przechowywane w katalogu usr/share/doc/nazwapakietu. Na początek przyjrzymy się opisowi zmian. Plik nosi nazwę changelog i po zakończeniu jego edycji musi on zostać skompresowany. Na początek jednak znajmiemy się jego treścią ponieważ układ jest dość specyficzny, a co gorsza pakiet lintian sprawdza poprawność zapisu pliku zmian. Poniżej znajduje się przykładowa zawartość pliku zmian.
helloworld (0.0.1) stable; urgency=low [ xf0r3m ] * Create a dummy script for print 'Hello, World!' Requesting for better changelogs. -- xf0r3m <xf0r3m@gmail.com> Wed, 31 Dec 2025 15:53:00 +0100
Każdy wpis w opisie zmian składa się z nagłówka, informacji o dokonanych zmianach oraz ze stopki. W nagłówku znajdują się kolejno nazwa pakietu, w nawiasach jego wersja, następnie dystrybucja dla której przygotowano ten pakiet - oznaczenie dystrybucji musi kończyć się średnikiem (;) oraz metadane. Metadane są listą informacji przekazywanych w formacie klucz=wartość. W tym przypadku mamy informacje związne ze stopniem wymuszania zmian w repozytorium, co jest związane z wagą zmian dokonanych w pakiecie. Jeśli zmiany nie są ważne, pakiet może zostać zaktualizowany w następnej kolejności. Pod nagłówkiem znajduje się sama informacja o dokonanych zmianach. Może ona zawierać nagłówek, choć nie jest on obowiązkowy. Kazdy temat w informacji powinien zaczynać się od gwiazdki (*) odzielonej od treści spacją. Dalszy opis pownien ropoczynać się od tej samej pozycji co temat. Informacja oddzielona jest od krawędzi okna jednym znakiem tabulacji. Wpis do opisu zmian kończy stopką, która oddzielona jest od krawędzi okna jedną spacją rozpoczyna się on podwójnego myślnika (--) następnie występuje nazwa opiekuna pakietu oraz jego adres e-mail. Po tych informacjach znajduje się data (hipotetycza) zmian. Data jest oddzielona od adresu e-mail opiekuna dwoma znakami spacji.
Ten plik ma dość specyficzną formę i chwilę nam zajmie opanowanie tego. Zamiast czekać na zrzut błędów lintiana, nasz opis zmian możemy sprawdzić za pomocą polecenia dpkg-parsechangelog. Plus jest w tym taki, że jeśli opanujemy jeden plik to będziemy mogli go edytować na potrzeby innych pakietów a nie tworzyć od zera. Dodatkowo istnieje polecenie, które jest nam w stanie wygenererować taki opis zmian. Po więcej informacji zapraszam do materiałów źródłowych (link nr. 2). Na koniec plik należy skompresować i nadać mu odpowiednie uprawnienia.
xf0r3m@debian:~/helloworld/usr/share/doc/helloworld$ gzip --best -n changelog xf0r3m@debian:~/helloworld/usr/share/doc/helloworld$ chmod 644 changelog.gz
Drugim plikiem jest informacja o prawach autorskich, na podstawie których rozpowszechaniane są pliki w pakiecie. Tutaj możemy użyć poniższego gotowca. Wystarczy tylko zmienić nazwę pakietu, datę i informacje o opiekunie, o ile zgadzamy się z licencją GPL.
helloworld Copyright: 2025 xf0r3m <xf0r3m@gmail.com> 2025-12-31 The entire code base may be distributed under the terms of the GNU General Public License (GPL), which appears immediately below. Alternatively, all of the source code as any code derived from that code may instead be distributed under the GNU Lesser General Public License (LGPL), at the choice of the distributor. The complete text of the LGPL appears at the bottom of this file. See /usr/share/common-licenses/(GPL|LGPL)
Po utworzniu plików dokumentacji, możemy utworzyć plik z podręcznikiem użytkownika. Generalnie to każdy plik wykonywalny w Debianie powinien mieć taki utworzony i tutaj szkoły są dwie. Na początek możemy utworzyć stronę podręcznika ręcznie. Powinna ona wyglądać jak poniżej (w notatniku)
.\" Hey, EMACS: -*- nroff -*- .\" Copyleft 2025 xf0r3m <xf0r3m@gmail.com> .\" .TH HELLOWORLD 1 .SH NAME helloworld \- Dummy script for printing 'Hello, World!' .SH SYNOPSIS .B helloworld .SH DESCRIPTION The .B helloworld prints 'Hello, World!' string on stdout. .SH SEE ALSO .BR echo (1). .SH AUTORS The .B helloworld script was written by xf0r3m <xf0r3m@gmail.com> .PP This document was written by xf0r3m <xf0r3m@gmail.com> for Debian.
Jest to jak najbardziej poprawna strona podręcznika użytkownika zgodna z wymogami Debiana. Poniżej znajdują są opisy poszczególnych instrukcji. Pierwsze trzy linie zawierają komentarz. W pierwszej linii znajduje się instrukcja dla edytora Emacs, następnie znajduje się informacja o autorze. Następnie występują już instrukcje odpowiedzialne za stronę podręcznika mamy zatem:
.TH- odpowiedzialne za nagłówki tytułowe, wyświetla podany tekst w trzech rogach strony, na kolejny argument wyświetlany jest w nawiasie..SH- odpowiedzialne za nagłówki sekcji, wyświetla pogrubiony tekst. Dzieli dzieli strone na typowe dlatego formatu sekcje. Wszystko co znajduje się między.SHtraktowane jest jak tekst tej sekcji..B- wyświetla pogrubiony tekst, podany jako argumenty..BR- wyświetla pogrubiony tekst, alfanumeryczny do piewszego odstępu i usuwa odstęp. Jeśli za odstępem znów znajdują się znaki alfanumeryczne to również zostaną pogrubione..PP- wprowadza wszystko poniżej od nowego akapitu. Zmiana tematu, ale nie zmiana sekcji.
Drugim podejściem do tworzenia stron podręcznika jest automatyzacja za
pomocą narzędzia help2man. To narzędzie jest w stanie utworzyć stronę
podręcznik bazując na infrormacjach wyświetlonych przez program
uruchomiony z opcja --help. Program ten wymaga, aby
były dostępne funkcję --help oraz --version.
Wyświelające dane sformatowane w taki sam sposób jak na podręczniku
dotyczącym tego narzędzia - link w źródłach. Ten sposób nie jest
pozbawiony wad, otóż w nazwie jako krótki opis tekst:
program - manual page for program,
oczywiście zamiast nazwy program
wstawiana jest nazwa naszego
skryptu oraz na końcu jego wersja. Ten zapis generuje ostrzeżenie
lintiana o useless-whatis-entry. Aby polecenie
help2man użyło naszego krótkiego opisu musimy użyć opcji
-n.
Po utworzeniu strony podręcznika, mamy gotowe wszystkie pliki powiązane z programem, które będą znajdować się w pakiecie. Teraz musimy utworzyć plik dodatkowy dla narzędzia APT oraz repozytorium aby mogło odpowiednio zarządzać pakietem. Ten plik to DEBIAN/control. Dla mojego testowego pakietu ten plik prezentuje się w następujący sposób.
Package: helloworld Version: 0.0.1 Section: utils Priority: optional Architecture: all Maintainer: xf0r3m <xf0r3m@gmail.com> Description: This is test script for .deb package building Depends: bash (>=5.0)
Spośród przedstawionych tutaj pól, nas powinny interesować kolejno:
Package- nazwa pakietu.Version- wersja pakietu.Architecture- architektura, dla której przygotowano pakiet.Maintainer:- dane opiekuna pakietu, nazwa oraz adres e-mail.Description:- opis programu zawartego w pakiecie.Depends:- zależności pakietu. Inne pakiety, których wymaga nasz program do działania.
Jeśli będziemy tworzyć pakiety bibliotekami lub modułami możemy również
zmienić wartość pola Section. Dziwna
wartość pola Description jest tutaj
nie bez powodu, otóż wymagane jest aby opis pakietu zawiera co najmniej
dwie linie, więc jeśli nie bedziemy w stanie sklecić dwóch zdań opisu
to możemy złamać jedno zdanie, tak jak pokazano na powyższym przykładzie.
W przypadku dodawania zależności, musimy również podać zgodną z naszym
programem, mimimalną wersje dodatkowych pakietów wymaganych przez
program dla którego tworzymy pakiet.
Jeśli program, dla którego przygotowujemy pakiet wymaga do działania plików konfiguracyjnych umieszczanych w katalogu /etc, to musimy umieścić informacje o tych plikiach w postaci ścieżek bezwzględnych (/etc/plik...) w pliku DEBIAN/conffile po jednej linii na każdy plik.
Teraz jeśli wszystkie pliki są gotowe. Możemy przjeść do budowania
pakietu. Wydajemy poniże polecenie i jego wynikiem będzie pojawienie
się pakietu pliku o nazwie, którą podaliśmy w polu
Package w pliku DEBIAN/control
z rozszerzeniem .deb.
xf0r3m@debian:~$ dpkg-deb --root-owner-group --build helloworld/
Polecenie to nie zwróci żadnych dodatkowych informacji poza lakonicznym
komunikatem o budowanym pakiecie o podanej nazwie w wyżej wymienionym
polu. Do sprawdzenia pakietów pod kątem poprawności z ogólnie przyjętymi
zasadami służy polecenie lintian. Polecenie to zwraca
błędy (E:) w przypadku rażących
zaniedbań lub ostrzeżenia (W:) w razie
mniejszych przewinień.
xf0r3m@debian:~$ lintian helloworld.deb
Jeśli polecenie zwróci jakieś zastrzeżenia, to musimy je poprawić.
Po zastosowaniu poprawek niezbędne będzie ponowne zbudowanie pakietu. Gdy
w pakiecie wszystko będzie w porządku, polecenie nie zwróci nic.
Poprostu zakończy swoje działanie zwracając kod 0. Nie których z
komunikatów zwracanych przez lintian
możemy nie zrozumieć od razu. Dlatego też istnieje cała strona
(link źródłowy nr. 3) poświęcona
głębszemu wyjaśnieniu komunikatów zwracanych przez to polecenie. Nawet
więcej, lintian sam podaje odpowiednie
strony wyjaśniające dany komunikat - pod kolorową nazwą komunikatu
kryje się hiperłącze, które można otworzyć o ile pozwala nam na to nasz
emulator terminala.
Jeśli lintian nie zwrócił żadnego komunikatu oznacza to, że nasz pakiet został poprawnie złożony. Teraz możemy przejść do testowej instalacji. Taki pakiet możemy zainstalować na dwa sposoby, który sposób będzie odpowiedni dla nas zależy od tego czy pakiet posiada zależności. Jeśli tak to nalepszym sposobem na instalację będzie użycie polecenia APT, jeśli nie posiada ich to równie dobrze możemy skorzystać z polecenia dpkg z opcją -i jak i APT.
xf0r3m@debian:~$ sudo dpkg -i ./helloworld.deb
xf0r3m@debian:~$ sudo apt install ./helloworld.deb
Ostrzeżenie APT pod koniec instalacji możemy zignorować, dotyczy ono braku możliwości zapisania naszego lokalnego pakietu do odpowiedniego katalogu. Tak zainstalowny skrypt jest gotowy do uruchomienia prosto z wiersza polecenia.
Podsumowując, tworzenie własnych pakietów jest nieco bardziej wysublimowanym sposoben na dostarczanie własnych narzędzi w dystrybucjach Linuksa. Oczywiście, wymaga to więcej pracy, jednak w nie musimy tworzyć żadnych skryptów instalacyjnych czy tłumaczyć niuansów instalacji. Taki sposób dostarczania oprogramowania z poziomu użytkownika końcowego jest najlepszy, ponieważ na dostawcy spoczywa odpowiedzialność za przygotowanie środowiska dla jego programu.
Źródła:
- How to Create a Simple Debian Package
- Poradnik maintainer'a, czyli jak zrobić pakiet deb
- Lintian tags explanation
- help2man Reference Manual
~xf0r3m