_____ _   _ _    _    ___      _
 / ____| \ | | |  | |  / / |    (_)
| |  __|  \| | |  | | / /| |     _ _ __  _   ___  __
| | |_ | . ` | |  | |/ / | |    | | '_ \| | | \ \/ /
| |__| | |\  | |__| / /  | |____| | | | | |_| |>  <
 \_____|_| \_|\____/_/   |______|_|_| |_|\__,_/_/\_\

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:

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:

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:

  1. How to Create a Simple Debian Package
  2. Poradnik maintainer'a, czyli jak zrobić pakiet deb
  3. Lintian tags explanation
  4. help2man Reference Manual

~xf0r3m