int21h

Používání knihoven v Linuxu

Toto je věc, které se týká c, ale v žádných učebnicích c ji nenajdete. Je to totiž čistě unixová záležitost. O co jde? Pokud děláte větší projekt složený z více programů, tak nejdříve všechny zkompilujete do přenosných objektových souborů *.o a ty pak slinkujete do jednoho výstupního programu. Knihovna v linuxu znamená složení více takových objektových souborů do jednoho celku. Určitě jste už setkali s linkováním knihoven. Je to parametr -l. Pokud se podíváte do adresáře /usr/lib (resp. /usr/local/lib), tak zjistíte, že se programy jmenují většinou libneco.so nebo libneco.a. Takovou knihovnu nalinkujete přes parametr -lneco

Teď už se pustíme do demonstračního příkladu


Příklad

výpis main.c:
#include <stdio.h>
#include "message.h"


int main() {
	proved(80);
	return 0;
}
výpis message.c:
#include <stdio.h>
#include "message.h"
#include "count.h"


int proved(int x) {
	printf("Sinus z x je %5.5f",vratsin(x));
	return 0;
}
výpis message.h:
int proved(int x);
výpis count.c:
#include <stdio.h>
#include <math.h>
#include "count.h"


float vratsin(int x) {
	return sin(x);
}
výpis count.h
float vratsin(int x);  
(Omluvte absurditu příkladu. Myslím, že demonstrační funkci ale plní.)
Normálně bychom program kompilovali tímto způsobem:
$ gcc -c main.c message.c count.c
$ gcc -o sinus main.o message.o count.o

Teď se ale podíváme, jak z objektů vytvořit knihovnu.

Statické knihovny

Statická knihovna se do výsledného programu vloží. To znamená, že program bude větší a hůře aktualizovatelný. Na druhou stranu nebudou problémy z přenositelností, protože program bude pracovat bez zvláštních potřeb po systému. Takové programy se někdy i distribuují. Příklad je třeba prohlížeč obrázků XnView. Program používá grafickou knihovnu Motif. Můžete se rozhodnout, jestli chcete normální verzi, která předpokládá, že máte knihovnu Motif ve vlastním systému (čemuž tak většinou je). Můžete si také stáhnout static verzi balíku. To znamená, že prostředí Motif je zakomponováno v programu - s tím samozřejmě roste velikost, ale také jistota, že program poběží všude.

Tak jak vytvořit statickou knihovnu.
Statická knihovna lib*.a je pouze archív vytvořený programem ar. Ten už je dosti zastaralý a všechno jeho využití převzal GNU tar. Tvorba knihoven zůstala jeho jedinou funkcí.
K vytvoření archívu zadáme
$ ar cq libfunc.a mesage.o count.o
(pozn. některé zdroje uvádějí ar cr, ale r znamená vložit do archivu s přepsáním, což se logicky nehodí k parametru c-vytvořit)
libfunc.a je tedy statická knihovna. Na její obsah se můžete podívat přes ar tv libfunc.a. Objekty *.o už nebudeme potřebovat, tak je můžete smazat.
A jak spojit knihovnu s programem:
$ gcc -c main.c vytvoříme si objekt hlavního programu (do knihoven se samozřejmě nevkládá)
$ gcc -o sinus main.o -lm -L. -lfunc
Parametr -L nastavuje adresář s knihovnami (.=aktuální), program prohledává nejdřív tento adresář a potom systémové.
Tak to je vše ke statickým. Existuje však ještě jeden druh. Knihovny sdílené dynamické.

Sdílené dynamické knihovny

Dynamická knihovna stejně jako statická obsahuje sadu objektových souborů *.o. Při slinkování s programem se ale do programu nevloží objekty, ale pouze jejich jména cesty, kde je má program najít. Program hledá v systémových adresářích a v adresářích uvedených v proměnné $LD_LIBRARY_PATH.

Výhoda dynamických knihoven je v tom, že program, který je používá je hodně menší než static verze, ale zase není jisté, že knihovna v systému bude. U knihoven jako libz, libgtk nebo libcrypt je jasné, že je bude systém obsahovat. Někdy to však jisté není. Obecně nedoporučuji používat static programy a spíše si nové knihovny stáhnout. Další výhodou je lehlá aktualizace. Pokud někdo vyvine novou verzi dynamické knihovny, tak se nemusí program používající knihovnu překompilovávat.

Tvorba dynamické knihovny:
$ gcc -c -fPIC message.c count.c
$ gcc -shared -fPIC -o libfunc.so message.o count.o

Opět můžete smazat *.o
Volba -fPIC znamená Position Independent Code. Pro nás to není ale vůbec důležité. Jen nezapomenout parametr zadávat.
A konečně přeložení
$ gcc -o sinus main.o -L. -lfunc -lm -Wl,-rpath,`pwd`
To od -Wl používejte jen při ladění a podobně. Jinak přesuňte libfunc.so do /usr/lib nebo jiného systémového adresáře. Pak už parametry nebudete potřebovat (ani -L.)

Závěr

V distribuci se většinou dodává statická i dynamická podoba knihovny, aby měli programátoři možnost vytvořit statickou verzi svého programu.

Zdroje
Pokročilé programování v operačním systému Linux - Softpress
man, info
2006-12-06 | BOby
Datum: 12.4.2008 16:52
Od: L.BENN
Titulek: dlopen a dlsym
Výstižný článek, určitě by se hodilo se zmínit o další možnosti natahování dynamických knihoven přes dlopen() a dlsym().

Reklamy:
„Nejkrásnější ze všech tajemství je být géniem a vědět to jen sám.“ Mark Twain