Source, compile και άλλα κινέζικα...

Από Κοινότητα Ελεύθερου Λογισμικού ΕΜΠ
Μετάβαση σε: πλοήγηση, αναζήτηση

Εισαγωγή

Η πρώτη ενασχόληση με το GNU/Linux ή προγράμματα ανοιχτού κώδικα, είναι πολύ πιθανό να μας φέρει αντιμέτωπους με όρους όπως "source", "compile", "configure", "tar" και διάφορους άλλους. Τι σημαίνουν όλα αυτά και γιατί είναι τόσο σημαντικά; Οι απαντήσεις βρίσκονται στις παρακάτω γραμμές...

Μια ματιά προς τα πίσω...

Πριν δούμε τι σημαίνουν οι παραπάνω όροι, ας κοιτάξουμε λίγο την ιστορία των συστημάτων Unix. Όταν το Unix άρχισε να δημιουργείται, στις αρχές του '70, η βασική γλώσσα προγραμματισμού ήταν η C. Έτσι, όλα τα συστήματα Unix γεννήθηκαν μέσα από την C και η ύπαρξή τους ήταν συνυφασμένη με αυτό. Μάλιστα, σε εκείνες τις πρώιμες εποχές της πληροφορικής δεν υπήρχαν πολλά έτοιμα προγράμματα και, συνεπώς, ο κάθε χρήστης έφτιαχνε τα δικά του προγράμματα μόνος του. Γι αυτό και τα συστήματα Unix διέθεταν σχεδόν πάντα πλήρες περιβάλλον ανάπτυξης προγραμμάτων, με εργαλεία, βιβλιοθήκες C και compilers (μεταγλωτιστές).

...και μία μπροστά

Μην βιαστείτε να πείτε ότι η κατάσταση αυτή έχει αλλάξει σήμερα. Σίγουρα, υπάρχει μία πληθώρα διαθέσιμων έτοιμων προγραμμάτων, ωστόσο είναι πολλοί αυτοί που, ο καθένας για τους δικούς του λόγους, γράφουν μόνοι τους τα δικά τους προγράμματα. Το GNU/Linux είναι ένα από τα καλύτερα παραδείγματα για του λόγου το αληθές! Όπως και το σύνολο των ελεύθερων προγραμμάτων και προγραμμάτων ανοιχτού κώδικα. Και παρότι υπάρχουν πλέον πολλές γλώσσες προγραμματισμού, το GNU/Linux εξακολουθεί ως γνήσιος απόγονος των συστημάτων Unix, να είναι συνυφασμένο με την C. Γι αυτό και δεν είναι λίγες εκείνες οι διανομές που έχουν ενσωματωμένες βιβλιοθήκες και εργαλεία ανάπτυξης προγραμμάτων για την γλώσσα C. Τα περισσότερα προγράμματα στο GNU/Linux εξακολουθούν να γράφονται σε αυτή την γλώσσα.

Η δύναμη είναι στη γνώση

Η κινητήριος δύναμη του GNU/Linux τα τελευταία χρόνια, πέρα από τον κόσμο που το αγκάλιασε, ήταν η άδεια χρήσης GPL (General Public Licence) του ιδρύματος GNU (προφέρεται γκνου). Αυτή όχι μόνο επέτρεπε σε όποιον ήθελε να δει και να παρέμβει στον πηγαίο κώδικα ενός προγράμματος (source code ή απλά source), αλλά υποχρέωνε και τον προγραμματιστή που θα έκανε αλλαγές, να επαναδημοσιεύσει τον τροποποιημένο πρόγραμμα κάτω από την ίδια άδεια χρήσης, την GPL, ανατροφοδοτώντας την διεθνή κοινότητα προγραμματιστών με τις αλλαγές και τα νέα στοιχεία που είχαν προστεθεί. Σε αυτή την εξάπλωση των προγραμμάτων συνέβαλε καθοριστικά το Internet, χωρίς το οποίο δεν θα είχε νόημα η άδεια χρήσης GPL. Έτσι λοιπόν, ο κύριος τρόπος διάδοσης των προγραμμάτων δεν ήταν η μεταφορά του εκτελέσιμου προγράμματος (όπως πχ. γίνεται με τα σημερινά εμπορικά προγράμματα) αλλά με την μεταφορά του ίδιου του πηγαίου κώδικα του προγράμματος. Όποιος ήθελε να χρησιμοποιήσει το πρόγραμμα που κατέβασε, δεν είχα παρά να το μεταγλωττίσει (compile) σε γλώσσα μηχανής, δηλαδή σε εκτελέσιμο πρόγραμμα, και να το τρέξει.

Εγκατάσταση ενός προγράμματος από πηγαίο κώδικα (installation from source)

Οι περισσότερες σημερινές διανομές GNU/L3inux μας επιτρέπουν να εγκαθιστούμε προγράμματα χωρίς να μπλεκόμαστε με πηγαίους κώδικες και μεταγλωττίσεις. Ωστόσο, αργά ή γρήγορα σχεδόν όλοι χρειάζεται να κάνουμε compile from source, πχ. επειδή η εφαρμογή που ζητάμε δεν διατίθεται στα πακέτα της διανομής μας. Για την ολοκλήρωση της εγκατάστασης είναι απαραίτητο να ανατρέξουμε στην γραμμή εντολών. Αυτό μπορεί να γίνει μέσω τη χρήση ενός terminal emulator.

Έστω λοιπόν ότι θέλουμε να κατεβάσουμε ένα αρχείο που περιέχει τον πηγαίο κώδικα του προγράμματος που μας ενδιαφέρει να εγκαταστήσουμε. Ας υποθέσουμε ότι το πρόγραμμα ονομάζεται application. Συνήθως, τέτοια αρχεία έχουν κατάληξη tar.gz , tgz ή tar.bz2, δηλαδή στο παράδειγμά μας application.tar.gz . Μέχρι να κατέβει το αρχείο μας, ας δούμε τί σημαίνουν αυτές οι καταλήξεις...

Υπάρχει ένα εργαλείο στο unix που ονομάζεται tar και αυτό που κάνει είναι η συνένωση πολλών αρχείων και φακέλων σε ένα αρχείο με κατάληξη .tar. Αν δηλαδή θέλω να ενώσω τα αρχεία file1, file2, file3 σε ένα αρχείο που ονομάζεται files.tar δεν έχω παρά να γράψω:

$ tar cvf files.tar file1 file2 file3

Ενώ για να επαναφέρω αργότερα τα τρία αρχικά αρχεία γράφω:

$ tar xvf files.tar

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

$ gzip files.tar

Το αρχείο files.tar θα αντικατασταθεί από ένα άλλο με όνομα files.tar.gz το οποίο είναι το αρχικό files.tar συμπιεσμένο. Για να το επαναφέρουμε, χρησιμοποιούμε το εργαλείο gunzip:

$ gunzip files.tar.gz

και το συμπιεσμένο files.tar.gz αντικαθίσταται από το αρχικό ασυμπίεστο files.tar. Η παραπάνω διαδικασία δύο βημάτων μπορεί να αντικατασταθεί με μία με τον εξής τρόπο:

$ tar zcvf files.tar.gz file1 file2 file3

για συμπίεση, ενώ για την αποσυμπίεση:

$ tar zxvf files.tar.gz

Τα κολλημένα γράμματα που ακολουθούν μετά την εντολή tar σημαίνουν:

z: χρήση εξωτερικού προγράμματος gzip ή gunzip c: δημιουργία (create) αρχείου .tar x: εξαγωγή (extract) από το αρχείο .tar v: verbose, δηλ. δείχνε μου ένα ένα τα ονόματα των αρχείων που προστίθενται/εξάγωνται f: χρήση αρχείου (διότι το εργαλείο tar είχε ως αρχική σκοπό την εγγραφή σε μαγνητοταινίες DAT για αποθήκευση backup)

Άρα, μάθαμε τί σημαίνει η κατάληξη .tar.gz. Το tgz είναι ακριβώς το ίδιο είδος αρχείου με τα .tar.gz απλά έχουν πιο κομψή κατάληξη. Καθαρά θέμα προτίμησης αυτού που φτιάχνει το συμπιεσμένο αρχείο. Τέλος, τα tar.bz2 είναι αρχεία .tar που συμπιέστηκαν με ένα διαφορετικό πρόγραμμα συμπίεσης, το bzip2. Στην περίπτωση αυτή, στην εντολή tar αντικαθιστούμε το z (χρήση εξωτερικού προγράμματος gzip/gunzip) με το j (χρήση εξωτερικού προγράμματος bzip2/bunzip2). Όσο εξηγούσαμε τις καταλήξεις, το αρχείο application.tar.gz έχει κατέβει! Και ξέρουμε τί θα το κάνουμε:

$ tar zxvf application.tar.gz

Αυτή η εντολή θα δημιουργήσει έναν φάκελο που ονομάζεται application. Μπαίνουμε μέσα στον φάκελο αυτό:

$ cd application

Αν δούμε τα περιεχόμενά του (εντολή ls) θα δούμε διάφορα αρχεία. Σχεδόν σε κάθε αρχείο που κατεβάζουμε υπάρχουν οδηγίες για την εγκατάσταση του στα αρχεία README και INSTALL. Στις περισσότερες περιπτώσεις δεν διαφέρουν από αυτές που περιγράφονται εδώ και είναι οι εξής: Τρέχουμε το αρχείο configure:

$ ./configure

Αυτό που κάνει το configure είναι να ελέγξει αν το σύστημά μας έχει όλα τα απαραίτητα αρχεία για την μεταγλώττιση (compilation) του πηγαίου κώδικα (μεταγλωττιστή, απαραίτητες βιβλιοθήκες--συνήθως C header files, κλπ) και δημιουργεί ένα αρχείο με βάση το οποίο θα γίνει το compliation (Makefile). Όταν τελειώσει το configure ελέγχουμε αν έβγαλε κάποιο σφάλμα (Error). Δεν χρειάζεται να ανατρέξουμε σε όλες τις γραμμές που τυπώθηκαν. Αρκούν οι 4-5 τελευταίες γραμμές. Αν υπάρχει σφάλμα, ανάλογα με την αιτιολογία που αναγράφεται το διορθώνουμε (πχ. εγκαθιστούμε ένα C compiler αν έλειπε, ή καποιες βιβλιοθήκες από τις οποίες εξαρτάται η εφαρμογή). Το configure δέχεται και παραμέτρους, για να δούμε ποιες είναι αυτές περνάμε την παρέμετρο --help. Για να συνεχίσουμε το παράδειγμά μας, υποθέτουμε ότι όλα πήγαν καλά και δεν υπάρχει σφάλμα. Το επόμενο βήμα είναι το compilation. Αυτό γίνεται με την εντολή make, την οποία και γράφουμε:

$ make

Αφού περιμένουμε λίγο χρόνο, ανάλογα με το μέγεθος του κώδικα που μεταγλωττίζεται, το complilation ολοκληρώνεται. Τώρα υπάρχει μέσα στον φάκελο το μεταγλωττισμένο (εκτελέσιμο) πρόγραμμα, αλλά αυτό δεν είναι ακόμα εγκατεστημένο στο σύστημά μας. Για να γίνει αυτό πρέπει να κάνουμε ένα τελευταίο βήμα. Για να εκτελεστεί όμως αυτό το βήμα, που απαιτεί να γραφούν αρχεία σε καταλόγους συστήματος της διανομής μας, πρέπει να έχουμε και τα κατάλληλα δικαιώματα (permissions). Γι αυτό γινόμαστε root:

$ su

Το σύστημα μας ζητάει password το οποίο εννοείται ότι το γνωρίζουμε. Αφού το εισάγουμε σωστά και πατήσουμε Enter είμαστε πλέον με τον λογαριασμό root, οπότε εκτελούμε:

# make install

Το πρόγραμμα εγκαθίσταται. Αν τρέχουμε Ubuntu ή κάποιο σύστημα GNU/Linux που δεν διαθέτει λογαριασμό root, αντί των δύο τελευταίων εντολών, γράφουμε απλά:

$ sudo make install

Τώρα μπορούμε να εγκαταλείψουμε τον λογαριασμό root, να βγούμε από τον φάκελο και να σβήσουμε τον φάκελο εγκατάστασης:

# exit
$ cd ..
$ rm -r application

Αυτό ήταν! Αν σας φαίνεται μεγάλη διαδικασία, η σύνοψή της θα σας πείσει ότι πρόκειται για 6 απλά μικρά βήματα. Σύνοψη:

  1. $ tar zcvf application.tar.gz
  2. $ cd application
  3. $ ./configure
  4. $ make
  5. su
  6. make install; exit

Αυτό ήταν όλο!

Επίλυση προβλημάτων

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

Το πρώτο λύνεται εγκαθιστώντας τα απαραίτητα εργαλεία. Τα βασικότερα είναι ένας C compiler και το make, ενώ πολλές εφαρμογές χρησιμοποιούν και τα autoconf και automake. Σε debian-based διανομές το πακέτο build-essential παρέχει τα πρώτα:

$ ./configure
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking whether make sets $(MAKE)... no
checking for working aclocal-1.4... missing
checking for working autoconf... missing
checking for working automake-1.4... missing
checking for working autoheader... missing
checking for working makeinfo... missing
checking whether to enable maintainer-specific portions of Makefiles... no
checking for gcc... no
checking for cc... no
checking for cc... no
checking for cl... no
configure: error: no acceptable C compiler found in $PATH
See `config.log' for more details.
#apt-get install build-essential autoconf automake

Το δεύτερο πρόβλημα είναι λίγο πιο πολύπλοκο, αφού ο χρήστης πρέπει να 'μεταφράσει' τις εξαρτήσεις που λείπουν σε ονόματα πακέτων για το σύστημα του. Συχνά τα πακέτα έχουν κάποιο πρόθεμα lib (αν είναι βιβλιοθήκες) και επίθεμα -dev (debian based διανομές) ή -devel (rpm based διανομές).

# ./configure
...
checking for pkg-config... no
*** A new enough version of pkg-config was not found.
checking for GLIB - version >= 2.0.0... no
*** The glib-config script installed by GLIB could not be found
...
# apt-get install libglib-dev pkg-config
# ./configure
...
configure: error: Terminfo/termcap not found - install ncurses-devel package
# apt-get install libncurses-dev 

Σε περίπτωση που το πρόβλημα εντοπιστεί κατά το make, το πιθανότερο είναι να μας διέφυγε κάποιο λάθος στο configure, ή να προσπαθούμε να εγκαταστήσουμε κάποια ασταθή έκδοση της εφαρμογής, που δεν έχει δοκιμαστεί επαρκώς. Στην τελευταία περίπτωση καλό θα ήταν να ακολουθήσουμε τις οδηγίες που έχει η εφαρμογή για bug report (αναφορά σφάλματος).

Απεγκατάσταση

Ορισμένες εφαρμογές υποστηρίζουν και απεγκατάσταση με την εξής εντολή:

# make uninstall 

Αλλιώς είναι απαραίτητο να σβηστούν ένα ένα τα αρχεία που εγκατέστησε η εφαρμογή.

Προσοχή: Για να δουλέψει σωστά η απεγκατάσταση, πρέπει να γίνει με τις ίδιες παραμέτρους όπως και η εγκατάσταση, οπότε είναι απαραίτητο να επαναλάβουμε την αρχική διαδικασία μέχρι και το στάδιο του configure (το οποίο θέλει και τις ίδιες παραμέτρους), σε περίπτωση που είχαμε σβήσει το φάκελο της εφαρμογής, ή είχαμε κάνει νέο configure.