Anda mungkin juga perlu memastikan bahwa Anda tidak bergantung pada glibc dinamis. Jalankan ldd
pada hasil eksekusi Anda dan catat semua dependensi dinamis (libc/libm/libpthread adalah tersangka umum).
Latihan tambahan akan membangun banyak contoh C++ 11 yang terlibat menggunakan metodologi ini dan benar-benar mencoba binari yang dihasilkan pada sistem 10,04 nyata. Dalam kebanyakan kasus, kecuali jika Anda melakukan sesuatu yang aneh dengan pemuatan dinamis, Anda akan langsung tahu apakah program bekerja atau mogok.
Posting blog itu sangat tidak akurat.
Sejauh yang saya tahu, perubahan C++ ABI telah diperkenalkan dengan setiap rilis utama GCC (yaitu rilis dengan komponen nomor versi pertama atau kedua yang berbeda).
Tidak benar. Satu-satunya perubahan C++ ABI yang diperkenalkan sejak GCC 3.4 telah kompatibel dengan versi sebelumnya, artinya C++ ABI telah stabil selama hampir sembilan tahun.
Lebih buruk lagi, sebagian besar distribusi Linux utama menggunakan snapshot GCC dan/atau menambal versi GCC mereka, sehingga hampir tidak mungkin untuk mengetahui dengan pasti versi GCC apa yang mungkin Anda hadapi saat mendistribusikan binari.
Perbedaan antara versi GCC yang ditambal distribusi kecil, dan tidak mengubah ABI, mis. Fedora 4.6.3 20120306 (Red Hat 4.6.3-2) kompatibel dengan ABI dengan rilis upstream FSF 4.6.x dan hampir pasti dengan 4.6.x dari distro lainnya.
Pada pustaka runtime GNU/Linux GCC menggunakan versi simbol ELF sehingga mudah untuk memeriksa versi simbol yang diperlukan oleh objek dan pustaka, dan jika Anda memiliki libstdc++.so
yang memberikan simbol-simbol itu akan berfungsi, tidak masalah jika itu adalah versi tambalan yang sedikit berbeda dari versi lain distro Anda.
tetapi tidak ada kode C++ (atau kode apa pun yang menggunakan dukungan runtime C++) yang dapat ditautkan secara dinamis jika ingin berfungsi.
Ini juga tidak benar.
Artinya, menautkan secara statis ke libstdc++.a
adalah salah satu opsi untuk Anda.
Alasannya mungkin tidak berfungsi jika Anda memuat pustaka secara dinamis (menggunakan dlopen
) adalah simbol libstdc++ yang bergantung padanya mungkin tidak diperlukan oleh aplikasi Anda saat Anda (secara statis) menautkannya, jadi simbol tersebut tidak akan ada di file yang dapat dieksekusi. Itu dapat diselesaikan dengan menautkan perpustakaan bersama secara dinamis ke libstdc++.so
(yang merupakan hal yang benar untuk dilakukan jika tergantung padanya.) Penempatan simbol ELF berarti simbol yang ada di executable Anda akan digunakan oleh pustaka bersama, tetapi simbol lain yang tidak ada di executable Anda akan ditemukan di mana saja libstdc++.so
itu terhubung ke. Jika aplikasi Anda tidak menggunakan dlopen
Anda tidak perlu peduli tentang itu.
Opsi lain (dan yang saya sukai) adalah menerapkan libstdc++.so
yang lebih baru di samping aplikasi Anda dan pastikan itu ditemukan sebelum libstdc++.so
sistem default , yang dapat dilakukan dengan memaksa tautan dinamis untuk mencari di tempat yang tepat, baik menggunakan $LD_LIBRARY_PATH
variabel lingkungan saat run-time, atau dengan menyetel RPATH
di executable pada link-time. Saya lebih suka menggunakan RPATH
karena tidak bergantung pada lingkungan yang disetel dengan benar agar aplikasi berfungsi. Jika Anda menautkan aplikasi Anda dengan '-Wl,-rpath,$ORIGIN'
(perhatikan tanda kutip tunggal untuk mencegah shell mencoba memperluas $ORIGIN
) maka executable akan memiliki RPATH
dari $ORIGIN
yang memberi tahu tautan dinamis untuk mencari pustaka bersama di direktori yang sama dengan yang dapat dieksekusi itu sendiri. Jika Anda memasukkan libstdc++.so
yang lebih baru di direktori yang sama dengan executable itu akan ditemukan saat run-time, masalah terpecahkan. (Pilihan lain adalah meletakkan executable di /some/path/bin/
dan libstdc++.so yang lebih baru di /some/path/lib/
dan tautkan dengan '-Wl,-rpath,$ORIGIN/../lib'
atau lokasi tetap lainnya relatif terhadap yang dapat dieksekusi, dan setel RPATH relatif ke $ORIGIN
)
Satu tambahan untuk jawaban luar biasa Jonathan Wakely, mengapa dlopen() bermasalah:
Karena kumpulan penanganan pengecualian baru di GCC 5 (lihat PR 64535 dan PR 65434), jika Anda membuka dan menutup pustaka yang terhubung secara statis ke libstdc++, Anda akan mendapatkan kebocoran memori (dari objek kumpulan) setiap kali. Jadi jika ada kemungkinan Anda akan menggunakan dlopen, sepertinya ide yang sangat buruk untuk menautkan libstdc++ secara statis. Perhatikan bahwa ini adalah kebocoran nyata, bukan yang jinak yang disebutkan di PR 65434.