GNU/Linux >> Znalost Linux >  >> Linux

Jak zacházet s dynamickými a statickými knihovnami v Linuxu

Linux je svým způsobem série statických a dynamických knihoven, které jsou na sobě závislé. Pro nové uživatele systémů založených na Linuxu může být celá manipulace s knihovnami záhadou. Ale se zkušenostmi může být obrovské množství sdíleného kódu zabudovaného do operačního systému výhodou při psaní nových aplikací.

Abychom vám pomohli dostat se do kontaktu s tímto tématem, připravil jsem malý příklad aplikace, který ukazuje nejběžnější metody, které fungují na běžných distribucích Linuxu (tyto nebyly testovány na jiných systémech). Chcete-li pokračovat v tomto praktickém kurzu pomocí vzorové aplikace, otevřete příkazový řádek a zadejte:

$ git klon https://github.com/hANSIc99/library_sample
$ cd library_sample/
$ make
cc -c main.c -Wall -Werror
cc -c libmy_static_a.c -o libmy_static_a.o -Wall -Werror
cc -c libmy_static_b.c -o libmy_static_b.o -Wall -Werror
ar -rsv libmy_static.a libmy_static_a.o libmy_static_b.o
ar:vytvoření libmy_static.a
a - libmy_static_a.o
a - libmy_static_b.o
cc -c -fPIC libmy_shared.c -o libmy_shared.o
cc - shared -o libmy_shared.so libmy_shared.o
$ make clean
rm *.o

Po provedení těchto příkazů by měly být tyto soubory přidány do adresáře (spusťte ls vidět je):

moje_aplikace
libmy_static.a
libmy_shared.so

O statickém propojení

Když se vaše aplikace propojí se statickou knihovnou, kód knihovny se stane součástí výsledného spustitelného souboru. To se provádí pouze jednou v době propojení a tyto statické knihovny obvykle končí .a rozšíření.

Statická knihovna je archiv (ar) objektových souborů. Objektové soubory jsou obvykle ve formátu ELF. ELF je zkratka pro Executable and Linkable Format, který je kompatibilní s mnoha operačními systémy.

Výstup file příkaz vám řekne, že statická knihovna libmy_static.a je ar typ archivu:

$ soubor libmy_static.a
libmy_static.a:aktuální archiv ar

Pomocí ar -t , můžete nahlédnout do tohoto archivu; ukazuje dva objektové soubory:

$ ar -t libmy_static.a 
libmy_static_a.o
libmy_static_b.o

Soubory archivu můžete extrahovat pomocí ar -x <archive-file> . Extrahované soubory jsou objektové soubory ve formátu ELF:

$ ar -x libmy_static.a
$ soubor libmy_static_a.o
libmy_static_a.o:ELF 64bitový LSB přemístitelný, x86-64, verze 1 (SYSV), není odstraněn

O dynamickém propojení

Další zdroje pro Linux

  • Cheat pro příkazy Linuxu
  • Cheat sheet pro pokročilé příkazy systému Linux
  • Bezplatný online kurz:Technický přehled RHEL
  • Síťový cheat pro Linux
  • Cheat sheet SELinux
  • Cheat pro běžné příkazy pro Linux
  • Co jsou kontejnery systému Linux?
  • Naše nejnovější články o Linuxu

Dynamické propojování znamená použití sdílených knihoven. Sdílené knihovny obvykle končí .so (zkratka pro "shared object").

Sdílené knihovny jsou nejběžnějším způsobem správy závislostí na systémech Linux. Tyto sdílené prostředky jsou načteny do paměti před spuštěním aplikace, a když několik procesů vyžaduje stejnou knihovnu, bude načtena do systému pouze jednou. Tato funkce šetří využití paměti aplikací.

Další věc, kterou je třeba poznamenat, je, že když je chyba opravena ve sdílené knihovně, bude z toho profitovat každá aplikace, která na tuto knihovnu odkazuje. To také znamená, že pokud chyba zůstane neodhalena, bude jí trpět každá odkazující aplikace (pokud aplikace používá postižené části).

Pro začátečníky může být velmi obtížné, když aplikace vyžaduje konkrétní verzi knihovny, ale linker zná pouze umístění nekompatibilní verze. V tomto případě musíte pomoci linkeru najít cestu ke správné verzi.

Ačkoli to není každodenní problém, pochopení dynamického propojení vám jistě pomůže při řešení takových problémů.

Naštěstí jsou mechanismy pro to docela jednoduché.

Chcete-li zjistit, které knihovny jsou nutné pro spuštění aplikace, můžete použít ldd , který vytiskne sdílené knihovny používané daným souborem:

$ ldd moje_aplikace 
        linux-vdso.so.1 (0x00007ffd1299c000)
        libmy_shared.so => ​​nenalezeno
        libc.so.4.6 => /lib c.6 (0x00007f56b869b000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f56b8881000)

Všimněte si, že knihovna libmy_shared.so je součástí úložiště, ale nebyl nalezen. Je to proto, že dynamický linker, který je zodpovědný za načtení všech závislostí do paměti před spuštěním aplikace, nemůže najít tuto knihovnu ve standardních umístěních, která prohledává.

Chyby spojené s linkery nacházejícími nekompatibilní verze běžných knihoven (jako bzip2 , například) může být pro nového uživatele značně matoucí. Jedním ze způsobů, jak to obejít, je přidat složku úložiště do proměnné prostředí LD_LIBRARY_PATH sdělit linkeru, kde má hledat správnou verzi. V tomto případě je správná verze v této složce, takže ji můžete exportovat:

$ LD_LIBRARY_PATH=$(pwd):$LD_LIBRARY_PATH
$ export LD_LIBRARY_PATH

Nyní dynamický linker ví, kde knihovnu najít, a aplikaci lze spustit. Můžete znovu spustit ldd k vyvolání dynamického linkeru, který zkontroluje závislosti aplikace a načte je do paměti. Adresa paměti se zobrazí za cestou k objektu:

$ ldd moje_aplikace 
        linux-vdso.so.1 (0x00007ffd385f7000)
        libmy_shared.so => ​​/home/stephan/library_sample/libmy_so.0.0. 0.  6 => /lib64/libc.so.6 (0x00007f3fad21d000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f3fad408000)

Chcete-li zjistit, který linker je vyvolán, můžete použít file :

$ file my_app 
my_app:ELF 64bitový LSB spustitelný soubor, x86-64, verze 1 (SYSV), dynamicky propojený, interpret /lib64/ld-linux-x86-64.so.2, BuildID[ sha1]=26c677b771122b4c99f0fd9ee001e6c743550fa6, pro GNU/Linux 3.2.0, neodstraněno

Linker /lib64/ld-linux-x86–64.so.2 je symbolický odkaz na ld-2.30.so , což je výchozí linker pro moji distribuci Linuxu:

$ soubor /lib64/ld-linux-x86-64.so.2 
/lib64/ld-linux-x86-64.so.2:symbolický odkaz na ld-2.31.so

Při pohledu zpět na výstup ldd , můžete také vidět (vedle libmy_shared.so ), že každá závislost končí číslem (např. /lib64/libc.so.6 ). Obvyklé schéma pojmenování sdílených objektů je:

**lib** XYZ.so **.<MAJOR>** . **<MINOR>** 

V mém systému libc.so.6 je také symbolickým odkazem na sdílený objekt libc-2.30.so ve stejné složce:

$ soubor /lib64/libc.so.6 
/lib64/libc.so.6:symbolický odkaz na libc-2.31.so

Pokud se potýkáte s problémem, že se aplikace nespustí, protože načtená knihovna má špatnou verzi, je velmi pravděpodobné, že tento problém můžete vyřešit kontrolou a přeskupením symbolických odkazů nebo zadáním správné vyhledávací cesty (viz „Dynamický zavaděč :ld.so" níže).

Další informace naleznete na ldd manuálová stránka.

Dynamické načítání

Dynamické načítání znamená, že knihovna (např. .so soubor) se načítá během běhu programu. To se provádí pomocí určitého programovacího schématu.

Dynamické načítání se použije, když aplikace používá pluginy, které lze za běhu upravit.

Viz dlopen manuálová stránka pro více informací.

Dynamický nakladač:ld.so

V Linuxu se většinou zabýváte sdílenými objekty, takže musí existovat mechanismus, který zjistí závislosti aplikace a nahraje je do paměti.

ld.so hledá sdílené objekty na těchto místech v následujícím pořadí:

  1. Relativní nebo absolutní cesta v aplikaci (pevně zakódovaná pomocí -rpath možnost kompilátoru na GCC)
  2. V proměnné prostředí LD_LIBRARY_PATH
  3. V souboru /etc/ld.so.cache

Mějte na paměti, že přidání knihovny do archivu systémové knihovny /usr/lib64 vyžaduje oprávnění správce. Můžete zkopírovat libmy_shared.so ručně do archivu knihovny a zprovozněte aplikaci bez nastavení LD_LIBRARY_PATH :

zrušte nastavení LD_LIBRARY_PATH
sudo cp libmy_shared.so /usr/lib64/

Když spustíte ldd , nyní můžete vidět cestu k archivu knihovny:

$ ldd moje_aplikace 
        linux-vdso.so.1 (0x00007ffe82fab000)
        libmy_shared.so => ​​/lib64/libmy_shared.so =(0x00007f00096) <> 0x00007f00096. lib64/libc.so.6 (0x00007f0a96216000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f0a96401000)

Přizpůsobení sdílené knihovny v době kompilace

Pokud chcete, aby vaše aplikace používala vaše sdílené knihovny, můžete během kompilace zadat absolutní nebo relativní cestu.

Upravte makefile (řádek 10) a znovu zkompilujte program vyvoláním make -B . Poté výstup ldd zobrazuje libmy_shared.so je uvedena se svou absolutní cestou.

Změňte toto:

CFLAGS =-Wall -Werror -Wl,-rpath,$(shell pwd)  

K tomu (nezapomeňte upravit uživatelské jméno):

CFLAGS =/home/stephan/library_sample/libmy_shared.so  

Poté znovu zkompilujte:

$ make 

Potvrďte, že používá absolutní cestu, kterou jste nastavili, kterou můžete vidět na řádku 2 výstupu:

$ ldd moje_aplikace
    linux-vdso.so.1 (0x00007ffe143ed000)
        libmy_shared.so => ​​/lib64/libmy_shared.so (0x00007fe50_0) /redhobr/amp0 my .so (0x00007fe509268000)
        libc.so.6 => /lib64/libc.so.6 (0x00007fe50909e000)
)       /lib64/ld-804-so.06

Toto je dobrý příklad, ale jak by to fungovalo, kdybyste vytvářeli knihovnu pro ostatní? Nová umístění knihoven lze zaregistrovat jejich zapsáním do /etc/ld.so.conf nebo vytvoření <library-name>.conf soubor obsahující umístění pod /etc/ld.so.conf.d/ . Poté ldconfig musí být proveden k přepsání ld.so.cache soubor. Tento krok je někdy nezbytný po instalaci programu, který s sebou přináší některé speciální sdílené knihovny.

Viz ld.so manuálová stránka pro více informací.

Jak zacházet s více architekturami

Obvykle existují různé knihovny pro 32bitové a 64bitové verze aplikací. Následující seznam ukazuje jejich standardní umístění pro různé distribuce Linuxu:

Rodina Red Hat

  • 32bitový:/usr/lib
  • 64bitový:/usr/lib64

Rodina Debian

  • 32bitový:/usr/lib/i386-linux-gnu
  • 64bitový:/usr/lib/x86_64-linux-gnu

Rodina Arch Linux

  • 32bitový:/usr/lib32
  • 64bitový:/usr/lib64

FreeBSD (technické, nikoli distribuce Linuxu)

  • 32bit:/usr/lib32
  • 64bit:/usr/lib

Vědět, kde tyto klíčové knihovny hledat, může způsobit, že nefunkční odkazy knihoven se stanou problémem minulosti.

I když to může být zpočátku matoucí, pochopení správy závislostí v linuxových knihovnách je způsob, jak mít pocit kontroly nad operačním systémem. Projděte si tyto kroky s jinými aplikacemi, abyste se seznámili s běžnými knihovnami a dále se učili, jak opravit jakékoli problémy s knihovnami, které by se mohly objevit.


Linux
  1. Jak nastavit statickou IP adresu a nakonfigurovat síť v Linuxu

  2. Jak nainstalovat a otestovat Ansible na Linuxu

  3. Jak nakonfigurovat statickou a dynamickou IP adresu v Arch Linuxu

  1. Jak spravovat statický a dynamický inventář hostitelů Ansible

  2. Jak nastavit statickou IP adresu a upravit směrovací tabulku v systému Linux

  3. Jak nastavit hlavičky a knihovny pro vývoj Linuxu

  1. Jak duální bootování Linuxu a Windows

  2. Jak spravovat a vypisovat služby v Linuxu

  3. Jak nainstalovat a používat Flatpak v Linuxu