Staticke linkovani

Jan Otte jotte na suse.cz
Pátek Březen 9 11:38:24 CET 2007


> Tak to zkusíme naprosto konkrétně :-)
> Triviální příklad:
> 
> #include <pthread.h>
> #include <unistd.h>
> int main(void){
>    write(1, "a", 1);
> }  

Perlicka: v tomto pripade pthread nepotrebujete, pujde to prelozit i bez
-lpthread nebot nic z teto knihovny nepouzivate (bohuzel to priklad
znehodnoti -- viz nize pod prikladem). Trivialnim prikladem kde je jina
knihovna potreba je pouziti napr. matem. fce. sin() (libm)

> 
> Cílem je přilinkovat libpthread (náhodně zvolená knihovna) staticky a 
> libc dynamicky, aby se používaly správné moduly libnss_* .
> Vše zkoušeno na Debianu Sarge i386, gcc 3.3.5, libc 2.3.2.

> gcc -o test test.c -Wl,-Bstatic -lpthread -Wl,-Bdynamic
> /usr/lib/gcc-lib/i486-linux/3.3.5/../../../libpthread.a(ptw-write.o)(.text+0x25): 
> In function `write':
> : undefined reference to `__syscall_error'
> /usr/lib/gcc-lib/i486-linux/3.3.5/../../../libpthread.a(ptw-write.o)(.text+0x55): 
> In function `write':
> : undefined reference to `__syscall_error'
> /usr/lib/gcc-lib/i486-linux/3.3.5/../../../libpthread.a(ptw-read.o)(.text+0x25): 
> In function `read':
> : undefined reference to `__syscall_error'
> /usr/lib/gcc-lib/i486-linux/3.3.5/../../../libpthread.a(ptw-read.o)(.text+0x55): 
> In function `read':
> : undefined reference to `__syscall_error'
> /usr/lib/gcc-lib/i486-linux/3.3.5/../../../libpthread.a(ptw-close.o)(.text+0x1f): 
> In function `close':
> : undefined reference to `__syscall_error'
> /usr/lib/gcc-lib/i486-linux/3.3.5/../../../libpthread.a(ptw-close.o)(.text+0x4a): 
> more undefined references to `__syscall_error' follow
> collect2: ld returned 1 exit status

To znamena je ze vam chybi nejaka knihovna. Vsimnete si sveho #include
<unistd.h>

Kdyz jej zmenite za #include <stdio.h> a write za printf tak vam to
projde:

--- cut here ---
> gcc -o testme test4.c -shared-libgcc -Wl,-Bstatic -lpthread
> -Wl,-Bdynamic -lc
> ldd testme
        libc.so.6 => /lib64/libc.so.6 (0x00002b4d756e0000)
        libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00002b4d75a22000)
        /lib64/ld-linux-x86-64.so.2 (0x00002b4d754c2000)
> ./testme
wer
> cat test4.c 
#include <pthread.h>
#include <stdio.h>
int main(void){
        printf("wer\n");
}  

--- cut here ---

Ale uvedomte si ze pri linkovani byla libpthread zahozena, protoze
nebyla potreba. Abyste si to opravdu vyzkousel, vynutte pouziti treba
jiz drive zminovane libm pouzitim sin().

> 
> Takže podle mě to nemá řešení a pokud někdo nepřijde s nadějnou cestou 
> jak dál, tak další experimenty vzdávám.

Reseni to ma, jen musite prijit na to co vam chybi. Princip
kombinovaneho linkovani si muzete vyzkouset na priklade vyse.

Priklad s libm:

--- cut here ---
> cat test3.c 
#include <stdio.h>
#include <math.h>
int main(void){
   printf("%f\n", sin(10));
}

> gcc -o testme test3.c -Wl,-Bstatic -lm -Wl,-Bdynamic
> gcc -o testme2 test3.c -lm
> ldd testme testme2
testme:
        libc.so.6 => /lib64/libc.so.6 (0x00002ae79c1db000)
        /lib64/ld-linux-x86-64.so.2 (0x00002ae79bfbd000)
testme2:
        libm.so.6 => /lib64/libm.so.6 (0x00002ba4f4ca7000)
        libc.so.6 => /lib64/libc.so.6 (0x00002ba4f4efd000)
        /lib64/ld-linux-x86-64.so.2 (0x00002ba4f4a89000)
> ls -l testme testme2
-rwxr-xr-x 1 jotte users 19775 2007-03-09 11:35 testme
-rwxr-xr-x 1 jotte users 11270 2007-03-09 11:35 testme2
> ./testme
-0.544021
> ./testme2
-0.544021
--- cut here ---


S pozdravem,
Honza



Další informace o konferenci Linux