Bagaimana cara saya menautkan secara statis beberapa pustaka tertentu ke biner saya saat menautkan dengan GCC?
gcc ... -static ...
mencoba untuk secara statis menautkan semua pustaka yang ditautkan, tetapi saya belum mendapatkan versi statis dari beberapa di antaranya (misalnya: libX11).
gcc
linker
static-libraries
peoro
sumber
sumber
Jawaban:
gcc -lsome_dynamic_lib code.c some_static_lib.a
sumber
code.c
file menjamin bahwa simbol di dalamnya akan diabaikan kecuali kebetulan ada sebuahmain()
fungsi dalam salah satu file perpustakaan objek.Anda juga bisa menggunakan
ld
opsi-Bdynamic
Semua perpustakaan setelahnya (termasuk yang ditautkan oleh gcc secara otomatis) akan ditautkan secara dinamis.
sumber
Anda juga dapat menggunakan:
-static-libgcc -static-libstdc++
flags untuk pustaka gccperlu diingat bahwa jika
libs1.so
danlibs1.a
keduanya ada, penaut akan memilihlibs1.so
sebelum-Wl,-Bstatic
atau sesudah-Wl,-Bdynamic
. Jangan lupa untuk lulus-L/libs1-library-location/
sebelum menelepon-ls1
.sumber
-static
suatu tempat di perintah gagal (saya berasumsi itu mencoba untuk menghubungkan lebih banyak hal secara statis daripada hanya perpustakaan yang saya inginkan).-Wl,-Bstatic
dan-Wl,-Bdynamic
penting.Dari halaman manual
ld
(ini tidak bekerja dengan gcc), mengacu pada--static
opsi:Salah satu solusinya adalah meletakkan dependensi dinamis Anda sebelum
--static
opsi pada baris perintah.Kemungkinan lain adalah untuk tidak menggunakan
--static
, tetapi sebaliknya memberikan nama file / jalur lengkap dari file objek statis (yaitu tidak menggunakan opsi -l) untuk menghubungkan secara statis ke perpustakaan tertentu. Contoh:Seperti yang Anda lihat di contoh,
libX11
tidak ada dalam daftar pustaka yang ditautkan secara dinamis, karena ditautkan secara statis.Hati-hati:
.so
File selalu ditautkan secara dinamis, bahkan ketika ditentukan dengan nama file / jalur lengkap.sumber
ldd a.out
?ldd
mengeluarkan pustaka bersama yang diperlukan dan libX11 tidak muncul di daftar itu.Masalah yang saya pahami adalah sebagai berikut. Anda memiliki beberapa perpustakaan, beberapa statis, beberapa dinamis dan beberapa statis dan dinamis. Perilaku default gcc adalah menghubungkan "sebagian besar dinamis". Artinya, gcc menautkan ke pustaka dinamis jika memungkinkan, tetapi sebaliknya kembali ke pustaka statis. Saat Anda menggunakan opsi -static untuk meng - gcc , perilakunya adalah hanya menautkan pustaka statis dan keluar dengan kesalahan jika tidak ada pustaka statis yang dapat ditemukan, bahkan jika ada pustaka dinamis yang sesuai.
Pilihan lain, yang beberapa kali saya harapkan dari gcc , adalah apa yang saya sebut -mostly-static dan pada dasarnya kebalikan dari -dynamic (default). -mostly-static akan, jika ada, lebih memilih untuk menautkan ke pustaka statis tetapi akan kembali ke pustaka dinamis.
Opsi ini tidak ada tetapi dapat diemulasikan dengan algoritme berikut:
Membangun baris perintah tautan tanpa menyertakan -static .
Ulangi opsi tautan dinamis.
Akumulasi jalur perpustakaan, yaitu opsi-opsi dalam bentuk -L <lib_dir> dalam variabel <lib_path>
Untuk setiap opsi tautan dinamis, yaitu yang berformat -l <lib_name> , jalankan perintah gcc <lib_path> -print-file-name = lib <lib_name> .a dan tangkap hasilnya.
Jika perintah mencetak sesuatu selain yang Anda berikan, itu akan menjadi jalur lengkap ke pustaka statis. Ganti opsi perpustakaan dinamis dengan jalur lengkap ke perpustakaan statis.
Bilas dan ulangi sampai Anda memproses seluruh baris perintah tautan. Secara opsional, skrip juga dapat mengambil daftar nama pustaka untuk dikecualikan dari penautan statis.
Skrip bash berikut tampaknya melakukan triknya:
Sebagai contoh:
saat sistem saya kembali:
atau dengan pengecualian:
Saya kemudian mendapatkan:
sumber
Ada juga
-l:libstatic1.a
varian (minus l titik dua) opsi -l di gcc yang dapat digunakan untuk menghubungkan pustaka statis (Terima kasih kepada https://stackoverflow.com/a/20728782 ). Apakah itu didokumentasikan? Tidak ada dalam dokumentasi resmi gcc (yang juga tidak persis untuk perpustakaan bersama): https://gcc.gnu.org/onlinedocs/gcc/Link-Options.htmlDoc binutils ld menjelaskannya. The
-lname
pilihan akan melakukan pencarian untuklibname.so
kemudian untuklibname.a
menambahkan awalan lib dan.so
(jika diaktifkan pada saat ini) atau.a
akhiran. Tetapi-l:name
opsi hanya akan mencari persis untuk nama yang ditentukan: https://sourceware.org/binutils/docs/ld/Options.htmlVarian
-l:namespec
ini didokumentasikan sejak versi 2.18 binutils (2007): https://sourceware.org/binutils/docs-2.18/ld/Options.htmlsumber
Beberapa loader (penaut) menyediakan sakelar untuk menghidupkan dan mematikan pemuatan dinamis. Jika GCC dijalankan pada sistem seperti itu (Solaris - dan mungkin lainnya), maka Anda dapat menggunakan opsi yang relevan.
Jika Anda tahu perpustakaan mana yang ingin Anda tautkan secara statis, Anda cukup menentukan file perpustakaan statis di baris tautan - dengan jalur lengkap.
sumber
untuk menghubungkan pustaka dinamis dan pustaka statis dalam satu baris, Anda harus meletakkan pustaka statis setelah berkas libs dan objek dinamis, seperti ini:
gcc -lssl main.o -lFooLib -o main
jika tidak, itu tidak akan berhasil. Aku butuh waktu untuk mengetahuinya.
sumber