Bagaimana saya bisa tahu dengan pasti apa yang digunakan pengguna C library yang digunakan sistem saya? Kemungkinan alasan untuk memerlukan informasi ini meliputi:
Ada paket sumber raksasa yang saya pertimbangkan untuk diunduh yang saya yakin akan melakukan pemeriksaan yang tepat dan mencantumkan versi pustaka mininum, tetapi saya lebih suka menghemat kerumitan dengan memeriksa dulu apakah itu akan berhasil.
Saya khawatir tentang kompatibilitas ABI dengan beberapa binari pihak ketiga yang ingin saya coba dan instal di luar sistem manajemen paket sistem.
Saya memiliki paket sumber yang dokumentasinya menyebutkan perlunya versi minimum dari pustaka sistem saya, tetapi proses pembuatannya tidak melakukan pemeriksaan apa pun.
Saya membangun kompilator silang yang menargetkan sistem tertentu dan tidak ingin mengambil risiko masalah kompatibilitas .
sumber
ldd
. Saya tidak yakin apakahotool --version
dapat dianggap memberikan informasi yang sama.Jawaban:
Sistem GNU / Linux biasanya menggunakan glibc (keluarga Fedora / Redhat, Arch) atau sepupu dekatnya, eglibc (keluarga Debian / Ubuntu); karena eglibc sekarang sedang digabungkan kembali ke glibc ( lihat EGLIBC 2.19 Cabang Dibuat di bawah "Berita" ), dalam waktu dekat mereka semua akan glibc lagi.
Cara termudah untuk memeriksa versi pastinya adalah dengan bertanya
ldd
, yang dikirimkan dengan pustaka C.Pada Fedora 20:
Itu glibc 2.18.
Di Raspbian (port Debian 7 untuk ARMv6 Broadcom SoC):
Itu eglibc 2.13.
Jika karena alasan apa pun Anda telah mencampur dan mencocokkan beberapa bagian atau sebaliknya tidak yakin
ldd
, Anda dapat meminta pustaka C secara langsung.Tidak ada yang dapat dieksekusi tetapi mereka memberikan petunjuk tentang di mana menemukannya.
Namun, itu tidak selalu begitu mudah, karena perpustakaan C tidak harus berada di suatu tempat
whereis
dapat menemukannya.Sayangnya, halaman manual tidak memberikan nomor versi.
ldd
masih sangat berguna, karena semua yang dapat dijalankan, yang dapat dieksekusi secara dinamis dapat dieksekusi pada sistem (mis., hampir semua yang ada di dalamnya/usr/bin
) akan terhubung ke pustaka C.libc.so.6
ada di baris ketiga.sumber
/lib/`uname -m`*
path. Jadi cara yang portabel akan menjadi:find /lib/`uname -m`* /usr/lib* -executable -name "*libc.so*" | xargs --version
. Terima kasih untuk penjelasannya.Sistem sebenarnya tidak terbatas pada satu pustaka C. Namun, sebagian besar hanya menggunakan satu, yang juga akan menjadi salah satu yang digunakan kompiler default. Dan karena Anda mengunduh kode sumber untuk dikompilasi, itu yang menjadi perhatian Anda.
Mulai dengan program sepele:
kompilasi menggunakan kompiler yang akan Anda gunakan untuk kode sumber, lalu gunakan
ldd
untuk mencari tahu di mana pustaka C:Anda sekarang memiliki jalur ke perpustakaan C. Anda bisa mencari ini di manajer paket Anda untuk menemukan paket (misalnya,
dpkg -S /lib/x86_64-linux-gnu/libc.so.6
ataurpm -q -f /lib/x86_64-linux-gnu/libc.so.6
).Setidaknya dalam kasus eglibc / glibc, Anda dapat menjalankannya:
Akhirnya, Anda bisa melihat apakah Anda bisa mendapatkan petunjuk
objdump -p /lib/x86_64-linux-gnu/libc.so.6
, dengan melihat di bagian definisi versi :Perhatikan bagaimana simbol GLIBC_2.18 memiliki nomor versi terbaru di antara simbol yang terdaftar, dan versi pustaka memang 2,18. Ini eglibc, meskipun (ini bertujuan agar kompatibel dengan biner dengan glibc 2.18, jadi ia menggunakan versi simbol yang sama).
Anda juga dapat mencoba menggunakannya
strings
untuk menemukan sesuatu tentang itu. Anda ingin menentukan panjang minimal yang lebih panjang (-n
), atau menggunakan grep untuk mencari sesuatu:keduanya bekerja untuk eglibc ini.
CATATAN: Utilitas paket Debian
dpkg-shlibdeps
menggunakan diobjdump
bawah tenda, bersama dengan informasi simbol yang tersimpan dalam paket perpustakaan Debian untuk menentukan versi minimum dependensi yang diperlukan oleh paket biner Debian pada waktu pembuatan. Pada dasarnya, ini terlihat pada simbol yang diekspor oleh paket biner Debian, dan kemudian menemukan versi minimum dari pustaka yang berisi simbol-simbol tersebut.sumber
Jawaban yang jelas, meskipun bukan yang paling komprehensif, adalah memeriksa manajer paket Anda, mis
(Sedihnya, glibc tidak memiliki
.pc
file pkconfig , begitupkgconfig --modversion glibc
juga non-runner.) Lihat jugagetconf
saran luar biasa @ Gnouc .Kasus paling sederhana, dengan gcc + glibc, dan yang paling sering saya gunakan pertama adalah dengan mengeksekusi
libc.so
, seperti yang dijelaskan dalam beberapa jawaban lain di sini. Tidak perlu melewati argumen apa pun, itu mengeluarkan versinya secara default. Ini berfungsi sejauh glibc-2.1 (glibc-2.0 seg-faults, meskipun saat itu Anda dapat memeriksaglibcbug
skrip (sekarang sudah pensiun) untuk mengonfirmasi versi). Metode ini juga berfungsi dengan versi musl -libc ( > 0.9.15) terbaru (yang baru berjalan 1.0 hari ini, 20 Maret). Itu tidak bekerja dengan uClibc, itu segfaults.Salah satu cara sederhana untuk mengetahui dengan pasti apa
gcc
yang akan Anda lakukan adalah mengkompilasi:(dengan glibc,
<stdio.h>
termasuk<features.h>
yang mendefinisikan makro GLIBC yang relevan, Anda perlu<gnu/libc-version.h>
deklarasi fungsi.)Ini menangkap kasus yang lebih rumit (multiple libc's, dan / atau multiple compiler), dengan asumsi Anda menggunakan kompiler yang tepat (dan flag) tentu saja. (Saya menduga itu tidak akan membedakan antara eglibc dan glibc yang tepat.)
Jika Anda yakin Anda menggunakan glibc (atau eglibc) maka(maaf, ini tidak benar).ld
juga akan mengkonfirmasi versiJika
__GNU_LIBRARY__
tidak didefinisikan Anda akan mendapatkan kesalahan, maka sudah saatnya untuk rencana B.gcc -dumpmachine
dapat membantu, misalnya untuk uclibc-uclibc
, suffix memiliki akhirangcc -dumpspecs | grep dynamic-linker
. Ini juga dapat menyiratkan ABI.gcc -print-file-name=libc.so
akan memberi tahu Anda file apa yang akan digunakan kompiler untuk "-lc
", ini hampir pasti merupakan skrip-tautan di dalam instalasi gcc Anda, yang dapat Anda baca sebagai teks biasa. Itu akan menunjukkan jalur yang tepat kelibc.so
. Ini juga akan berfungsi jika Anda memberikan tanda suka-m32
atau-m64
.Jika Anda menggunakan uclibc (seperti yang digunakan oleh OpenWRT dan lainnya), ia mendefinisikan
__UCLIBC_MAJOR__
,__UCLIBC_MINOR__
dan__UCLIBC_SUBLEVEL__
juga__UCLIBC__
dalam<features.h>
, sehingga mudah dideteksi menggunakan variasi kecil pada cuplikan kode C di atas. Demi kompatibilitas, uClibc juga dapat mendefinisikan makro GNU / GLIBC seperti yang digunakan di atas, saat ini berpura-pura menjadi glibc-2.2. Ini saat ini tidak melaksanakangnu_get_libc_X()
fungsi, tetapi tidak melaksanakangetconf
yang juga dapat menyesatkan (saya menduga itu mengembalikan jawaban kosong untukgetconf GNU_LIBC_VERSION
, saya membangun env yang merajuk hari ini jadi saya tidak bisa mengkonfirmasi.)Jika Anda menggunakan dietlibc , menjalankan
diet -v
akan menampilkan versi.(FWIW, selama beberapa tahun dengan perangkat lunak menggunakan autoconf, saya punya lebih banyak masalah dengan uncheck-for
gcc
dang++
persyaratan daripada dengan diperiksa-untuk fitur glibc.)sumber
GNU libc (apa yang digunakan sebagian besar distribusi Linux dalam satu bentuk atau yang lain) berusaha keras untuk menjaga kompatibilitas mundur. Jadi, Anda harus mengalami masalah hanya jika Anda mencoba menjalankan biner yang terlalu baru pada versi lama (atau distribusi "perusahaan", mereka biasanya membekukan versi, terutama yang dasar seperti perpustakaan C, perbaikan backporting sambil menjaga kompatibilitas biner yang merusak) . Saya percaya Anda jauh lebih mungkin mengalami masalah dengan perpustakaan lain (C ++ memiliki beberapa perubahan API / ABI dalam memori baru-baru ini, beberapa perpustakaan lain hanya tidak peduli untuk kompatibilitas ke belakang).
Sedihnya, satu-satunya cara untuk mengetahui dengan pasti adalah dengan mencoba.
sumber
(Ini pada dasarnya sama dengan jawaban goldilocks tetapi dengan penjelasan lebih lanjut tentang apa yang terjadi di bawah tenda.)
Pustaka bersama inti untuk GNU libc,
libc.so.6
(di Linux; Hurd memiliki SONAME berbeda), memiliki properti yang tidak biasa (untuk pustaka bersama) yang dapat Anda gunakan sebagai executable. Jika ya, itu akan mencetak hal-hal yang biasanya dicetak oleh utilitas GNU ketika dijalankan--version
, seperti ini:Tapi tentu saja direktori tempat
libc.so.6
tinggal tidak ada$PATH
, jadi Anda harus tahu di mana mencarinya. Mungkin di/lib
,/lib64
,/usr/lib
, atau sesuatu yang bahkan wackier (seperti dalam kasus ini). Dengan mudah,ldd
akan memberi tahu Anda:Agar itu berfungsi, tentu saja, Anda harus mengetahui pathname lengkap dari eksekusi biner yang terhubung secara dinamis. Dapat
sh
dieksekusi dijamin berada di/bin
(karena begitu banyak#!
skrip mengharapkannya), dan tidak dapat dengan sendirinya menjadi#!
skrip. Ini bisa menjadi statis terkait, tapi saya belum menemukan sebuah sistem yang melakukan itu bertahun-tahun.Saya tidak tahu apa yang Anda lakukan jika Anda menggunakan uClibc atau musl atau sesuatu yang lebih eksotis.
sumber
$ ldd $(which sh) | grep libc
. : DCara lain untuk mendapatkannya:
sumber