Δημιουργία Βιβλιοθηκών 


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

Εάν έχετε σκοπό να αναπτύξετε μια μεγάλη βιβλιοθήκη που θα θέλατε να μπορεί να μεταφερθεί και να λειτουργήσει σε πολλά συστήματα, τότε καλό είναι να χρησιμοποιήσετε ένα εργαλείο όπως το GNU libtool το οποίο είναι ένα γενικό σενάριο φλοιού UNIX/Linux για την υποστληριξη βιβλιοθηκών βιβλιοθηκών (generic library support script). Το libtool κρύβει την πολυπλοκότητα της χρησιμοποίησης των διαμοιραζόμενων βιβλιοθηκών πίσω από μια συνεπή, φορητή διεπαφή. Επιπλέον παρέχει φορητές διεπαφές για τη δημιουργία αρχείων αντικείμενου κώδικα, σύνδεση στατικών και μοιραζόμενων βιβλιοθηκών, σύνδεση εκτελέσιμων, αποσφαλμάτωση εκτελέσιμων, εγκατάσταση βιβλιοθηκών και εγκατάσταση εκτελέσιμων. Περιλαμβάνει επίσης το libltdl, ένα περιτύλιγμα φορητότητας (portability wrapper) για τα δυναμικά προγράμματα φόρτωσης (dynamic loading programs). 

Για περισσότερες πληροφορίες, δείτε την τεκμηρίωσή του στο

http://www.gnu.org/software/libtool/manual.html


Παρακάτω θα δείξουμε ένα μικρό παράδειγμα δημιουργίας μιας βιβλιοθήκης. 

Η Συνάρτηση της Βιβλιοθήκης

Αυτός είναι ο κώδικας της συνάρτησης που θα γίνει βιβλιοθήκη. Εϊναι μια απλή συνάρτηση που επιστρέφει το μέσο όρο δύο πραγματικών αριθμμών. Το όνομα του αρχείου του πηγαίου κώδικα είναι calc_mean.c.
#include <stdio.h>

double mean(double a, double b) {
return (a+b) / 2;
}
Το αντίστοιχο αρχείο κεφαλής λέγεται calc_mean.h.
double mean(double, double);

Δημιουργία Στατικής Βιβλιοθήκης

Μια στατική (static) βιβλιοθήκη είναι βασικά ένα σύνολο από αρχεία αντικείμενου κώδικα που έχουν μεταγλωττιστεί (ή αντιγραφεί) σε ένα ενιαίο αρχείο. Αυτό το ενιαίο αρχείο είναι η βιβλιοθήκη. Το αρχείο δημιουργείται με την εφαρμογή του UNIX/Linux archiver (ar).

Πρώτα το αρχείο του πηγαίου κώδικα μεταγλωττίζεται σε αρχείο αντικείμενου κώδικα, όπως ακριβώς και στη περίπτωση των πολλαπλών αρχείων:
gcc -c calc_mean.c -o calc_mean.o
Κατόπιν, η καλείται η εφαρμογή ar για να παράγει τη στατική βιβλιοθήκη με όνομα libmean.a με βάση το αρχείο του αντικείμενου κώδικα calc_mean.o
ar rcs libmean.a calc_mean.o
Tο όνομα της βιβλιοθήκης πρέπει να ξεκινά με το πρόθεμα lib και να έχει επέκταση .a. Είναι προφανές οτι στα δύο παραπάνω βήματα θα μπορούσαμε να έχουμε περισσότερα από ένα αρχεία πηγαίου ή αντικείμενου κώδικα ως είσοδο των εφαρμογών gcc και ar αντίστοιχα.

Δημιουργία Μοιραζόμενης Βιβλιοθήκης

Όπως και στη περίπτωση των στατικών βιβλιοθηκών, αρχικά δημιουργείται ένα αρχείο αντικείμενου κώδικα. Η επιλογή -fPIC ενημερώνει τη gcc να παράγει μετατοπίσημο (relocatable) κώδικα, δηλαδή κώδικα που οι διευθύνσεις των μεταβλητών, συναρτήσεων κλπ να είναι σχετικές ή δυναμικές (relative, dynamic) και όχι απόλυτες ή στατικές (absolute, static) σε σχέση με το σημείο εισόδου (κλήσης) της συνάρτησης. Αυτό είναι απαραίτητο ώστε ο κώδικας της βιβλιοθήκης να είναι ανεξάρτητος από τη θέση της βιβλιοθήκης στο τελικό συνδεδεμένο εκτελέσιμο (position independent). Έτσι η βιβλιοθήκη μπορεί να μοιραστεί σε, δηλαδή να χρησιμοποιηθεί από, διαφορετικά προγράμματα.

gcc -c -fPIC calc_mean.c -o calc_mean.o

Κατόπιν προχωρούμε στη δημιουργία της μοιραζόμενης βιβλιοθήκης:
gcc -shared -Wl,-soname,libmean.so.1 -o libmean.so.1.0.1 calc_mean.o

Κάθε μοιραζόμενη βιβλιοθήκη έχει ένα ειδικό όνομα, το λεγόμενο soname. Το soname ξεκινά με το πρόθεμα lib, ακολουθεί το όνομα της βιβλιοθήκης, η επέκταση .so και τέλος μια ακόμα τελεία (.) ακολουθούμενη από έναν αριθμό έκδοσης (version number) που αυξάνεται όποτε η διεπαφή της βιβλιοθήκης αλλάζει. Εδώ το soname είναι libmean.so.1 .

Επίσης κάθε μοιραζόμενη βιβλιοθήκη έχει ένα "πραγματικό" όνομα, το οποίο είναι το όνομα αρχείου που περιέχει τον πραγματικό κώδικα βιβλιοθήκης. Το πραγματικό όνομα προσθέτει στο soname μια επιπλέον περίοδο, ένα δευτερεύοντα αριθμό, μια ακόμα τελεία, και τον αριθμό διανομής (release number). Η τελευταία τελεία και ο αριθμός διανομής είναι προαιρετικά. Εδώ το πραγματικό όνομα είναι libmean.so.1.0.1 .

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

Περισσότερα για τις συμβάσεις της ονομασίας των βιβλιοθηκών στα σχετικά εγχειρίδια.

Χρήση της Βιβλιοθήκης

Το παρακάτω πρόγραμμα main.c χρησιμοποιεί τη βιβλιοθήκη calc_mean. Θα το συνδέσουμε τη πρώτη φορά με τη στατική βιβλιοθήκη και τη δεύτερη φορά με τη μοιραζόμενη βιβλιοθήκη.
#include <stdio.h>
#include "calc_mean.h"

int main(int argc, char *argv[]) {

double v1, v2, m;
v1 = 5.2;
v2 = 7.9;

m = mean(v1, v2);

printf("The mean of %3.2f and %3.2f is %3.2f\n", v1, v2, m);

return 0;
}
Σύνδεση με στατική βιβλιοθήκη:
gcc -static main.c -L. -lmean -o statically_linked
Σημείωση: στο όνομα σύνδεσης ΔΕΝ περιλαμβάνεται το πρόθεμα lib και η επέκταση .a .

Σύνδεση με μοιραζόμενη βιβλιοθήκη:
gcc main.c -o dynamically_linked -L. -lmean
Σημείωση: στο όνομα σύνδεσης ΔΕΝ περιλαμβάνεται το πρόθεμα lib και η επέκταση .so.1.0.1.

Ασκήσεις 

Άσκηση 1

Με βάση το παράδειγμα που παρουσιάστηκε στην ενότητα των προγραμμάτων πολλαπλών αρχείων δημιουργείστε μια δική σας στατική και μια μοιραζόμενη βιβλιοθήκη.
μετάφραση και προσαρμογή στα Ελληνικά Κ.Γ. Μαργαρίτης
16/5/2008