Dynamisk länkning och shared objects i FreeBSD: Difference between revisions
mNo edit summary |
|||
Line 1: | Line 1: | ||
Problem med dynamisk länkning är ofta det som strular när man ska kompilera länka ihop något större program. Särskilt om man inte är root på systemet och måste installera sina program på andra ställen än systemets standardställen. | Problem med dynamisk länkning är ofta det som strular när man ska kompilera länka ihop något större program. Särskilt om man inte är root på systemet och måste installera sina program på andra ställen än systemets standardställen. | ||
== Exempel: myapp & libfoo.so == | == Exempel: myapp & libfoo.so == |
Revision as of 19:46, 1 January 2012
Problem med dynamisk länkning är ofta det som strular när man ska kompilera länka ihop något större program. Särskilt om man inte är root på systemet och måste installera sina program på andra ställen än systemets standardställen.
Exempel: myapp & libfoo.so
Vi börjar med ett exempel på ett litet program som består av en exekverbar fil + en so-fil. Detta exempel kommer sedan användas för att åskådliggöra problemen runt so-filer och dynamisk länkning. Vår filstruktur i exemplet är:
. ├── Makefile ├── lib │ ├── Makefile │ ├── foo.c │ └── foo.h └── main.c
Länka utan sökväg till runtime loadern
Bygga och länka libfoo.so
Källkoden till libfoo.so ligger i foo.c och dess interface i foo.h. När vi kompilerar koden måste vi använda -fPIC flaggan. Vi använder det fullständiga kommandot: Template:Box Kommando För att sedan länka ihop libfoo.so så använder vi följande kommando: Template:Box Kommando Optionen -shared används för att skapa ett shared object (so-fil).
Bygga och länka myapp
Vår exekverbar fil består av källkoden main.c men behöver en funktion i libfoo.so för att kunna köras. Vi kompilerar källkoden med kommandot:
För att länka programmet myapp kör vi kommandot: Template:Box Kommando
Om man nu försöker köra myapp kommer man få följande fel: Template:Box Kommando När programmet myapp ska laddas hittar loadern inte libfoo.so filen. För att lösa problem kan vi sätta variabeln LD_LIBRARY_PATH och peka ut var vår libfoo.so ligger. Nu kommer loadern hitta libfoo.so och myapp går att köra. Denna lösning har dock många nackdelar.
Länka med absolut eller relativ sökväg till runtime loadern
För att slippa behöva sätta LD_LIBRARY_PATH vid exekvering kan sökvägar byggas in i ELF filen vid länkning. Loadern kommer vid exekvering använda dessa för att hitta de dynamiskt länkade so-filerna. Bygg och länka libfoo.so som ovan, men länka myapp med följande kommando: Template:Box Kommando Vi kan nu köra myapp utan att behöva sätta LD_LIBRARY_PATH. Man kan kolla vilka sökvägar som är inbyggda i ELF-filen genom att köra kommandot: Template:Box Kommando
Nackdelen med en absolutsökväg är att libfoo.so måste ligga på samma ställe överallt programmet myapp ska köra. Så en relativ sökväg kan tyckas vara bättre. Då behöver bara myapp och libfoo.so relativt ligga på samma ställe. Låt och ändra till en relativ sökväg genom att länka myapp med kommandot: Template:Box Kommando
Vi kan nu köra myapp, men bara när vi står i samma katalog som myapp själv. Så relativ sökväg löser inte heller problemet att kunna köra myapp från olika ställen.
Länka med sökväg via $ORIGIN till runtime loadern
För att lösa problemet med relativ sökväg till libfoo.so, så ska vi använda oss av $ORIGIN i den relativa sökvägen. $ORIGIN löses upp till den aktuella platsen som myapp ligger vid exekveringen. Tyvärr så är namnet $ORIGIN illa valt då $ betyder olika saker i Makefiler, skal etc. Om vi vill köra kommandot i ett bash-skal så behöver vi lägga till ett \ före $-tecknet: Template:Box Kommando I FreeBSD måste vi också lägga till optionen -z origin till länkaren för att ange att objektet ev. använder sig av en $ORIGIN sökväg.
Nu kan myapp och libfoo.so läggas på olika ställen och ändå kunna exekveras. Det enda som krävs är att libfoo.so alltid ligger i en katalog som heter lib under myapp filen.