Mengapa Sistem Build?

Laporkan masalah Lihat sumber

Halaman ini membahas apa yang dimaksud dengan sistem build, apa fungsinya, mengapa Anda harus menggunakan sistem build, dan mengapa compiler dan skrip build bukan merupakan pilihan terbaik saat organisasi Anda mulai menskalakan. Ini ditujukan bagi developer yang tidak memiliki banyak pengalaman dengan sistem build.

Apa yang dimaksud dengan sistem build?

Pada dasarnya, semua sistem build memiliki tujuan sederhana: mengubah kode sumber yang ditulis oleh engineer menjadi biner yang dapat dieksekusi yang dapat dibaca oleh mesin. Sistem build bukan hanya untuk kode yang ditulis manusia, tetapi juga memungkinkan mesin membuat build secara otomatis, baik untuk pengujian maupun rilis ke produksi. Dalam organisasi yang memiliki ribuan engineer, biasanya sebagian besar build dipicu secara otomatis, bukan langsung oleh engineer.

Tidak bisakah saya menggunakan compiler saja?

Kebutuhan akan sistem build mungkin tidak langsung terlihat. Sebagian besar engineer tidak menggunakan sistem build saat mempelajari coding: sebagian besar dimulai dengan memanggil alat seperti gcc atau javac langsung dari command line, atau yang setara dalam lingkungan pengembangan terintegrasi (IDE). Selama semua kode sumber berada di direktori yang sama, perintah seperti ini akan berfungsi dengan baik:

javac *.java

Hal ini akan memerintahkan compiler Java untuk mengambil setiap file sumber Java dalam direktori saat ini dan mengubahnya menjadi file class biner. Dalam kasus yang paling sederhana, inilah yang Anda butuhkan.

Namun, begitu kode diperluas, detail akan dimulai. javac cukup cerdas untuk dilihat di subdirektori dari direktori saat ini untuk menemukan kode yang akan diimpor. Namun, tidak ada cara untuk menemukan kode yang disimpan di bagian lain sistem file (mungkin library yang digunakan bersama oleh beberapa project). Ia juga hanya tahu cara membuat kode Java. Sistem besar sering kali melibatkan bagian yang berbeda yang ditulis dalam berbagai bahasa pemrograman dengan web dependensi di antara bagian-bagian tersebut, yang berarti tidak ada compiler untuk satu bahasa yang mungkin dapat membuat seluruh sistem.

Setelah Anda menangani kode dari beberapa bahasa atau beberapa unit kompilasi, pembuatan kode tidak lagi merupakan proses satu langkah saja. Sekarang Anda harus mengevaluasi apa yang diperlukan oleh kode Anda dan mem-build bagian-bagian tersebut dalam urutan yang tepat, mungkin menggunakan serangkaian alat yang berbeda untuk setiap bagian. Jika ada dependensi yang berubah, Anda harus mengulangi proses ini untuk menghindari ketergantungan pada biner yang sudah usang. Untuk codebase berukuran sedang juga, proses ini dapat langsung menjadi membosankan dan rentan error.

Compiler juga tidak tahu apa-apa tentang cara menangani dependensi eksternal, seperti file JAR pihak ketiga di Java. Tanpa sistem build, Anda dapat mengelolanya dengan mendownload dependensi dari internet, menempelkannya dalam folder lib di hard drive, dan mengonfigurasi compiler untuk membaca library dari direktori tersebut. Seiring waktu, sulit untuk mempertahankan update, versi, dan sumber dependensi eksternal ini.

Bagaimana dengan skrip shell?

Misalkan project hobi Anda dimulai cukup sederhana sehingga Anda dapat membuatnya hanya dengan menggunakan compiler, tetapi Anda mulai mengalami beberapa masalah yang dijelaskan sebelumnya. Mungkin Anda tetap tidak merasa memerlukan sistem build dan dapat mengotomatiskan bagian-bagian yang membosankan dengan menggunakan beberapa skrip shell sederhana yang menangani proses pembuatannya dalam urutan yang benar. Hal ini dapat membantu untuk sementara, tetapi tidak lama lagi Anda akan mulai mengalami lebih banyak masalah:

  • Menjadi membosankan. Saat sistem Anda berkembang menjadi lebih kompleks, Anda mulai menghabiskan hampir banyak waktu untuk mengerjakan skrip build seperti pada kode sebenarnya. Men-debug skrip shell adalah hal yang menyakitkan, dengan semakin banyak peretasan yang ditempatkan di atas satu sama lain.

  • Lambat. Untuk memastikan Anda tidak sengaja mengandalkan library usang, Anda harus membuat skrip build setiap dependensi secara berurutan setiap kali Anda menjalankannya. Anda berpikir untuk menambahkan beberapa logika guna mendeteksi bagian yang perlu dibuat ulang, tetapi kedengarannya sangat rumit dan rawan error untuk skrip. Atau Anda harus menentukan bagian mana yang perlu dibuat ulang setiap saat, tetapi Anda akan kembali ke persegi.

  • Kabar baik: saatnya untuk rilis! Sebaiknya cari tahu semua argumen yang perlu diteruskan ke perintah jar untuk membuat build akhir. Selain itu, ingat cara menguploadnya dan mengirimkannya ke repositori pusat. Kemudian, build dan kirim update dokumentasi, serta kirimkan notifikasi kepada pengguna. Hmm, mungkin ini meminta skrip lain...

  • Bencana! Hard drive Anda error, dan sekarang Anda perlu membuat ulang seluruh sistem. Anda cukup cerdas untuk menyimpan semua file sumber dalam kontrol versi, tetapi bagaimana dengan library yang Anda download? Dapatkah Anda menemukan semuanya lagi dan memastikan bahwa versinya sama dengan saat pertama kali Anda mendownloadnya? Skrip Anda mungkin bergantung pada alat tertentu yang diinstal di tempat tertentu, dapatkah Anda memulihkan lingkungan yang sama agar skrip berfungsi lagi? Bagaimana dengan semua variabel lingkungan yang Anda tetapkan lama untuk membuat compiler berfungsi dengan baik, lalu dilupakan?

  • Meskipun mengalami masalah, project Anda cukup sukses sehingga Anda dapat mulai merekrut lebih banyak engineer. Sekarang, Anda menyadari bahwa tidak perlu bencana untuk masalah yang telah muncul sebelumnya—Anda harus menjalani proses bootstrapping yang sama setiap kali developer baru bergabung dengan tim Anda. Terlepas dari upaya terbaik Anda, masih ada perbedaan kecil dalam sistem setiap orang. Sering kali, apa yang berfungsi pada mesin satu orang tidak berfungsi di komputer orang lain, dan setiap kali dibutuhkan beberapa jam jalur alat debug atau versi library untuk mengetahui di mana perbedaannya.

  • Anda memutuskan bahwa Anda perlu mengotomatiskan sistem build. Secara teori, hal ini semudah mendapatkan komputer baru dan menyiapkannya untuk menjalankan skrip build setiap malam menggunakan cron. Anda masih harus menjalani proses penyiapan yang menyakitkan, tetapi sekarang Anda tidak akan mendapatkan manfaat dari otak manusia yang dapat mendeteksi dan menyelesaikan masalah kecil. Kini, setiap pagi saat Anda masuk, Anda melihat bahwa build tadi malam gagal karena kemarin developer membuat perubahan yang berfungsi pada sistem mereka, tetapi tidak berfungsi pada sistem build otomatis. Setiap kali ini adalah perbaikan sederhana, tetapi hal ini sering terjadi sehingga Anda akhirnya menghabiskan banyak waktu setiap hari untuk menemukan dan menerapkan perbaikan sederhana ini.

  • Build menjadi lebih lambat dan lebih lambat seiring pertumbuhan project. Suatu hari, sambil menunggu build selesai, Anda memandang dengan sedih di desktop rekan kerja yang tidak ada aktivitas, yang sedang berlibur, dan berharap ada cara untuk memanfaatkan semua yang menghabiskan daya komputasinya.

Anda telah mengalami masalah skala klasik. Untuk developer tunggal yang mengerjakan maksimum beberapa ratus baris kode selama maksimal satu atau dua minggu (yang mungkin adalah seluruh pengalaman developer junior yang baru saja lulus universitas), Anda hanya perlu membuat compiler. Skrip mungkin bisa membuat Anda sedikit lebih baik. Namun, segera setelah Anda perlu berkoordinasi dengan beberapa developer dan mesin mereka, bahkan skrip build yang sempurna saja tidak cukup karena akan sangat sulit untuk memperhitungkan perbedaan kecil dalam mesin tersebut. Pada tahap ini, pendekatan sederhana ini runtuh dan sekarang saatnya untuk berinvestasi dalam sistem build sungguhan.