2012-01-04 15 views
8

Aynı işlemi GCC 4.4 ve GCC 4.5 üzerinde yapmaya çalışırken bir fark gözlemliyorum. Bunu yaptığım kod tescilli olduğu için bunu sağlayamıyorum, ancak bu basit test vakasında benzer bir başarısızlığı gözlemliyorum.GCC 4.5 vs 4.4 bağımlılarla bağlantı kurma

Temelde yapmaya çalıştığım şey, bir paylaşılan kitaplığa (libb) başka bir paylaşılan kitaplığa (liba) bağımlı olmaktır. Libb'yi yüklerken libb 'nin de yüklenmesi gerektiğini - libb' nin liba 'daki sembolleri kullanmamasına rağmen.

Gözlemlediğim şey, GCC 4.4 ile derlediğimde liba'nın yüklü olduğunu, ancak GCC 4.5 ile derlediğim takdirde libb yüklü olmadığını görüyorum.

İki dosyadan oluşan küçük bir sınama durumum var: a.c ve b.c. Dosyaların içeriği:

//a.c 
int a(){ 
    return 0; 
} 

//b.c 
int b(){ 
    return 0; 
} 
//c.c 
#include <stdio.h> 
int a(); 
int b(); 

int main() 
{ 
    printf("%d\n", a()+b()); 
    return 0; 
} 
//test.sh  
$CC -o liba.so a.c -shared 
$CC -o libb.so b.c -shared -L. -la -Wl,-rpath-link . 
$CC c.c -L. -lb -Wl,-rpath-link . 
LD_LIBRARY_PATH=. ./a.out 

Bu GCC

farklı sürümleri ile benim çıkış
$ CC=gcc-4.4 ./test.sh 
1 
$ CC=gcc-4.5 ./test.sh 
/tmp/cceJhAqy.o: In function `main': 
c.c:(.text+0xf): undefined reference to `a' 
collect2: ld returned 1 exit status 
./test.sh: line 4: ./a.out: No such file or directory 
$ CC=gcc-4.6 ./test.sh 
/tmp/ccoovR0x.o: In function `main': 
c.c:(.text+0xf): undefined reference to `a' 
collect2: ld returned 1 exit status 
./test.sh: line 4: ./a.out: No such file or directory 
$ 

kimse neler olduğunu açıklayabilir mi? Bir başka fazladan bilgi, libb.so üzerindeki ldd'nin GCC 4.4 üzerinde değil, GCC 4.5 üzerinde liba.so göstermesidir.

$CC -shared -o liba.so a.c 
$CC -L. -Wl,--no-as-needed -Wl,--copy-dt-needed-entries -la -shared -o libb.so b.c -Wl,-rpath-link . 
$CC -L. c.c -lb -Wl,-rpath-link . 
LD_LIBRARY_PATH=. ./a.out 

Bu GCC 4.5 ile şu çıktıyı verdi:

DÜZENLEME

şuna test.sh değişti

/usr/bin/ld: /tmp/cc5IJ8Ks.o: undefined reference to symbol 'a' 
/usr/bin/ld: note: 'a' is defined in DSO ./liba.so so try adding it to the linker command line 
./liba.so: could not read symbols: Invalid operation 
collect2: ld returned 1 exit status 
./test.sh: line 4: ./a.out: No such file or directory 
+0

Benim yapım ortamı Debian 6.0 On Ubuntu 11.10 x86-64 –

+0

olduğunu.3, paketlenmiş GCC 4.4, örneği sorunsuz olarak ele alır. Paketlenmiş KİK 4.3, kayıp bir 'fPIC' bayrağı hakkında şikayet ediyor. –

cevap

11

görünüyor etmek olmuştur değişiklikler var ld tarafından bağlantı sırasında nasıl DT_NEEDED kitaplıkları tedavi edilir. İşte şimdiki man ld ilgili bölümü:

komut satırında belirtilen --copy-dt-needed-entries dinamik kütüphaneleri yinelemeli olmak çıkış ikili gerektirdiği sembolleri çözmek amacıyla, diğer kütüphanelere onların DT_NEEDED etiketlerini takip aranır olacak bulunmaktadır. varsayılan ayarıyla, onu izleyen dinamik kitaplıkların aranması, dinamik kitaplığın kendisiyle birlikte duracaktır. Sembolleri çözmek için DT_NEEDED bağlantı yok aktarılacaktır.

(--copy-dt-needed-entries bölümünün bir bölümü).

GCC 4.4 ile GCC 4.5 arasında bir süre (görünüşte, bazı referanslara bakın, here - gerçekten yetkili bir şey bulamıyor), varsayılan, yinelemeli aramadan, özyinelemeli aramaya (daha yeni biriyle göreceğiniz gibi) değiştirildi. GCC'lerde). Bu bağlayıcı ayarı gerçekten (en azından bir kısmını) konu ile olduğunu

$CC c.c -L. -lb -la -Wl,-rpath-link . 

kontrol edebilirsiniz:

Her durumda

, siz (ve olmalıdır) son bağlantı adımında liba belirterek düzeltebilirim sizin yeni derleyici ve bu komut satırı ile çalışan:

$CC c.c -L. -Wl,--copy-dt-needed-entries -lb -Wl,--no-copy-dt-needed-entries \ 
     -Wl,-rpath-link . 
+0

Bu çok iyi bir açıklama olabilir, ancak bayrakların eklenmesi sonucu değiştirmez. Ben hem libb.so oluştururken hem de cc –

+0

yapılarını eklerken bunları eklemeyi denedim. LD için benim sürümüm, GNU ld (Ubuntu için GNU Binutils) 2.21.53.20110810 –

+0

Bayraklar yalnızca son bağlantıda değil '.so' dosyalarını oluşturma. Her durumda, gerçek düzeltme yürütülebilir dosyanızı hem libb' ** hem de ** liba ile ilişkilendirmektir. (Ld 2.22'deyim.) – Mat

İlgili konular