A linkelési folyamat feltárása – Statikus vs. dinamikus könyvtárak
Sztatikus és dinamikus könyvtár létrehozása
A statikus könyvtár esetében a bináris fájlok (kiterjesztés .o
) objektumkódja egyetlen, .a
kiterjesztésű archív fájlban egyesül. Ez az archívum egy eszköztárhoz hasonlít, amely tartalmazza az összes olyan eszközt, amelyet az adott könyvtárat a linkelés során meghívó programokban használhatunk. Az eszközök oda kerülnek be, ahol szükség van rájuk. Az alábbi képen egy sor .c
fájlom van.
Mivel a könyvtár egy objektumkódot tartalmazó archívum, az összes ilyen .c
fájlt át kell alakítanom .o
fájlokká a következő parancs segítségével:
gcc -Wall -Wextra -Werror -pedantic -c *.c
A -c
opció közvetlenül a linkelés előtt leállítja a fordítási folyamatot az objektumkód fájlok létrehozása után. Most már megvan az összes objektumkód fájl:
Ha a ar -rc libholbertonschool.a *.o
parancsot futtatom, akkor ezeket a fájlokat egyetlen .a
könyvtárfájlba archiválhatom. A ar
parancs az archiválásra, a -r
opció a .o
kiterjesztésű tagok áthelyezésére, a -c
opció pedig az archívum létrehozására szolgál, ha az még nem létezik. Egy könyvtárfájl lib
előtaggal kezdődik, és .a
kiterjesztéssel rendelkezik. Az utolsó lépés, amely egyes rendszereken szükséges, az archívum tartalmának indexelése a linkelés felgyorsítása érdekében. Ezt a ranlib libholbertonschool.a
segítségével lehet elvégezni. Most már van egy könyvtáram, amely a fenti képen látható összes függvény objektumkódját tartalmazza.
A statikus könyvtár használata
Hogy ezt a könyvtárat valamilyen tesztfájllal használjam, a tesztfájlt a könyvtárral kell lefordítanom a következő két parancs valamelyikével:
gcc test.c ./libholbertonschool.a -o exename
gcc test.c -L. -lholbertonschool -o exename
Mindkettő ugyanazt teszi, de a második kicsit rejtélyesebb. A -L.
opció az aktuális könyvtárban lévő könyvtárakat keresi, a holbertonschool
-hez kapcsolódó -l
pedig implicit módon keresi a könyvtárfájlt, ahol lib
előtagot és .a
utótagot feltételez. Könyvtárfájllal való fordítás nélkül a gcc
hibát fog dobni, mivel a linkelni kívánt függvények nincsenek megadva. Ha a fordítás során megadunk egy könyvtárat, akkor a fordító most meg tudja keresni a könyvtárban a szükséges függvényeket, és be tudja illeszteni őket oda, ahol szükség van rájuk.
Dinamikus könyvtárak
A dinamikus könyvtárak létrehozása némileg eltér a statikus könyvtáraktól, de a fogalmak általában ugyanazok. Ugyanannyi .c
fájlom van, és a prototípusaikat definiáló fejlécfájl egy lists.h
nevű fájlban.
A dinamikus könyvtár létrehozásához, amely .so
(a megosztott objektumot jelöli), a következő fordítási parancsot adhatjuk meg:
gcc -fPIC -Wall -Werror -Wextra -pedantic *.c -shared -o libholberton.so
A -fPIC
jelző a pozíciófüggetlen kódot jelenti, amely a dinamikus linkeléshez szükséges. Ennek jelentése pontosan az, aminek hangzik – mivel a dinamikusan linkelt könyvtárak bárhol tárolhatók a memóriában, ahol elférnek, ez a flag lehetővé teszi, hogy a könyvtárfájlt a tárolási helyétől függetlenül használjuk.
A -shared
flag lehetővé teszi egy megosztott archívum létrehozását, a -o
opcióval pedig átnevezhetjük a kimeneti fájlt libholberton.so
-re.
A parancs futtatása után már van egy megosztott könyvtáram!
A dinamikus könyvtár használata
Tegyük fel, hogy a következő kóddal rendelkezem:
#include "holberton.h"
#include <stdlib.h>
#include <stdio.h>/**
* main - check the code for Holberton School students.
*
* Return: Always EXIT_SUCCESS.
*/
int main(void)
{
printf("%d\n", _strlen("Holberton"));
return (EXIT_SUCCESS);
}
A programot a következő kóddal tudom lefordítani:
gcc -Wall -pedantic -Werror -Wextra -L. 0-main.c -lholberton -o len
A statikus könyvtárakhoz hasonlóan a -L.
opciók könyvtárfájlokat keresnek a könyvtárban, a holberton
elejére illesztett -l
pedig implicit módon olyan könyvtárfájlokat keres, amelyek előtagja lib
, utótagja .so
, és a kettő között holberton
.
Az imént létrehozott könyvtárfájl használatához meg kell győződnöm arról, hogy a fordító képes megtalálni az összes könyvtárfájlt a memóriában, és hogy azok kezdetben megfelelően be vannak töltve a memóriába. Ha most lefuttatom a ldd len
sort, a következőket látom: