Gcc'de paylaşılan kütüphane işlevinin statik bağlantısı


138

Paylaşılan kitaplık işlevini gcc'de statik olarak nasıl bağlayabilirim?


14
Statik bağlantılı ile ne demek istiyorsun? Yürütülebilir dosyanın .so gerekmeden dağıtılmasını ister misiniz?
Emiliano

Yanıtlar:


108

Bakınız:

http://www.linuxquestions.org/questions/linux-newbie-8/forcing-static-linking-of-shared-libraries-696714/

http://linux.derkeiler.com/Newsgroups/comp.os.linux.development.apps/2004-05/0436.html

Bağlamak için kütüphanenin statik sürümüne ihtiyacınız vardır.

Paylaşılan kitaplık aslında giriş noktaları belirtilmiş (ve bazı yapışkan adresleme sorunları dahil) özel bir biçimde yürütülebilir bir dosyadır. Statik olarak bağlanmak için gereken tüm bilgilere sahip değildir.

Paylaşılan bir kütüphaneyi statik olarak bağlayamazsınız (veya statik bir kütüphaneyi dinamik olarak bağlayamazsınız).

Bayrak -static, bağlayıcıyı paylaşılan (.so) yerine statik kitaplıklar (.a) kullanmaya zorlar. Ancak statik kitaplıklar her zaman varsayılan olarak yüklenmez, bu nedenle statik kitaplığı kendiniz yüklemeniz gerekebilir.

Olası başka bir yaklaşım, statifier veya Ermine kullanmaktır . Her iki araç da girdi olarak dinamik olarak bağlanmış bir yürütülebilir dosya alır ve çıktı da tüm paylaşılan kitaplıkların gömülü olduğu bağımsız bir yürütülebilir dosya oluşturur.


11
Statik kütüphanede, dinamik kütüphanede bulunmayan statik olarak bağlanabilmesi için hangi bilgiler bulunur?
kbolino

75

Bağlantıya, söz hakkından, isterseniz libapplejuice statik değil, diyelim ki, liborangejuice , böyle bağlayabilirsiniz:

gcc object1.o object2.o -Wl,-Bstatic -lapplejuice -Wl,-Bdynamic -lorangejuice -o binary

Bir uyarı var - liborangejuicekullanırsa libapplejuice, o libapplejuicezaman da dinamik olarak bağlanacaktır.

liborangejuiceStatik libapplejuiceolabilmek için libapplejuicestatik olarak yanınıza bağlamanız gerekir .

Ve bunu da -Wl,-Bdynamicdahil olmak üzere her şeyi statik olarak bağlayacaksınız libc(bunu yapmak iyi bir şey değildir).


2
Gcc'ye direk olarak neyin statik olarak bağlanacağını söylemenin ve onu atlamamanın ve bağlayıcıyla konuşmamasının bir yolu yok mu?
Elazar Leibovich

1
@ElazarLeibovich bu şekilde statik ve dinamik bir kombinasyon elde edemezsiniz.
Haozhun

@EugeneBujak: Uyarı benim sistemimde geçerli değil. Örnek: gcc -o main main.cc -Wl,-rpath=. -Wl,-Bdynamic -lB -Wl,-Bstatic -lA -Wl,-Bdynamic -L. libB kullanan LIBA , bağlandığı ve lddbir referans göstermez LIBA . Yürütülebilir dosya gayet iyi çalışıyor. G ++ 4.7.3 ile test edilmiştir.
radix

Doğrudan, dinamik, bağımlılığın dolaylı (iç içe), statik, bağımlılığı, dinamik olarak bağlanmaz.
Vinny

Aşağıdakileri göz önünde bulundurun: binA, libC'ye bağımlı libB.so'ya bağlıdır. Diğerlerinin de belirttiği gibi, .so'nun kendileri yürütülebilir, bu nedenle paylaşılan bir nesne bağlandığında, statik kitaplık bağımlıları, bağlayıcı tarafından sankiyle aynı şekilde işlenir. çalıştırılabilir bir dosya bağlanıyor: .a statik lib'den alınan semboller .so tarafından başvurulan (ve çözülmeyen) sembollerdir. Bu, binA'nın libC.a'da libB.so'da herhangi bir yere başvurulmayan bir sembole başvurması durumunda, binA libB.so'ya bağlansa bile bu sembolün tanımsız olacağı anlamına gelir (bağlama sırasında -Wl, - tüm arşiv kullanılır) libB.so).
Vinny

18

Paylaşılan kitaplığınızın (.so) .a dosyasına sahipseniz, dosyayı tam yoluna bir nesne dosyasıymış gibi ekleyebilirsiniz, örneğin:

Bu, main.o dosyasını yalnızca derleyerek oluşturur:

gcc -c main.c

Bu, nesne dosyasını ilgili statik kitaplıkla bağlar ve yürütülebilir dosyayı oluşturur ("main" olarak adlandırılır):

gcc main.o mylibrary.a -o main

Veya tek bir komutta:

gcc main.c mylibrary.a -o main

Ayrıca mutlak veya göreceli bir yol da olabilir:

gcc main.c /usr/local/mylibs/mylibrary.a -o main

12

Evet, bunun 8 yaşında bir soru olduğunu biliyorum, ancak paylaşılan bir nesne kütüphanesine statik olarak bağlamanın mümkün olduğu söylendi ve bu konuda daha fazla bilgi aradığımda tam anlamıyla en iyi hit oldu.

Bir paylaşımlı nesne kitaplığını statik olarak bağlamanın ld( gcc's bağlayıcı) ile mümkün olmadığını göstermek için - sadece mümkün olmadığında ısrar eden bir grup insanın aksine - aşağıdaki gcckomutu kullanın:

gcc -o executablename objectname.o -Wl,-Bstatic -l:libnamespec.so

(Tabii ki derlemek gerekecek objectname.odan sourcename.cve muhtemelen de kendi paylaşılan nesne kitaplığı oluşturan gerekir. Bunu yaparsanız, kullanım -Wl,--library-path,.o ld nedenle yerel dizinde kütüphanenizi bulabilirsiniz.)

Aldığınız asıl hata:

/usr/bin/ld: attempted static link of dynamic object `libnamespec.so'
collect2: error: ld returned 1 exit status

Umarım yardımcı olur.


10

Biraz geç ama ... Birkaç yıl önce kaydettiğim bir bağlantı buldum ve bunun sizin için yararlı olabileceğini düşündüm:

CDE: Otomatik olarak taşınabilir Linux uygulamaları oluşturun

http://www.pgbovine.net/cde.html

  • Sadece programı indirin
  • Taşınabilir geçiş yapmak istediğiniz ikilinin adını bağımsız değişken olarak ikili geçişi yürütün, örneğin: nmap

    ./cde_2011-08-15_64bit nmap

Program, nmap ve bağımlılarına bağlı tüm kütüphaneleri okuyacak ve hepsini cde-package / (aynı dizinde olduğunuz) bir klasöre kaydedecektir .

  • Son olarak, klasörü sıkıştırabilir ve taşınabilir ikili dosyayı hangi sisteme dağıtabilirsiniz.

Unutmayın, taşınabilir programı başlatmak için cde-package / nmap.cde dosyasında bulunan ikili dosyayı çalıştırmanız gerekir.

Saygılarımla


2
Sorunun cevabını tam olarak vermese de - soruna dikkate değer bir çözüm.
Razong

Bağlantı şimdi ölü gibi görünüyor.
sinan

0

Gcc'de bu desteklenmez. Aslında, bu, bildiğim mevcut herhangi bir derleyici / bağlayıcıda desteklenmiyor.


4
Statik bağlamanın mevcut herhangi bir derleyici tarafından nasıl desteklenmediğini açıklayabilir misiniz?
jww

5
@noloader, dinamik kitaplığın statik olarak bağlanması?
nothrow
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.