Apakah program kecil, sangat sederhana yang dapat dieksekusi, seperti yang ditunjukkan di bawah ini, yang dikompilasi pada satu rasa Linux berjalan pada rasa yang berbeda? Atau apakah perlu dikompilasi ulang?
Apakah arsitektur mesin penting dalam kasus seperti ini?
int main()
{
return (99);
}
glibc
sana, atau sebaliknya. Memang, itu tidak sepenuhnya mustahil .gcc -m32 -static
). Dengan melakukan hal itu, Linux i386 atau amd64 apa pun dapat menjalankan executable.Jawaban:
Tergantung. Sesuatu yang dikompilasi untuk IA-32 (Intel 32-bit) dapat berjalan pada amd64 karena Linux pada Intel mempertahankan kompatibilitas mundur dengan aplikasi 32-bit (dengan perangkat lunak yang sesuai diinstal). Ini adalah
code
kompilasi Anda pada sistem RedHat 7.3 32-bit (sekitar 2002, gcc versi 2.96) dan kemudian biner disalin ke dan dijalankan pada sistem Centos 7.4 64-bit (sekitar 2017):RedHat Kuno 7,3 hingga Centos 7.4 (pada dasarnya RedHat Enterprise Linux 7.4) tetap dalam keluarga "distribusi" yang sama, sehingga kemungkinan akan memiliki portabilitas yang lebih baik daripada menginstal dari beberapa "Linux dari awal" instal dari 2002 ke beberapa distribusi Linux acak lainnya pada 2018 .
Sesuatu yang dikompilasi untuk amd64 tidak akan berjalan pada rilis Linux 32-bit saja (perangkat keras lama tidak tahu tentang perangkat keras baru). Ini juga berlaku untuk perangkat lunak baru yang dikompilasi pada sistem modern yang dimaksudkan untuk dijalankan pada hal-hal lama kuno, karena perpustakaan dan bahkan panggilan sistem mungkin tidak mundur portabel, sehingga mungkin memerlukan trik kompilasi, atau mendapatkan kompiler lama dan sebagainya, atau mungkin sebaliknya kompilasi pada sistem lama. (Ini adalah alasan yang baik untuk menjaga mesin virtual dari barang-barang tua kuno di sekitar.)
Arsitektur memang penting; amd64 (atau IA-32) sangat berbeda dari ARM atau MIPS sehingga biner dari salah satu dari mereka tidak akan diharapkan untuk dijalankan pada yang lain. Pada tingkat perakitan,
main
bagian kode Anda pada IA-32 mengkompilasi melaluigcc -S code.c
kedimana sistem amd64 dapat menangani (pada sistem Linux - OpenBSD sebaliknya pada amd64 tidak mendukung binari 32-bit; kompatibilitas ke belakang dengan lengkungan lama memang memberi ruang gerak penyerang ruang gerak, misalnya CVE-2014-8866 dan teman-teman). Sementara itu pada sistem MIPS big-endian
main
bukannya mengkompilasi ke:dimana prosesor Intel tidak akan tahu harus melakukan apa, dan juga untuk perakitan Intel pada MIPS.
Anda mungkin dapat menggunakan QEMU atau emulator lain untuk menjalankan kode asing (mungkin sangat, sangat lambat).
Namun! Kode Anda adalah kode yang sangat sederhana, sehingga akan memiliki masalah portabilitas lebih sedikit daripada yang lain; program biasanya menggunakan perpustakaan yang telah berubah dari waktu ke waktu (glibc, openssl, ...); untuk yang satu mungkin juga perlu menginstal versi lama dari berbagai pustaka (RedHat misalnya biasanya menempatkan "compat" di suatu tempat dalam nama paket untuk itu)
atau mungkin khawatir tentang perubahan ABI (Application Binary Interface) untuk hal-hal lama yang menggunakan glibc, atau perubahan yang lebih baru karena C ++ 11 atau rilis C ++ lainnya. Kita juga dapat mengkompilasi statis (sangat meningkatkan ukuran biner pada disk) untuk mencoba menghindari masalah pustaka, meskipun apakah beberapa biner lama melakukan ini tergantung pada apakah distribusi Linux lama mengkompilasi sebagian besar semuanya dinamis (RedHat: ya) atau tidak. Di sisi lain, hal-hal seperti
patchelf
dapat rejigger dinamis (ELF, tetapi mungkin tidaka.out
memformat) biner untuk menggunakan perpustakaan lain.Namun! Mampu menjalankan suatu program adalah satu hal, dan benar-benar melakukan sesuatu yang bermanfaat dengannya. Binari Intel 32-bit yang lama mungkin memiliki masalah keamanan jika mereka bergantung pada versi OpenSSL yang memiliki beberapa masalah keamanan yang mengerikan dan tidak di-backport di dalamnya, atau program mungkin tidak dapat bernegosiasi sama sekali dengan server web modern (seperti yang modern server menolak protokol dan sandi lama dari program lama), atau protokol SSH versi 1 tidak lagi didukung, atau ...
sumber
for GNU/Linux 2.6.32
(atau semacamnya) di output darifile /usr/bin/ls
.Singkatnya: Jika Anda membawa biner yang dikompilasi dari satu host ke host lain menggunakan arsitektur yang sama (atau yang kompatibel) , Anda mungkin akan membawanya ke distribusi lain . Namun seiring meningkatnya kompleksitas kode, kemungkinan tertaut dengan pustaka yang tidak diinstal; dipasang di lokasi lain; atau diinstal pada versi yang berbeda, meningkat. Misalnya, mengambil kode Anda, yang
ldd
melaporkan dependensi berikut ketika dikompilasi dengangcc -o exit-test exit-test.c
host Linux Ubuntu (berasal dari Debian):Jelas biner ini tidak akan berjalan jika saya menendang ke, katakanlah, Mac (
./exit-test: cannot execute binary file: Exec format error
). Mari kita coba memindahkannya ke kotak RHEL:Oh sayang. Kenapa ini bisa terjadi?
Bahkan untuk kasus penggunaan ini, forklifting gagal karena tidak ada perpustakaan bersama.
Namun, jika saya mengompilasinya
gcc -static exit-test-static exit-test.c
, porting ke sistem tanpa pustaka berfungsi dengan baik. Dengan mengorbankan, tentu saja, ruang disk:Solusi lain yang layak adalah dengan menginstal pustaka yang diperlukan pada host baru.
Seperti banyak hal di alam semesta U&L, ini adalah kucing dengan banyak kulit, dua di antaranya diuraikan di atas.
sumber
amd64
biner dan menjalankannya padaamd64
distribusi lain , atau membanguni386
biner dan menjalankannya padai386
distribusi lain .Menambahkan ke jawaban @thrig dan @DopeGhoti yang sangat baik: OS Unix atau Unix-like, termasuk Linux, secara tradisional selalu dirancang dan diselaraskan lebih untuk portabilitas kode sumber daripada binari.
Jika tidak memiliki perangkat keras khusus atau menjadi sumber sederhana seperti dalam contoh Anda, Anda dapat memindahkannya tanpa masalah sama sekali dari antara hampir semua versi Linux atau arsitektur sebagai kode sumber selama server tujuan menginstal paket pengembangan C , pustaka yang diperlukan, dan pustaka pengembangan terkait yang diinstal.
Sejauh porting kode lebih lanjut dari versi lama Linux dalam waktu yang lama, atau program yang lebih spesifik seperti modul kernel untuk versi kernel yang berbeda, Anda mungkin harus menyesuaikan dan memodifikasi kode sumber ke akun untuk pustaka / API / ABI yang sudah usang.
sumber
Secara default , Anda hampir pasti akan mengalami masalah dengan perpustakaan eksternal. Beberapa jawaban lain menjelaskan lebih detail tentang masalah-masalah itu, jadi saya tidak akan menduplikasi pekerjaan mereka.
Anda dapat , bagaimanapun, mengkompilasi banyak program - bahkan yang non-sepele - menjadi portabel di antara sistem Linux. Kuncinya adalah toolkit yang disebut Basis Standar Linux . The LSB dirancang untuk menciptakan hanya jenis aplikasi portabel. Kompilasi aplikasi untuk LSB v5.0 dan itu akan berjalan di lingkungan Linux lainnya (dengan arsitektur yang sama) yang mengimplementasikan LSB v5.0. Beberapa distro Linux sesuai dengan LSB, dan yang lain menyertakan LSB toolkit / pustaka sebagai paket yang dapat diinstal. Jika Anda membuat aplikasi menggunakan alat LSB (seperti
lsbcc
pembungkus untukgcc
) dan menautkan ke perpustakaan versi LSB, Anda akan membuat aplikasi portabel.sumber
qemu
Anda bahkan dapat menjalankan program yang dikompilasi untuk arsitektur yang berbeda, (tidak berkinerja tinggi, tetapi Anda dapat menjalankannya)apt-get install
beberapa paket.Mungkin.
Hal-hal yang cenderung merusaknya termasuk.
Jika Anda menghindari menggunakan perpustakaan yang cepat berubah, hindari perubahan arsitektur dan bangun di distro tertua yang ingin Anda targetkan. Anda memiliki peluang bagus untuk membuat satu karya biner di banyak distro.
sumber
Selain beberapa hal yang disebutkan sebelumnya, ada beberapa perubahan dalam format file yang dapat dieksekusi. Untuk sebagian besar, linux menggunakan ELF, tetapi versi yang lebih lama menggunakan a.out atau COFF.
Awal dari wikihole:
https://en.wikipedia.org/wiki/Comparison_of_executable_file_formats
Mungkin ada cara untuk mendapatkan versi yang lebih lama untuk menjalankan format yang lebih baru, tetapi saya pribadi tidak pernah melihatnya.
sumber