Sdílené knihovny (tutorial)
Vytváření dynamických knihoven je všeobecně považováno za počin hodný pravého počítačového kouzelníka a je obestřeno temnotou nevědomosti. Ve skutečnosti existuje jen málo věcí, které by byly jednodušší (a konstrukce kosmických lodí mezi ně nepatří :-)). Jediný problém je, že dynamický linker je pod každým operačním systémem stvoření naprosto unikátní, takže přenositelné dynamické knihovny již nejsou maličkost. Naštěstí existuje program Libtool, který se snaží doplnit Autoconf o prostředky k jejich přenositelnému vytváření. My se zde budeme zabývat pouze tím, jak takové věci fungují pod Linuxem.
Každá dynamická knihovna je identifikována třemi parametry: jménem, verzí
interfacu a verzí implementace. Různé implementace se stejným interfacem
by měly být navzájem zaměnitelné, proto je v každém programu uloženo o knihovnách,
které potřebuje, pouze jak se jmenují a jaký mají mít interface a dynamický
linker již automaticky vybere nejnovější implementaci. Teď jsem trošku zalhal,
protože ve skutečnosti takové věci nezařizuje dynamický linker samotný, nýbrž
program ldconfig
, který vytváří soubor /etc/ld.so.cache
se seznamem všech známých knihoven.
Pro každou knihovnu existuje několik symbolických linků. Například pro
knihovnu libexample
s interfacem verze 1
a implementací
verze 2.3
, která by byla uložena v souboru /usr/lib/libexample.so.1.2.3
,
by existovaly následující linky:
/usr/lib/libexample.so.1 -> /usr/lib/libexample.so.1.2.3
- Tento link je založen
ldconfig
em a řiká, že pro verzi interfacu 1 se má použít implementace 1.2.3. /usr/lib/libexample.so -> /usr/lib/libexample.so.1
- Tento link se zakládá ručně a určuje, jaká verze interfacu se má defaultně použít, když někdo při kompilaci požádá o použití této knihovny.
Pokud chceme dynamickou knihovnu vytvořit, stačí všechny moduly zkompilovat
do objectů s parametrem -fPIC
(kninovny musí být position
independent). Na rozdíl od statických knihoven se linkuje vždy celá knihovna,
takže není nutné rozdrobit celou knihovnu na maličké modulky po funkcích.
Moduly poté slinkujeme do dynamické knihovny s přepínači -shared
-Wl,-soname,libexample.so.1
. U parametru soname
uvedeme,
jak se má interface knihovny jmenovat.