ar
Di Linux, ar
adalah pengarsip tujuan umum GNU. (Ada varian non-GNU ar
di OS mirip Unix lainnya). Dengan opsic
ar c... archive-name file...
Ini menciptakan arsip yang berisi salinan file...
. Secara archive-name
konvensional tetapi tidak harus memiliki ekstensi .a
(untuk arsip ). Masing file...
- masing dapat berupa file apa pun, tidak harus berupa file objek.
Ketika file yang diarsipkan adalah semua file objek, biasanya niat untuk menggunakan arsip untuk mengirimkan pilihan file objek ke dalam tautan program atau DSO (Dynamic Shared Objects). Dalam hal ini archive-name
juga akan secara konvensional diberikan awalan lib
, misalnya
libfoo.a
, sehingga dapat ditemukan sebagai file input calon linker melalui opsi linker -lfoo
.
Digunakan sebagai file input linker, libfoo.a
biasanya disebut perpustakaan statis . Penggunaan ini merupakan sumber kebingungan berkesinambungan bagi programmer yang tidak mahir, karena hal itu membuat mereka berpikir bahwa arsip libfoo.a
sama dengan DSO libfoo.so
, biasanya disebut perpustakaan dinamis / bersama , dan untuk membangun harapan yang salah atas dasar ini. Sebenarnya "perpustakaan statis" dan "perpustakaan dinamis" sama sekali tidak sama dan digunakan dalam hubungan dengan cara yang sangat berbeda.
Perbedaan mencolok adalah bahwa perpustakaan statis tidak diproduksi oleh linker , tetapi dengan ar
. Jadi tidak ada hubungan yang terjadi, tidak ada resolusi simbol yang terjadi. File objek yang diarsipkan tidak berubah: mereka hanya dimasukkan ke dalam tas.
Ketika sebuah arsip adalah masukan dalam keterkaitan sesuatu yang yang dihasilkan oleh linker - seperti program atau DSO - terlihat linker dalam tas untuk melihat apakah ada file objek di dalamnya yang memberikan definisi untuk referensi simbol terselesaikan yang masih harus dibayar sebelumnya dalam tautan. Jika menemukan apapun, ekstrak file-file objek dari tas dan link mereka ke dalam file output, persis seperti jika mereka diberi nama individual di commandline linker dan arsip tidak disebutkan sama sekali. Jadi seluruh peran arsip dalam tautan adalah sebagai sekumpulan file objek yang darinya tautan dapat memilih yang diperlukan untuk melanjutkan tautan tersebut.
Secara default, GNU ar
membuat arsip outputnya siap digunakan sebagai input linker. Itu menambahkan "file" palsu ke arsip, dengan nama file sihir palsu, dan dalam file palsu ini menulis konten yang bisa dibaca oleh linker sebagai tabel pencarian dari simbol global yang ditentukan oleh file objek apa pun dalam arsip. ke nama dan posisi file objek tersebut dalam arsip. Tabel pencarian inilah yang memungkinkan tautan untuk melihat dalam arsip dan mengidentifikasi file objek apa pun yang menentukan referensi simbol yang belum terselesaikan yang telah ada di tangannya.
Anda dapat menekan pembuatan atau memperbarui tabel pencarian ini dengan opsi q
(=
cepat ) - yang sebenarnya telah Anda gunakan dalam ar
contoh Anda sendiri - dan juga dengan opsi (modal) S
(= tidak ada tabel simbol ). Dan jika Anda memohon ar
untuk membuat atau memperbarui arsip yang tidak memiliki tabel simbol (uptodate) karena alasan apa pun, maka Anda dapat memberikannya dengan s
opsi.
ranlib
ranlib
tidak membuat perpustakaan sama sekali. Di Linux, ranlib
adalah program lawas yang menambahkan tabel simbol (uptodate) ke ar
arsip jika tidak ada. Efeknya persis sama dengan ar s
, dengan GNU ar
. Secara historis, sebelum ar
diperlengkapi untuk menghasilkan tabel simbol itu sendiri, ranlib
adalah kludge yang menyuntikkan file palsu sihir ke dalam arsip untuk memungkinkan linker untuk mengambil file objek dari itu. Dalam OS non-GNU Unix-like, ranlib
mungkin masih diperlukan untuk tujuan ini. Contoh Anda:
ar qc libgraphics.a *.o
ranlib libgraphics.a
mengatakan:
- Buat
libgraphics.a
dengan menambahkan arsip semua *.o
file di direktori saat ini, tanpa tabel simbol.
- Kemudian tambahkan tabel simbol ke
libgraphics.a
Di linux, ini memiliki efek bersih yang sama dengan:
ar cr libgraphics.a *.o
Dengan sendirinya,, ar qc libgraphics.a *.o
membuat arsip yang tidak dapat digunakan tautan, karena tidak memiliki tabel simbol.
ld
Contoh Anda:
ld -r -o libgraphics.a *.o
sebenarnya cukup ortodoks. Ini menggambarkan penggunaan cukup langka dari linker ,
ld
, untuk menghasilkan gabungan file objek dengan menghubungkan beberapa file masukan ke dalam file output objek tunggal, di mana resolusi simbol telah dilakukan sejauh mungkin , mengingat input file. Opsi -r
(= relocatable ) mengarahkan linker untuk menghasilkan target file objek (bukan program, atau DSO) dengan menghubungkan input sejauh mungkin dan tidak gagal linkaqe jika referensi simbol yang tidak ditentukan tetap di file output. Penggunaan ini disebut penautan parsial .
File output ld -r ...
adalah file objek, bukan ar
arsip , dan menentukan nama file output yang terlihat seperti ar
arsip tidak membuatnya menjadi satu. Jadi contoh Anda menggambarkan penipuan. Ini:
ld -r -o graphics.o *.o
akan jujur. Tidak jelas bagi saya apa tujuan penipuan semacam itu, karena bahkan jika file objek ELF dipanggil libgraphics.a
, dan merupakan input ke tautan baik dengan nama itu, atau oleh -lgraphics
, linker akan dengan benar mengidentifikasi itu sebagai file objek ELF , bukan ar
arsip, dan akan mengonsumsinya dengan cara ia menggunakan file objek apa pun di commandline: itu menghubungkannya tanpa syarat ke file output, sedangkan titik memasukkan arsip asli adalah untuk menautkan anggota arsip hanya dengan menautkan anggota arsip hanya dengan syarat bahwa mereka direferensikan . Mungkin Anda hanya memiliki contoh tautan yang kurang informasi di sini.
Membungkus...
Kami sebenarnya hanya melihat satu cara menghasilkan sesuatu yang secara konvensional disebut perpustakaan , dan itulah produksi yang disebut perpustakaan statis , dengan mengarsipkan beberapa file objek dan meletakkan tabel simbol dalam arsip.
Dan kita belum melihat sama sekali bagaimana menghasilkan hal lain dan yang paling penting yang secara konvensional disebut perpustakaan , yaitu Dynamic Shared Object / shared library / dynamic library.
Seperti sebuah program, DSO diproduksi oleh tautan . Sebuah program dan DSO adalah varian binari ELF yang dipahami oleh pemuat OS dan dapat digunakan untuk merakit proses yang sedang berjalan. Biasanya kita memanggil linker melalui salah satu salah satu frontends GCC ( gcc
, g++
, gfortran
, dll):
Menautkan suatu program:
gcc -o prog file.o ... -Ldir ... -lfoo ...
Menautkan DSO:
gcc -shared -o libbar.so file.o ... -Ldir ... -lfoo ...
Baik pustaka bersama dan pustaka statis dapat ditawarkan ke tautan dengan -lfoo
protokol seragam , saat Anda menautkan beberapa program atau DSO lainnya. Opsi itu mengarahkan tautan untuk memindai direktori pencarian yang ditentukan atau default untuk menemukan salah satu
libfoo.so
atau libfoo.a
. Secara default, setelah menemukan salah satu dari mereka itu akan memasukkan file itu ke tautan, dan jika menemukan keduanya di direktori pencarian yang sama, itu akan lebih disukai libfoo.so
. Jika libfoo.so
, dipilih maka penghubung menambahkan DSO ke daftar ketergantungan runtime dari program atau DSO apa pun yang Anda buat. Jika libfoo.a
dipilih maka linker menggunakan arsip sebagai pilihan file objek untuk linkage ke file output, jika diperlukan, di sana dan kemudian. Tidak ada ketergantungan runtime aktif
libfoo.a
itu sendiri mungkin; itu tidak dapat dipetakan ke dalam suatu proses; itu tidak ada artinya bagi pemuat OS.
Disalin dari https://stackoverflow.com/a/47924864/195787 .