Tautan statis fungsi pustaka bersama di gcc

141

Bagaimana cara menautkan fungsi pustaka bersama secara statis di gcc?

suresh
sumber
15
Apa yang Anda maksud dengan terhubung secara statis? Apakah Anda ingin executable Anda didistribusikan tanpa membutuhkan .so?
Emiliano

Jawaban:

109

Mengacu pada:

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

Anda memerlukan versi statis pustaka untuk menautkannya.

Perpustakaan bersama sebenarnya dapat dieksekusi dalam format khusus dengan titik masuk yang ditentukan (dan beberapa masalah pengalamatan lengket disertakan). Itu tidak memiliki semua informasi yang diperlukan untuk ditautkan secara statis.

Anda tidak dapat menautkan pustaka bersama secara statis (atau secara dinamis menautkan pustaka statis).

Bendera -staticakan memaksa linker untuk menggunakan pustaka statis (.a), bukan yang dibagikan (.so). Tetapi pustaka statis tidak selalu diinstal secara default, jadi Anda mungkin harus menginstal sendiri pustaka statis tersebut.

Pendekatan lain yang mungkin adalah menggunakan statifier atau Ermine . Kedua alat mengambil sebagai masukan yang dapat dieksekusi yang terhubung secara dinamis dan sebagai keluaran membuat eksekusi mandiri dengan semua pustaka bersama yang disematkan.

Sam Liao
sumber
12
Informasi apa yang dimiliki pustaka statis, sehingga bisa ditautkan secara statis, yang tidak dimiliki pustaka dinamis?
kbolino
76

Jika Anda ingin menautkan, katakanlah, libapplejuice secara statis, tetapi tidak, katakanlah, liborangejuice , Anda dapat menautkan seperti ini:

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

Ada peringatan - jika liborangejuicedigunakan libapplejuice, maka libapplejuiceakan ditautkan secara dinamis juga.

Anda harus menautkan liborangejuicesecara statis bersama dengan libapplejuiceuntuk menjadi libapplejuicestatis.

Dan jangan lupa untuk menyimpan -Wl,-Bdynamiclagi Anda akan berakhir dengan menautkan semua statis, termasuk libc(yang bukan hal yang baik untuk dilakukan).

Eugene Bujak
sumber
2
Adakah cara untuk memberi tahu gcc secara langsung apa yang harus ditautkan secara statis, dan tidak melewati dia dan berbicara dengan penaut?
Elazar Leibovich
1
@ElazarLeibovich Anda tidak bisa mendapatkan kombinasi statis dan dinamis seperti itu.
Haozhun
@EugeneBujak: Peringatan tidak berlaku di sistem saya. Contoh: gcc -o main main.cc -Wl,-rpath=. -Wl,-Bdynamic -lB -Wl,-Bstatic -lA -Wl,-Bdynamic -L. libB menggunakan libA , ia ditautkan dan lddtidak menunjukkan referensi ke libA . Eksekusi berfungsi dengan baik. Diuji dengan g ++ 4.7.3.
radix
Ketergantungan tidak langsung (bersarang), statis, langsung, dinamis, tidak dengan sendirinya menjadi terkait secara dinamis.
Vinny
Pertimbangkan hal berikut: binA bergantung pada libB.so yang bergantung pada libC.a Seperti yang telah dinyatakan orang lain, .so itu sendiri dapat dieksekusi, jadi ketika objek bersama ditautkan, semua dependensi pustaka statis diproses oleh linker sama seperti jika sebuah executable sedang ditautkan: satu-satunya simbol yang ditarik dari .a static lib adalah yang direferensikan (dan tidak terselesaikan) oleh .so. Ini berarti bahwa jika binA mereferensikan simbol di libC.a, tidak direferensikan di mana pun di libB.so, bahkan jika binA menautkan ke libB.so, simbol itu tidak akan ditentukan (kecuali -Wl, - seluruh arsip digunakan saat menautkan libB.so).
Vinny
18

Jika Anda memiliki file .a dari pustaka bersama (.so), Anda dapat memasukkannya dengan jalur lengkapnya seolah-olah itu adalah file objek, seperti ini:

Ini menghasilkan main.o hanya dengan mengkompilasi:

gcc -c main.c

Ini menautkan file objek tersebut dengan pustaka statis terkait dan membuat file yang dapat dieksekusi (bernama "main"):

gcc main.o mylibrary.a -o main

Atau dalam satu perintah:

gcc main.c mylibrary.a -o main

Ini juga bisa menjadi jalur absolut atau relatif:

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

Ya, saya tahu ini adalah pertanyaan berusia 8 tahun, tetapi saya diberi tahu bahwa adalah mungkin untuk menautkan secara statis ke pustaka objek bersama dan ini benar-benar menjadi yang teratas ketika saya mencari informasi lebih lanjut tentangnya.

Untuk benar-benar mendemonstrasikan bahwa menautkan pustaka objek bersama secara statis tidak dimungkinkan dengan ld( gcclinker) - berlawanan dengan hanya sekelompok orang yang bersikeras bahwa itu tidak mungkin - gunakan gccperintah berikut :

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

(Tentu saja Anda harus mengkompilasi objectname.odari sourcename.c, dan Anda mungkin juga harus membuat perpustakaan objek bersama Anda sendiri. Jika Anda melakukannya, gunakan -Wl,--library-path,.agar ld dapat menemukan perpustakaan Anda di direktori lokal.)

Kesalahan sebenarnya yang Anda terima adalah:

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

Semoga membantu.

Ian Moote
sumber
10

Agak terlambat tapi ... Saya menemukan tautan yang saya simpan beberapa tahun yang lalu dan saya pikir itu mungkin berguna untuk kalian:

CDE: Buat aplikasi Linux portabel secara otomatis

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

  • Cukup unduh programnya
  • Jalankan penerusan biner sebagai argumen nama biner yang ingin Anda jadikan portabel, misalnya: nmap

    ./cde_2011-08-15_64bit nmap

Program akan membaca semua lib yang terhubung ke nmap dan dependensinya dan akan menyimpan semuanya dalam folder bernama cde-package / (di direktori yang sama dengan Anda).

  • Terakhir, Anda dapat memampatkan folder dan menerapkan biner portabel di sistem apa pun.

Ingat, untuk meluncurkan program portabel Anda harus menjalankan biner yang terletak di cde-package / nmap.cde

salam Hormat

Francis
sumber
2
Meskipun tidak benar-benar memberikan jawaban atas pertanyaan - ini adalah solusi penting untuk masalah tersebut.
razong
Tautannya sepertinya sudah mati sekarang.
sinan
0

Di gcc, ini tidak didukung. Faktanya, ini tidak didukung di compiler / linker yang ada yang saya ketahui.

nothrow
sumber
4
Bisakah Anda menjelaskan bagaimana penautan statis tidak didukung oleh kompiler yang ada?
jww
5
@noloader, menghubungkan statis perpustakaan dinamis?
nothrow