Φτιάξτε πακέτα RPM!

dimitris | Πέμ, 02/28/2008 - 21:12 | 34'

Τα “πακέτα λογισμικού” στον κόσμο του Linux έχουν ξεχωριστή σημασία. Είναι ο κανονικός τρόπος εγκατάστασης λογισμικού. Σε αυτό το tutorial, θα μάθουμε πως να φτιάχνουμε πακέτα RPM.

Εισαγωγή

Όπως θα ξέρετε, υπάρχουν δύο τρόποι εγκατάστασης εφαρμογών στο Linux:

1) Με μεταγλώττιση (compile) από τον κώδικα τους και
2) Με απευθείας εγκατάσταση “πακέτων” (binary packages).

O πρώτος τρόπος συνίσταται μόνο για έμπειρους χρήστες που θέλουν πλήρη έλεγχο στο σύστημα. Ο δεύτερος τρόπος είναι ο ενδεδειγμένος για τους περισσότερους χρήστες, μια και οι πιο πολλές διανομές έχουν ένα διαχειριστή πακέτων, δηλαδή ένα σύστημα που επιτρέπει την απευθείας εγκατάσταση πακέτων εφαρμογών μέσω του Διαδικτύου. Ουσιαστικά, ένα πακέτο είναι η εφαρμογή που έχει μεταγλωττιστεί για μια συγκεκριμένη διανομή (από τους developers ή κάποιον άλλο χρήστη) με συγκεκριμένο τρόπο και είναι έτοιμο για εγκατάσταση σε κάθε σύστημα με την ίδια διανομή Linux.

Η διαδικασία δημιουργίας ενός πακέτου λέγεται “packaging” (πακετάρισμα) ή building (“χτίσιμο”). Επιπλέον, οι περισσότερες διανομές διαθέτουν servers στο Διαδίκτυο που φιλοξενούν χιλιάδες πακέτα έτοιμα για εγκατάσταση μέσω του διαχειριστή πακέτων της εκάστοτε διανομής.

Τώρα, υπάρχουν δύα βασικά είδη πακέτων στις διανομές Linux: τα RPM και τα DEB. Τα πρώτα προέρχονται από το παλιό Red Hat Linux - το RPM σημαίνει άλλωστε RedHat Package Manager. Τα DEB προέρχονται από το Debian. Τα RPM χρησιμοποιούνται από τις λεγόμενες “RPM διανομές” όπως το Fedora, το Mandriva και το PCLinuxOS ενώ τα DEB από τις “Debian διανομές” όπως το Debian, το Ubuntu, το Kubuntu, το Mepis κλπ.

Γι' αυτό σε αυτό το tutorial, θα χρησιμοποιήσουμε το Fedora, που προερχεται από το Red Hat, και παράλληλα θα ακολουθούμε (σχεδόν) όλες τις οδηγίες 'πακεταρίσματος' της διανομής αυτής. Ό,τι πούμε όμως θα πρέπει λογικά να ισχύει και για κάθε άλλη RPM διανομή αλλά και οποιοδήποτε RPM προσπαθήσετε να φτιάξετε. Ουσιαστικά Η διαδικασία

Τι θα πακετάρουμε

Το λογισμικό που επιλέξαμε να 'πακετάρουμε' είναι μια εφαρμογή mind-mapping σε Python, που λέγεται Labyrinth (www.gnome.org/~dscorgie/labyrinth.html). Εσείς επιλέξτε όποιο θέλετε.

Η δημιουργία πακέτων RPM δεν είναι εύκολη, αλλά υπάρχουν εργαλεία για να σας βοηθήσουν. Αυτά είναι τα σκριπτάκια RPMDevTools που προσφέρει το Fedora. Εάν έχετε Fedora, αρκεί να δώσετε από την κονσόλα ως root:

yum install rpmdevtools

Εάν πάλι δεν έχετε Fedora, μπορείτε να τα βρείτε και να τα εγκαταστήσετε από το rpm.org.

Με τα εργαλεία αυτά εγκατεστημένα, ως κανονικοί χρήστες, δώστε την εντολή:

rpmdev-setuptree

Η εντολή αυτή δημιουργεί ένα φάκελο rpmbuild, με την τυπική δομή φακέλων για RPM (SPECS, RPMS, SRPMS, SOURCES, BUILD). Το επόμενο πράγμα που πρέπει να κάνετε είναι να κατεβάσετε το tarball με τον πηγαίο κώδικα της εφαρμογής που θέλετε να πακετάρετε και να το αντιγράψετε στο υποφάκελο SOURCES. Μην αποσυμπιέσετε το tarball...αφήστε το ως έχει.

Το αρχείο spec

Το σημείο εκκίνησης για τη δημιουργία ενός RPM είναι το αρχείο spec. Αυτό το μικρό αρχείο κειμένου περιέχει τις οδηγίες που λένε στον RPM installer πως να κάνει τη δουλειά του: δηλαδή τι είναι η εφαρμογή, τι απαιτεί και που πρέπει να βάλει τα μέρη της. Το αρχείο spec είναι, ουσιαστικά, όλη η δουλειά που πρέπει να κάνετε για να φτιάξετε το RPM. Όλα τα υπόλοιπα γίνονται αυτόματα.

Πολλοί χρήστες ξεκινούν από κάποιο έτοιμο αρχείο spec από μια παρόμοια εφαρμογή με αυτήν που θέλουν να πακετάρουν. Πράγματι, είναι πολύ καλή ιδέα να κατεβάσετε μερικά SRPMs και να δείτε τα spec που περιέχουν, επειδή αν έχετε ποτέ κάποιο πρόβλημα, το πιθανότερο είναι ότι κάποιος άλλος έχει βρει τη λύση. Τα SPRMs είναι RPMs με όλον τον πηγαίο κώδικα και εντολές μεταγλώττισης, και εκεί θα βρείτε σίγουρα μια λύση.

Συνήθως, όμως, είναι καλύτερα, και αυτό θα κάνουμε, να ξεκινήσετε από ένα πρότυπο αρχείο spec, δηλαδή ένα template. Τα templates δημιουργούνται από τα εργαλεία RPMDev που μόλις εγκαταστήσατε. Έτσι, από το φάκελο rpmroot, δώστε
rpmdev-newspec -o SPECS/labyrinth.spec

Αυτή η εντολή δημιουργεί ένα μίνιμουμ template και το βάζει στο φάκελο SPECS, πράγμα χρήσιμο αφού εκεί υποτίθεται ότι πρέπει να μπαίνουν τα διάφορα templates. Ας το δούμε τώρα (ανοίξτε το με κάποιον κειμενογράφο):

Name:
Version:
Release: 1%{?dist}
Summary:
Group:
License:
URL:
Source0:
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-
%(%{__id_u} -n)
BuildRequires:
Requires:
%description
%prep
%setup -q
%build
%configure
make %{?_smp_mflags}
%install
rm -rf $RPM_BUILD_ROOT
make install DESTDIR=$RPM_BUILD_ROOT
%clean
rm -rf $RPM_BUILD_ROOT
%files
%defattr(-,root,root,-)
%doc
%changelog

Όπως βλέπετε, ένα σημαντικό μέρος της δουλειάς έχει γίνει ήδη, τουλάχιστον για απλά πακέτα. Υπάρχουν όμως αρκετά πράγματα που πρέπει να προστεθούν, γι' αυτό ας ξεκινήσουμε από την αρχή.

Στο “Name” προφανώς μπαίνει το labyrinth (με μικρά), και η έκδοση (Version) είναι η ίδια με του προγράμματος, εδώ 0.2. Στο “Release” γράφετε την έκδοση του RPM, όχι της εφαρμογής. Εδώ, μια και είναι η πρώτη έκδοση του, βάζουμε 1. Ωστόσο, κατά τις δοκιμές, και ιδιαίτερα αν προσπαθήσετε να γίνει δεκτό το πακέτο σας σε αποθετήρια RPM, είναι καλύτερο να ξεκινήσετε από το 0 και κάποια λέξη που να δείχνει ότι είναι δοκιμαστική έκδοση (συν, προαιρετικά, έναν δεύτερο αριθμό έκδοσης). Το “Summary” είναι ένα μικρό κομμάτι κειμένου, που συνήθως εμφανίζεται στους γραφικούς διαχειριστές λογισμικού, με λίγες πληροφορίες για το πακέτο. Μην ξεπεράσετε τις οκτώ λέξεις...

Τώρα το αρχείο πρέπει να ξεκινά κάπως έτσι:
Name:labyrinth
Version:0.2
Release:0.test.1
Summary:Python-based mind-mapping application

Περνάμε τώρα στο πιο σημαντικό τμήμα, γι' αυτό δώστε βάση! Το πεδίο Group δεν απαιτείται από όλες τις διανομές, αλλά χρησιμοποιείται ιδιαίτερα στις Fedora/Red Hat και συναφείς, γι' αυτό βάλτε το. Θα βρείτε μια λίστα με αποδεκτά groups για το Fedora στο http://fedoraproject.org/wiki/RPMGroups.

Το πεδίο License επίσης απαιτείται. Εκεί βάζετε την άδεια χρήσης. Στις περισσότερες περιπτώσεις θα είναι η GPL, αλλά μπορεί να είναι η BSD, η MIT, η X11 ή κάποια άλλη. Είναι απολύτως απαραίτητο να εξακριβώσετε την άδεια χρήσης από την τεκμηρίωση της εφαρμογής.

Το “URL” πρέπει να είναι η ιστοσελίδα του προγράμματος, και στο πεδίο Source0: γράφετε ένα URL του tarball με τον πηγαίο κώδικα. Ο λόγος που έχει το 0 στο όνομά του είναι ότι κάποιες φορές μπορεί να απαιτούνται περισσότερα του ενός αρχεία με κώδικα για να φτιαχτεί ένα πακέτο. Τέλος, και για την ώρα, αφήστε το BuildRoot ως έχει. Έτσι, αυτό το κομμάτι του αρχείου πρέπει να μοιάζει με το εξής:

Group:Applications/Productivity
License:GPL
URL:http://www.gnome.org/~dscorgie/labyrinth.html
Source0:http://www.gnome.org/~dscorgie/labyrinth-0.2.tar.gz
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-
%(%{__id_u} -n)

Στη συνέχεια, το BuildRequires: είναι το πιο δύσκολο, γι' αυτό ας τ' αφήσουμε για την ώρα, για να ξεμπερδέψουμε με τα εύκολα πρώτα. Στο επόμενο πεδίο, πρέπει απλά να βάλετε μια λεπτομερή περιγραφή, που συνήθως θα βρείτε στην τεκμηρίωση της εφαρμογής. Μην γράψετε πολλά! Αρκεί μια απλή και ξεκάθαρη περιγραφή του τι κάνει το πρόγραμμα. Τα επόμενα πεδία καθορίζουν τη διαδικασία ρύθμισης και δημιουργίας του πακέτου. Για πολλές εφαρμογές, αρκεί να τα αφήσετε όπως είναι και δεν χρειάζεται να τα πειράξετε...

Πάμε τώρα στο τέλος, στο “changelog”. Πρέπει να βάλουμε κάτι εκεί, και μάλιστα με την εξής μορφή:

date +”%a %b %e %Y”

Αυτή καθορίζει τη μορφή της ημερομηνίας. Γράψτε την ημερομηνία και μετά το όνομά σας, το email και την έκδοση του πακέτου και στο τέλος μια γραμμή περιγραφής της έκδοσης αυτής. Τώρα θα πρέπει να έχετε κάτι που να είναι σαν κι αυτό:

%changelog
* Tue Nov 7 2006 John Ploppypants 
0.2-1.test.1
- Initial RPM build

Ψάχνοντας για εξαρτήσεις

ΟΚ, τελειώσαμε με τα εύκολα! Το αρχείο spec που φτιάξαμε δεν θα δουλέψει, αλλά είναι καλή αρχή. Πρέπει τώρα να το “κάνουμε build” για να δούμε τι σφάλματα θα μας εμφανίσει. Έτσι από το φάκελο rpmroot δώστε την εντολή:

rpmbuild -bc SPEC/labyrinth.spec

Αυτή λέει στο εργαλείο rpmbuild να εκτελέσει τα στάδια προετοιμασίας και μεταγλώττισης. Στην ιδανική περίπτωση, o compiler θα τυπώσει σφάλματα και θα μας πει όλα όσα πρέπει να ξέρουμε για τις απαιτήσεις της μεταγλώττισης που θα βάλουμε στο τμήμα BuildRequires: που αφήσαμε απαράλλαχτο στο αρχείο spec.

Το τι ακριβώς θα δείτε εσείς εξαρτάται από το σύστημά σας, αλλά σε μια κανονική εγκατάσταση, θα εμφανιστούν πιθανότατα αρκετές αράδες κειμένου όπου το σκριπτάκι configure βρίσκει προβλήματα, μετά λίγο κείμενο, και στο τέλος ένα μήνυμα σφάλματος σαν κι αυτό:

checking pkg-config is at least version 0.9.0... yes
checking for LABYRINTH... configure: error: Package
requirements (gtk+-2.0 >= 2.8
pygtk-2.0 >= 2.8
pygobject-2.0 >= 2.10
gnome-python-2.0 >= 2.12
gnome-desktop-2.0 >= 2.14
pycairo >= 1.0
) were not met:
No package ‘pygtk-2.0’ found
No package ‘pycairo’ found
Consider adjusting the PKG_CONFIG_PATH environment
variable if you
installed software in a non-standard prefix.
Alternatively, you may set the environment variables
LABYRINTH_CFLAGS
and LABYRINTH_LIBS to avoid the need to call pkg-config.
See the pkg-config man page for more details.
error: Bad exit status from /var/tmp/rpm-tmp.23019 (%build)

RPM build errors:
Bad exit status from /var/tmp/rpm-tmp.23019 (%build)

Ορίστε. Έχουμε τώρα μια λίστα με τις εξαρτήσεις του Labyrinth, δηλαδή τα PyGTK 2 και Pycairo. Για τη μεταγλώττιση, χρειαζόμαστε πάντα τις εκδόσεις devel (ανάπτυξης) αυτών των πακέτων-εξαρτήσεων, τις οποίες πρέπει να προσθέσουμε στο αρχείο spec.

Προσέξτε κάτι: αυτά τα πακέτα είναι οι εξαρτήσεις του στο δικό σας σύστημα. Αυτό όμως δεν σημαίνει ότι θα αρκούν και για όλους τους άλλους. Για να είστε λοιπόν περισσότερο σίγουροι, πρέπει να ψάξετε λίγο ακόμα. Υπάρχουν μερικά πακέτα που χρειάζονται για τη μεταγλώττιση που δεν φαίνονται εδώ: Είναι προφανές ότι αν το πακέτο σας απαιτεί το Cairo για να εγκατασταθεί, τότε θα χρειάζεται και το cairo-dev για να μεταγλωττιστεί. Αλλά τότε θα χρειάζεται και τα εργαλεία μεταγλώττισης: τα Automake, Autoconf κλπ. Να προσέξετε ιδιαίτερα εφαρμογές που χρησιμοποιούν διαφορετικό μεταγλωττιστή ή εντολές make!

Πρέπει επίσης να λάβετε υπόψη τους χρήστες στους οποίους απευθύνεται η εφαρμογή. Για παράδειγμα, πολλές διανομές θεωρώντας ότι ο GCC είναι πάντα εγκατεστημένος, δεν τον εμφανίζουν στη λίστα των εξαρτήσεων. Γι' αυτό πρέπει να συμβουλευτείτε τις οδηγίες της διανομής για την οποία φτιάχνετε το πακέτο. Επίσης, ένα καλό μέρος να μάθετε για τις εξαρτήσεις μιας εφαρμογής είναι η ίδια η τεκμηρίωση της, όπου συνήθως αναφέρεται τι ακριβώς χρειάζεται. Επίσης, μπορείτε να τρέξετε το configure, το οποίο στα μηνύματα του συνήθως αναφέρει ποιες βιβλιοθήκες χρειάζεται η εφαρμογή.

Ένα ακόμα τρικ είναι να τρέξετε την εντολή ldd για το εκτελέσιμο (αν πρόκειται για εφαρμογή). Αυτή θα σας δώσει μια λίστα με όλες τις συνδεδεμένες με αυτό βιβλιοθήκες. Μάλιστα, τα σκριπτάκια RPMdev θα το κάνουν αυτό αυτόματα για να προσθέσουν εξαρτήσεις για να τρέξουν το εκτελέσιμο.

Όταν λοιπόν αποκτήσετε την πλήρη λίστα εξαρτήσεων, αρχίζει το...κλάδεμα. Για παράδειγμα, αν η εφαρμογή εξαρτάται από τις Α, Β και C βιβλιοθήκες, αλλά οι Α, Β εξαρτώνται επίσης από την C, τότε είναι ασφαλές να παραλείψετε την C. Ένα παράδειγμα είναι κάποια εφαρμογή που απαιτεί το Gnome: αδιαμφισβήτητα θα απαιτεί κι ένα σωρό ακόμα βιβλιοθήκες. Αλλά το να προσθέτετε αδικαιολόγητα πολλές εξαρτήσεις είναι κακό πράγμα. Πίσω στο Labyrinth τώρα: μια γρήγορη ματιά στην τεκμηρίωση της εφαρμογής και μια μικρή μελέτη των αρχείων ρύθμισης, μας οδήγησε στην ακόλουθη λίστα εξαρτήσεων:

Python == 2.4
gtk+ >= 2.8
pygtk-2.0 >= 2.8
pygobject-2.0 >= 2.10
gnome-python-2.0 >= 2.12
gnome-desktop-2.0 >= 2.14
pycairo >= 1.0
cairo
libbonobo >=2.0
pango
pangocairo
gdk_pixbuff >= 2.0
freetype >2.0

Τώρα, είναι καλό να γνωρίζετε καλά κάθε πακέτο, επειδή η λίστα αυτή μπορεί άνετα να μειωθεί αρκετά. Πολλά από αυτά είναι απλά 'κληρονομημένες' εξαρτήσεις, δηλαδή απαιτούνται επειδή κάποια άλλη εξάρτηση τις χρειάζεται. Εδώ μπορούμε άνετα να παραλείψουμε το FreeType επειδή απαιτείται επίσης από άλλα πακέτα της λίστας. Παρόμοια, η ίδια η Python είναι μέρος της αρχικής εγκατάστασης του Fedora, οπότε μπορούμε επίσης να την αγνοήσουμε.

Βρες το πακέτο

Τι θα κάνετε όταν δεν ξέρετε τα ακριβή ονόματα κάποιων πακέτων; Η εντολή rpm δίνει την απάντηση. Με μερικές παραμέτρους μπορείτε να 'ρωτήσετε' τα εγκατεστημένα πακέτα για το τι απαιτούν και τι προσφέρουν. Η πιο χρήσιμη παράμετρος απ' όλες είναι η whatprovides:

# rpm -q --whatprovides cairo
cairo-1.2.4-1.fc6

Η παράμετρος -q δηλώνει ότι θέτουμε ένα 'ερώτημα' ενώ με την --whatprovides δίνουμε το όνομα του πακέτου. Το αποτέλεσμα είναι το πραγματικό πακέτο που είναι εγκατεστημένο στο σύστημά σας. Φυσικά, για να δουλέψει αυτό το τρικ, είναι αναγκαία προϋπόθεση να έχετε εγκαταστήσει όλο το λογισμικό που απαιτεί η εφαρμογή για να τρέξει.

Το μόνο πράγμα που δεν λέει η παραπάνω εντολή είναι αν η εγκατεστημένη έκδοση είναι εκείνη που απαιτεί το Labyrinth. Αρκεί το Cairo 1.0; Αυτό είναι κάτι που δεν μπορείτε να το προσδιορίσετε εύκολα, χωρίς να κοιτάξετε τον ...κώδικα, και ακόμα και τότε είναι δύσκολο. Μπορείτε φυσικά να κάνετε δοκιμές, αλλά θα χάσετε πολύ χρόνο. Συνήθως, όμως, είναι ασφαλές να χρησιμοποιήσετε την έκδοση του πακέτου που περιέχεται στη διανομή για την οποία προορίζετε το πακέτο σας.

Στο παράδειγμά μας, η εξάρτηση για την Cairo προέρχεται από την Pycairo. Οπότε, υποβάλλουμε ένα ακόμα ερώτημα rpm για να σιγουρευτούμε:

rpm -q --requires pycairo
cairo >= 1.1.10
libc.so.6
libc.so.6(GLIBC_2.0)
libc.so.6(GLIBC_2.1.3)
libc.so.6(GLIBC_2.4)
libcairo.so.2
...

Η παράμετρος requires, ακολουθούμενη από το όνομα του πακέτου, τυπώνει όλες τις εξαρτήσεις του. Η πρώτη γραμμή είναι εκείνη που μας ενδιαφέρει. Το Pycairo χρειάζεται την Cairo 1.1.10 και πάνω, όχι την έκδοση που έχουμε εμείς εγκαταστήσει. Επειδή όμως το Labyrinth είναι μια εφαρμογή Python που χρησιμοποιεί την Cairo μέσω του Pycairo, μπορούμε άνετα να το αφήσουμε ως έχει.

Με παρόμοιο τρόπο, τσεκάροντας την λίστα των εξαρτήσεων μπορέσαμε να εξαλείψουμε ή να βρούμε όλα τα πακέτα που απαιτούνται από το Labyrinth. Ένα μόνο μας ξέφυγε: το pygobject-2.0. Δυστυχώς, στην περίπτωση του, η εντολή rpm --whatprovides δεν έδωσε κάποια απάντηση. Ούτε η --requires μας έδωσε κάτι. Υπάρχουν όμως δύο ακόμα τρικ να χρησιμοποιήσουμε. Πρώτον, μπορούμε να ψάξουμε απλώς σε όλη τη βάση δεδομένων του RPM για οποιαδήποτε αναφορά στο PyGObject:

#rpm -qa | grep pygobject
pygobject2-2.12.2-1.fc6
pygobject2-devel-2.12.2-1.fc6

Τσακ! Τώρα εξηγούνται όλα. Το PyGObject δεν εμφανιζόταν πριν επειδή έχει ένα 2 στο όνομά του (που εμείς δεν βάζαμε). ΟΚ. Αξίζει επίσης να αναφέρουμε και την άλλη, ελαφρά πιο δύσκολη, μέθοδο αναζήτησης, επειδή δεν θα συμβαίνει πάντα η εξάρτηση να είναι μέρος του ονόματος ενός πακέτου. Σε αυτήν την περίπτωση, θα έπρεπε να ψάξουμε για εγκατεστημένα αρχεία που σχετίζονται με το πακέτο που μας ενδιαφέρει:

locate pygobject
/usr/include/pygtk-2.0/pygobject.h
/usr/lib/pkgconfig/pygobject-2.0.pc
/usr/share/pygobject
...[και πολλά ακόμα]

Εδώ φαίνεται σίγουρα ότι ο υποφάκελος στο usr/share ανήκει στο πακέτο που ψάχνουμε. Τώρα μπορούμε πολύ εύκολα να κάνουμε ένα διαφορετικό ερώτημα με την rpm που παρακολουθεί και τα εγκατεστημένα αρχεία:

rpm -qf /usr/share/pygobject
pygobject2-devel-2.12.2-1.fc6

Και πάλι βρήκαμε το ίδιο πακέτο!

Εδώ τελειώνει το δυσκολότερο κομμάτι της δημιουργίας ενός RPM. Οπότε βάζουμε όλες αυτές τις εξαρτήσεις της μεταγλώττισης στο πεδίο BuildRequires του αρχείου spec και “σχολιάζουμε” το πεδίο Requires, αφού για την ώρα δεν το χρειαζόμαστε. Τώρα οι γραμμές αυτές του spec πρέπει να είναι κάπως έτσι:

BuildRequires: python-devel desktop-file-utils pycairo-devel cairodevel
automake autoconf
BuildRequires: pygtk2-devel >= 2.8
BuildRequires: pygobject2-devel >= 2.10
#Requires:

Εάν απορείτε για το desktop-files-utils, πρόκειται για εργαλεία που χρησιμοποιούνται για την εγκατάσταση των εικονιδίων στο desktop, των μενού κτλ στις εφαρμογές desktop. Τώρα δοκιμάστε ξανά την rpmbuild και θα δείτε ότι τελειώνει με ένα + exit 0. Όλα εντάξει.

Συλλογή αρχείων

Δεν τελειώσαμε όμως. Για να δουλέψει σωστά, το σύστημα rpm χρειάζεται να ξέρει για όλα τα αρχεία που θα περιέχονται στο νέο πακέτο. Αλλά εμείς δεν ξέρουμε καν ποια είναι αυτά! Ευτυχώς, τα εργαλεία RPMDev θα μας πουν ότι χρειάζεται. Δοκιμάστε ξανά τη μεταγλώττιση, φτάνοντας αυτή τη φορά μέχρι την εγκατάσταση, με την παράμετρο i:

rpmbuild -bi SPEC/labyrinth.spec

Θα δείτε ένα σωρό μηνύματα, που τελειώνουν με:

RPM build errors:
Installed (but unpackaged) file(s) found:
/usr/bin/labyrinth
/usr/lib/python2.4/site-packages/labyrinth/BaseThought.py
...[πολλά αρχεία]
/usr/share/icons/hicolor/24x24/apps/labyrinth.png
/usr/share/icons/hicolor/scalable/apps/labyrinth.svg
/usr/share/labyrinth/labyrinth-ui.xml
/usr/share/labyrinth/labyrinth.glade

Αυτή είναι η πλήρης λίστα με τα αρχεία που θα πρέπει να λάβετε υπόψη σας. Έτσι, μετά την ετικέτα %files, θα μπορούσατε να αραδιάσετε όλα αυτά τα αρχεία. Αλλά αυτό θα ήταν κουραστικό, και θα χάνετε την ευκαιρία να αξιοποιήσετε μερικές από τις θαυμάσιες μακροεντολές που δείχνουν τις ικανότητές σας με το rpm. Επίσης κάνει δυσκολότερη τη συντήρηση του spec αρχείου. Γι' αυτό θα πρέπει να 'αλλάξουμε' λίγο τη λίστα.

Τα ευκολότερα αρχεία να ξεκινήσετε είναι εκείνα που βρίσκονται σε κοινούς φακέλους. Να μερικές από τις μακροεντολές του rpm για μονοπάτια (paths):

%{_bindir}   Αντικαθίσταται με το μονοπάτι των εκτελέσιμων του χρήστη, συνήθως το 
/usr/bin.
%{_libdir}  Το μονοπάτι για τις βιβλιοθήκες του χρήστη, συνήθως /user/lib.
%{_datadir} Το μονοπάτι με τα διαμοιραζόμενα δεδομένα του χρήστη, συνήθως /usr/share.

Το όλο ζουμί εδώ είναι η λέξη 'συνήθως'. Δεν ξέρετε ακριβώς ποιο είναι το μονοπάτι για όλα αυτά, αντίθετα αφήνετε το σύστημα rpm να βρει το σωστό κάθε φορά. Επίσης, αν ορίσετε ένα φάκελο, τότε ορίζετε τα πάντα που περιέχει και έτσι είναι ασφαλές να χρησιμοποιήσετε αυτήν την μακροεντολή όταν η εφαρμογή είναι η μόνη που θα έχει πρόσβαση στα δεδομένα (π.χ. τα διαμοιραζόμενα). Επομένως, η λίστα μπορεί να γίνει ως εξής:

%{_bindir}/labyrinth
%{_libdir}/python2.4/site-packages/labyrinth/
%{_datadir}/labyrinth/
#%{_datadir}/icons/hicolor/16x16/apps/labyrinth.png
#%{_datadir}/icons/hicolor/22x22/apps/labyrinth.png
#%{_datadir}/icons/hicolor/24x24/apps/labyrinth.png
#%{_datadir}/icons/hicolor/scalable/apps/labyrinth.svg
#%{_datadir}/applications/labyrinth.desktop

Αλλά υπάρχει ένα πρόβλημα. Το site-packages της Python βρίσκεται σε ένα φάκελο που περιέχει αριθμό έκδοσης. Εάν βγει μια νέα έκδοση της Python τότε αυτό το μονοπάτι δεν θα ισχύει πια. Η ίδια η Python μπορεί να μας πει ποιας έκδοσης είναι, αλλά πως θα το πούμε αυτό στο σκριπτάκι; Η λύση είναι να φτιάξουμε μια νέα μακροεντολή:

%define pyver %(python -c ‘import sys ; print sys.version[:3]’)

Αυτή η δήλωση define μας επιτρέπει να φτιάξουμε το δικό μας macro που εκτελεί τα περιεχόμενα των παρενθέσεων και τα 'επιστρέφει' (στην προκείμενη περίπτωση, πρόκειται για μια εντολή της Python που επιστρέφει τον αριθμό έκδοσής της). Είναι επίσης καλό να έχουμε αυτή τη δήλωση στην αρχή του spec για να αποφύγουμε μπλεξίματα. Τώρα μπορούμε να την χρησιμοποιήσουμε για να αντικαταστήσουμε το μονοπάτι με τον αριθμό έκδοσης στο επίμαχο σημείο:

%{_libdir}/python%{pyver}/site-packages/labyrinth/

Τέλος, υπάρχουν μερικά ειδικά αρχεία που πρέπει να προσθέσουμε σε αυτό το τμήμα του spec: τα αρχεία τεκμηρίωσης της εφαρμογής. Αυτά έχουν την ετικέτα %doc και πρέπει εκεί να συμπεριλάβουμε όλα τα συνήθη αρχεία στην ρίζα ενός tarball (COPYING, AUTHORS, README κλπ). Ψάξτε επίσης και για άλλα αρχεία τεκμηρίωσης στους υποφακέλους του.

%doc AUTHORS COPYING INSTALL NEWS README
%doc doc/FileFormat doc/TheFuture

Τώρα δοκιμάστε ξανά την εντολή εγκατάστασης και σιγουρευτείτε ότι ολοκληρώνεται σωστά (διορθώνοντας τυπογραφικά λάθη).

Σε μερικά spec μπορεί να δείτε την ετικέτα %provides. Σε ένα RPM μιας απλής εφαρμογής, μπορείτε σχεδόν πάντα να την αγνοήσετε. Προφανώς το Labyrinth δεν παρέχει τίποτε, εκτός από τον εαυτό του, αλλά αυτό είναι η εξορισμού υπόθεση για το rpm, επομένως δεν χρειάζεται να γράψουμε άλλη μια φορά στην provides.

Αναφέραμε όμως και τα desktop-files-utils. Αυτά είναι σκριπτάκια που βάζουν εικονίδια και εγγραφές στα μενού του desktop για την εφαρμογή του πακέτου. Στο τέλος του τμήματος %install μπορείτε να κάνετε την εγκατάσταση στο desktop με τον παρακάτω κώδικα:

desktop-file-install --vendor=”” \
--dir=%{buildroot}%{_datadir}/applications/ \
%{buildroot}/%{_datadir}/applications/labyrinth.desktop

Το κλειδί εδώ είναι ότι η εντολή αυτή δείχνει στο αρχείο .desktop που παρέχει η ίδια η εφαρμογή, στο μέρος όπου έχει εγκατασταθεί. Είναι συνήθως ασφαλές να αφήνετε κενή την παράμετρο vendor εάν η εφαρμογή δεν φτιάχνεται από κάποια εμπορική εταιρεία, αλλά κάποιες διανομές έχουν ιδιαίτερους κανόνες γι' αυτό.

Το τελικό build

Το spec μας έχει ολοκληρωθεί. Τώρα, το τελικό στάδιο για τη δημιουργία του RPM είναι να κάνουμε το πλήρες build:

rpmbuild -ba SPEC/labyrinth.spec

Όταν τελειώσει, θα δείτε ότι δημιουργήθηκαν τρία αρχεία, το SRPM, το RPM με τα εκτελέσιμα και ένα αρχείο αποσφαλμάτωσης. Είναι καιρός να δοκιμάσετε τι ...ψάρια πιάσατε, εγκαθιστώντας το πακέτο .RPM στο σύστημά σας. Ως root δώστε (αλλάζοντας φυσικά την αρχιτεκτονική και τους αριθμούς έκδοσης):

rpm -Uvh RPMS/i386/labyrinth-0.2-0.test.1.i386.rpm

Συγχαρητήρια. Μόλις φτιάξατε το πρώτο σας RPM! Ένας καλός τρόπος για να προχωρήσετε πλέον είναι να το υποβάλετε στην ομάδα ανάπτυξης της διανομής (εκτός εάν το έχει ήδη). Τότε θα αρχίσετε να συνεισφέρετε αληθινά στον ανοικτό κώδικα και θα κερδίσετε χρήσιμες εμπειρίες!

ΑΛΛΕΣ ΑΡΧΙΤΕΚΤΟΝΙΚΕΣ
Κάποιες διανομές έχουν διαφορετικούς τρόπους να κάνουν τα ίδια πράγματα. Κάποιες αρχιτεκτονικές έχουν επίσης τους δικούς τους τρόπους. Αλλά μπορείτε να γράφετε ένα spec αρχείο που να τις καλύπτει όλες: στις στάνταρ μακροεντολές του RPΜ περιλαμβάνονται οι συνθήκες %ifarch και %ifos, που μπορείτε να αξιοποιήσετε για πολύπλοκα scripts.

ΠΑΡΑΠΟΜΠΕΣ

Ακόμα κι αν δεν είστε hackers, θα είδατε ό,τι η δημιουργία ενός πακέτου για το Labyrinth ήταν σχετικά απλή διαδικασία, αφού δεν χρειάστηκε να κάνουμε πολλά κόλπα. Αλλά ένα RPM πακέτο δίνει πολλές δυνατότητες, όπως το να φτιάχνετε πακέτα για πολλές αρχιτεκτονικές ή λειτουργικά συστήματα, να στήνετε daemons, και άλλα συναφή. Μάλιστα, πολλές βιβλιοθήκες και εφαρμογές το απαιτούν. Η τεκμηρίωση του συστήματος RPM είναι δυστυχώς λίγο απαρχαιωμένη, αλλά να μερικές χρήσιμες παραπομπές.

Ένας πλήρης οδηγός, αλλά έξι χρονών παλιός:
www.rpm.org/max-rpm

Οι οδηγίες για πακετάρισμα του Fedora περιλαμβάνουν χρήσιμες συνθήκες του συστήματος RPM.
http://fedoraproject.org/wiki/Packaging/Guidelines

O οδηγός πακεταρίσματος για το SUSE/openSUSE.
http://en.opensuse.org/SUSE_Build_Tutorial

Δώσε αστέρια!