Apa faktor sosial atau teknis yang menyebabkan munculnya mentalitas CIY?
Akar penyebabnya jelas alasan teknisnya: Biner-portabilitas lebih sulit daripada portabilitas-sumber . Di luar paket-paket distro, sebagian besar perangkat lunak Gratis masih hanya tersedia dalam bentuk sumber karena itu jauh lebih nyaman bagi penulis / pengelola.
Sampai distro Linux mulai mengemas sebagian besar hal yang ingin digunakan kebanyakan orang, satu-satunya pilihan Anda adalah mendapatkan sumber dan mengompilasinya untuk sistem Anda sendiri. Vendor Unix Komersial biasanya tidak menyertakan hal-hal yang diinginkan hampir semua orang (mis. Shell yang bagus seperti GNU bash
atau sejenisnya), hanya implementasi mereka sendiri sh
dan / atau csh
, jadi Anda perlu membuat sendiri barang-barang jika Anda (sebagai sys-admin) ingin untuk memberikan lingkungan Unix yang bagus kepada pengguna Anda untuk penggunaan interaktif.
Situasi sekarang, dengan kebanyakan orang menjadi satu-satunya admin dan satu-satunya pengguna mesin yang duduk di desktop mereka, sangat berbeda dari model Unix tradisional. Sysadmin memelihara perangkat lunak pada sistem pusat, dan pada desktop semua orang. (Seringkali dengan memiliki workstation orang hanya NFS-mount /opt
dan /usr/local/
dari server pusat, dan menginstal barang di sana.)
Sebelum hal-hal seperti .NET dan Java, portabilitas biner sejati di berbagai arsitektur CPU tidak mungkin. Budaya Unix berevolusi dengan portabilitas sumber sebagai default untuk alasan ini, dengan sedikit upaya untuk mencoba mengaktifkan portabilitas biner hingga upaya Linux baru-baru ini seperti LSB. Sebagai contoh, POSIX ( yang standar Unix utama) hanya mencoba untuk standarisasi sumber-portabilitas, bahkan dalam versi terbaru.
Faktor budaya terkait: AT&T komersial awal Unix datang dengan kode sumber (pada kaset). Anda tidak perlu membangun sistem dari sumber, itu hanya ada jika Anda ingin melihat bagaimana sesuatu benar-benar berfungsi ketika dokumen tidak cukup.
Wikipedia mengatakan :
"Kebijakan Unix untuk dokumentasi on-line yang luas dan (selama bertahun-tahun) akses siap ke semua kode sumber sistem meningkatkan harapan programmer, dan berkontribusi pada peluncuran gerakan perangkat lunak bebas tahun 1983."
Saya tidak yakin apa yang memotivasi keputusan ini, karena memberikan pelanggan akses ke kode sumber perangkat lunak komersial tidak pernah terdengar akhir-akhir ini. Jelas ada beberapa bias budaya awal dalam arah ini, tetapi mungkin yang tumbuh dari akar Unix sebagai OS portabel yang sebagian besar ditulis dalam bahasa C (bukan bahasa assembly) yang dapat dikompilasi untuk perangkat keras yang berbeda. Saya pikir banyak OS sebelumnya memiliki lebih banyak kode mereka yang ditulis dalam asm untuk CPU tertentu, sehingga portabilitas tingkat sumber adalah salah satu kekuatan awal Unix. (Saya mungkin salah tentang ini; Saya bukan ahli tentang Unix awal, tetapi Unix dan C terkait.)
Distribusi perangkat lunak dalam bentuk sumber sejauh ini merupakan cara termudah untuk membiarkan orang mengadaptasinya ke sistem apa pun yang mereka inginkan. (Baik pengguna akhir atau orang mengemasnya untuk distro Linux). Jika perangkat lunak telah dikemas oleh / untuk distribusi, pengguna akhir dapat menggunakannya.
Tetapi terlalu banyak mengharapkan penulis dari sebagian besar paket untuk membuat binari untuk setiap sistem yang memungkinkan. Beberapa proyek besar menyediakan binari untuk beberapa kasus umum (terutama x86 / windows di mana OS tidak datang dengan lingkungan build, dan vendor OS telah memberikan penekanan besar pada distribusi installer biner saja).
Mendapatkan perangkat lunak untuk dijalankan pada sistem yang berbeda dari yang digunakan penulis bahkan mungkin memerlukan beberapa perubahan kecil, yang mudah dilakukan dengan sumbernya . Program kecil satu kali yang ditulis seseorang untuk menggaruk gatalnya sendiri mungkin belum pernah diuji pada kebanyakan sistem yang tidak jelas. Memiliki sumber memungkinkan untuk melakukan perubahan tersebut. Penulis asli mungkin telah mengabaikan sesuatu, atau sengaja menulis kode yang lebih portabel karena menghemat banyak waktu. Bahkan paket utama seperti Info-ZIP tidak memiliki penguji di setiap platform segera, dan membutuhkan orang untuk mengirimkan patch portabilitas mereka saat masalah ditemukan.
(Ada jenis lain dari masalah portabilitas tingkat sumber yang hanya terjadi karena perbedaan build env, dan tidak benar-benar relevan dengan masalah di sini. Dengan portabilitas biner gaya Java, alat-alat otomatis ( autoconf
/ auto-make
) dan hal-hal serupa seperti cmake
tidak akan terjadi. "Itu diperlukan. Dan kita tidak akan memiliki hal-hal seperti beberapa sistem memerlukan dimasukkannya <netinet/in.h>
alih - alih<arpa/inet.h>
untukntohl(3)
. (Dan mungkin kita tidak akan memiliki ntohl()
atau hal-hal byte-order lainnya di tempat pertama!)
Saya mengembangkan dalam bahasa .NET secara teratur, jadi saya tidak buta komputer.
Kompilasi-sekali, jalankan-di mana saja adalah salah satu tujuan utama .NET dan juga Java, jadi wajar untuk mengatakan bahwa seluruh bahasa telah ditemukan dalam upaya untuk menyelesaikan masalah ini , dan pengalaman pengembang Anda bersama salah satu dari mereka. Dengan .NET, biner Anda berjalan di lingkungan runtime portabel (CLR) . Java menyebutnya lingkungan runtime Java Virtual Machine . Anda hanya perlu mendistribusikan satu biner yang akan bekerja pada sistem apa pun (setidaknya, sistem mana pun di mana seseorang telah menerapkan JVM atau CLR). Anda masih dapat memiliki masalah portabilitas seperti, pemisah jalur /
vs \
, atau cara mencetak, atau detail tata letak GUI, tentu saja.
Banyak perangkat lunak ditulis dalam bahasa yang sepenuhnya dikompilasi ke dalam kode asli . Tidak ada .net
atau bytecode java, hanya kode mesin asli untuk CPU yang akan dijalankan, disimpan dalam format file yang dapat dieksekusi non-portabel. C dan C ++ adalah contoh utama dari ini, terutama di dunia Unix. Jelas ini berarti biner harus dikompilasi untuk arsitektur CPU tertentu.
Versi perpustakaan adalah masalah lain . Perpustakaan dapat dan sering menjaga API level sumber tetap stabil saat mengubah ABI tingkat biner. (Lihat Perbedaan antara API dan ABI .) Misalnya, menambahkan anggota lain ke opaque struct
masih mengubah ukurannya, dan memerlukan kompilasi ulang dengan header untuk versi perpustakaan baru untuk kode apa pun yang mengalokasikan ruang untuk struct seperti itu, apakah itu dinamis (malloc) ), statis (global), atau otomatis (lokal di stack).
Sistem operasi juga penting . Sebuah rasa yang berbeda dari Unix untuk arsitektur CPU yang sama mungkin memiliki format file yang berbeda biner, ABI yang berbeda untuk membuat panggilan sistem, dan nilai-nilai numerik yang berbeda untuk konstanta seperti fopen(3)
's O_RDONLY
, O_APPEND
,O_TRUNC
.
Perhatikan bahwa bahkan biner yang terhubung secara dinamis masih memiliki beberapa kode startup khusus OS yang berjalan sebelumnya main()
. Di Windows, ini crt0
. Unix dan Linux memiliki hal yang sama, di mana beberapa kode Startup C-Runtime secara statis dihubungkan ke setiap biner. Saya kira secara teori Anda dapat merancang sistem di mana kode itu secara dinamis terhubung juga, dan bagian dari libc atau dynamic linker itu sendiri, tetapi ini bukan cara kerja dalam praktik pada OS apa pun yang saya ketahui. Itu hanya akan memecahkan masalah ABI sistem panggilan, bukan masalah nilai numerik untuk konstanta untuk fungsi perpustakaan standar. (Biasanya panggilan sistem dilakukan melalui fungsi libc wrapper: biner Linux x86-64 normal untuk sumber yang menggunakan mmap()
tidak akan menyertakan syscall
instruksi, hanya sebuahcall
instruksi ke fungsi libc wrapper dengan nama yang sama.
Ini adalah bagian dari mengapa Anda tidak bisa menjalankan binari i386-FreeBSD di i386-Linux. (Untuk sementara, kernel Linux memiliki lapisan kompatibilitas system-call. Saya pikir setidaknya salah satu BSD dapat menjalankan binari Linux, dengan lapisan compat yang sama, tetapi Anda tentu saja membutuhkan perpustakaan Linux.)
Jika Anda ingin mendistribusikan binari, Anda harus membuat yang terpisah untuk setiap kombinasi CPU / OS-rasanya + versi / diinstal-perpustakaan-versi .
Kembali ke tahun '80 -an / '90 -an, ada banyak jenis CPU yang umum digunakan untuk sistem Unix (MIPS, SPARC, POWER, PA-RISC, m68k, dll.), Dan banyak rasa berbeda dari Unix (IRIX, SunOS, Solaris, AIX, HP-UX, BSD, dll.)
Dan itu hanya sistem Unix . Banyak paket sumber juga dapat dikompilasi dan bekerja pada sistem lain , seperti VAX / VMS, MacOS (m68k dan PPC), Amiga, PC / MS-DOS, Atari ST, dll.
Masih banyak arsitektur CPU dan OS, meskipun sekarang sebagian besar desktop x86 menjalankan salah satu dari tiga OS utama.
Jadi sudah ada lebih banyak kombinasi CPU / OS daripada yang bisa Anda goyang, bahkan sebelum Anda mulai berpikir tentang ketergantungan pada pustaka pihak ke-3 yang mungkin ada di versi yang berbeda pada sistem yang berbeda. (Apa pun yang tidak dikemas oleh vendor OS harus diinstal dengan tangan.)
Setiap jalur yang dikompilasi ke dalam biner juga spesifik sistem. (Ini menghemat RAM dan waktu dibandingkan dengan membacanya dari file konfigurasi saat startup). Sistem Unix lama-sekolah biasanya memiliki banyak hal yang dikustomisasi dengan tangan, jadi tidak mungkin Anda dapat membuat asumsi yang valid tentang apa yang ada di mana.
Mendistribusikan binari benar-benar tidak mungkin dilakukan untuk Unix jadul kecuali untuk proyek komersial besar yang mampu membangun dan menguji semua kombinasi utama .
Bahkan membuat biner untuk adil i386-linux-gnu
dan amd64-linux-gnu
sulit. Banyak waktu dan usaha telah dihabiskan untuk hal-hal seperti Linux Standard Base untuk memungkinkan biner portabel . Bahkan menghubungkan binari secara statis tidak menyelesaikan segalanya. (mis. bagaimana seharusnya program pengolah kata mencetak pada sistem RedHat vs. sistem Debian? Bagaimana cara menginstal menambahkan pengguna atau grup untuk daemon, dan mengatur agar skrip startupnya dijalankan setelah setiap reboot?) Itu tidak bagus contoh, karena kompilasi ulang dari sumber tidak menyelesaikannya.
Selain semua itu, kembali pada hari memori lebih berharga daripada sekarang. Meninggalkan fitur opsional pada waktu kompilasi dapat membuat biner yang lebih kecil (ukuran kode lebih sedikit) yang juga menggunakan lebih sedikit memori untuk struktur datanya. Jika suatu fitur memerlukan anggota tambahan dalam setiap instance dari sesuatu class
atau struct
untuk melacak sesuatu, menonaktifkan fitur tersebut akan menyusutkan objek sebesar 4 byte (misalnya), yang bagus jika itu adalah objek yang dialokasikan oleh program 100k.
Fitur waktu kompilasi opsional dewasa ini paling sering digunakan untuk menjadikan perpustakaan tambahan opsional. misalnya anda dapat mengkompilasi ffmpeg
dengan atau tanpa libx264
, libx265
, libvorbis
, dan banyak perpustakaan lainnya untuk spesifik video / encoders audio, penanganan subtitle, dll dll Lebih umum, banyak hal dapat dikompilasi dengan atau tanpa libreadline
: jika tersedia ketika Anda menjalankan ./configure
, yang biner yang dihasilkan akan tergantung pada pustaka, dan menyediakan pengeditan baris yang bagus saat membaca dari terminal. Jika tidak, maka program akan menggunakan beberapa dukungan untuk hanya membaca baris dari stdin dengan fgets()
atau sesuatu.)
Beberapa proyek masih menggunakan fitur opsional untuk meninggalkan kode yang tidak diperlukan karena alasan kinerja. misalnya kernel Linux itu sendiri dapat dibangun tanpa dukungan SMP (misalnya untuk sistem tertanam atau desktop kuno), dalam hal ini banyak penguncian lebih sederhana. Atau dengan banyak fitur opsional lainnya yang memengaruhi beberapa kode inti, tidak hanya meninggalkan driver atau fitur perangkat keras lainnya. (Meskipun opsi konfigurasi lengkung khusus dan khusus perangkat keras untuk banyak kode sumber total. Lihat Mengapa kernel Linux 15+ juta baris kode? )