Halaman ini membahas apa itu sistem build, apa yang dilakukannya, alasan Anda harus menggunakan sistem build, dan alasan compiler serta skrip build bukan pilihan terbaik saat organisasi Anda mulai berkembang. Dokumen ini ditujukan bagi developer yang tidak memiliki banyak pengalaman dengan sistem build.
Apa itu sistem build?
Pada dasarnya, semua sistem build memiliki tujuan yang jelas: mengubah kode sumber yang ditulis oleh engineer menjadi biner yang dapat dieksekusi dan dapat dibaca oleh mesin. Sistem build tidak hanya untuk kode yang ditulis oleh manusia; sistem ini juga memungkinkan mesin membuat build secara otomatis, baik untuk pengujian maupun untuk rilis ke produksi. Di organisasi dengan ribuan engineer, biasanya sebagian besar build dipicu secara otomatis, bukan langsung oleh engineer.
Mengapa saya tidak bisa menggunakan compiler saja?
Kebutuhan akan sistem build mungkin tidak langsung terlihat. Sebagian besar engineer tidak menggunakan sistem build saat belajar coding: sebagian besar memulai dengan memanggil alat seperti gcc
atau javac
langsung dari command line, atau yang setara di lingkungan pengembangan terintegrasi (IDE). Selama semua kode sumber berada di direktori yang sama, perintah seperti ini akan berfungsi dengan baik:
javac *.java
Perintah ini menginstruksikan compiler Java untuk mengambil setiap file sumber Java di direktori saat ini dan mengubahnya menjadi file class biner. Dalam kasus paling sederhana, inilah yang Anda butuhkan.
Namun, segera setelah kode diperluas, komplikasi akan dimulai. javac
cukup pintar untuk mencari di subdirektori direktori saat ini guna menemukan kode yang akan diimpor. Namun, tidak ada cara untuk menemukan kode yang disimpan di bagian lain dari
sistem file (mungkin library yang digunakan bersama oleh beberapa project). Selain itu, hanya mengetahui cara mem-build kode Java. Sistem besar sering kali melibatkan berbagai bagian yang ditulis dalam berbagai bahasa pemrograman dengan jaringan dependensi di antara bagian-bagian tersebut, yang berarti tidak ada compiler untuk satu bahasa yang dapat membangun seluruh sistem.
Setelah Anda berurusan dengan kode dari beberapa bahasa atau beberapa unit kompilasi, membangun kode tidak lagi menjadi proses satu langkah. Sekarang Anda harus mengevaluasi apa yang bergantung pada kode Anda dan membangun 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 dependensi pada biner yang tidak berlaku. Untuk codebase yang berukuran sedang, proses ini akan menjadi membosankan dan rentan terhadap error.
Compiler juga tidak mengetahui cara menangani dependensi eksternal, seperti file JAR
pihak ketiga di Java. Tanpa sistem build,
Anda dapat mengelola ini dengan mendownload dependensi dari internet, menempelkannya
di folder lib
pada 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 proyek hobi Anda dimulai dengan cukup sederhana sehingga Anda dapat membuatnya hanya menggunakan compiler, tetapi Anda mulai menghadapi beberapa masalah yang dijelaskan sebelumnya. Mungkin Anda masih merasa tidak memerlukan sistem build dan dapat mengotomatiskan bagian yang membosankan menggunakan beberapa skrip shell sederhana yang menangani build dengan urutan yang benar. Cara ini akan membantu untuk sementara, tetapi segera Anda akan menghadapi lebih banyak masalah:
Prosesnya menjadi membosankan. Saat sistem Anda menjadi lebih kompleks, Anda mulai menghabiskan hampir sama banyaknya waktu untuk mengerjakan skrip build seperti pada kode sebenarnya. Proses men-debug skrip shell sangat menyakitkan, dengan semakin banyak peretasan yang ditumpuk satu sama lain.
YouTube Studio baru lambat. Untuk memastikan Anda tidak secara tidak sengaja mengandalkan library yang sudah usang, Anda harus membuat skrip build membangun setiap dependensi secara berurutan setiap kali Anda menjalankannya. Anda berpikir untuk menambahkan beberapa logika untuk mendeteksi bagian mana yang perlu dibangun ulang, tetapi hal itu terdengar sangat rumit dan rentan terhadap error untuk skrip. Atau Anda berpikir untuk menentukan bagian mana yang perlu dibangun ulang setiap kali, tetapi kemudian Anda kembali ke titik awal.
Kabar baik: saatnya merilis! Sebaiknya cari tahu semua argumen yang perlu Anda teruskan ke perintah jar untuk membuat build akhir. Dan ingat cara mengupload dan mengirimkannya ke repositori pusat. Kemudian, buat dan dorong pembaruan dokumentasi, serta kirim notifikasi kepada pengguna. Hmm, mungkin perlu skrip lain...
Gawat! Hard drive Anda rusak, dan sekarang Anda perlu membuat ulang seluruh sistem. Anda cukup pintar untuk menyimpan semua file sumber dalam kontrol versi, tetapi bagaimana dengan library yang Anda download? Dapatkah Anda menemukan semuanya lagi dan memastikan bahwa versi yang Anda download sama dengan versi yang pertama kali Anda download? Skrip Anda mungkin bergantung pada alat tertentu yang diinstal di tempat tertentu—dapatkah Anda memulihkan lingkungan yang sama agar skrip berfungsi kembali? Bagaimana dengan semua variabel lingkungan yang Anda tetapkan sejak lama agar compiler berfungsi dengan baik, lalu Anda lupakan?
Terlepas dari masalah tersebut, proyek Anda cukup berhasil sehingga Anda dapat mulai merekrut lebih banyak engineer. Sekarang Anda menyadari bahwa tidak perlu terjadi bencana agar masalah sebelumnya muncul—Anda harus melalui proses bootstrap yang menyakitkan yang sama setiap kali developer baru bergabung dengan tim Anda. Dan meskipun Anda sudah berupaya sebaik mungkin, masih ada sedikit perbedaan dalam sistem setiap orang. Sering kali, apa yang berfungsi di komputer seseorang tidak berfungsi di komputer orang lain, dan setiap kali hal itu terjadi, dibutuhkan beberapa jam untuk men-debug jalur alat atau versi pustaka guna mengetahui letak perbedaannya.
Anda memutuskan bahwa Anda perlu mengotomatiskan sistem build. Secara teori, hal ini sesederhana mendapatkan komputer baru dan menyiapkannya untuk menjalankan skrip build setiap malam menggunakan cron. Anda masih harus melalui proses penyiapan yang menyakitkan, tetapi sekarang Anda tidak mendapatkan manfaat dari otak manusia yang dapat mendeteksi dan menyelesaikan masalah kecil. Sekarang, setiap pagi saat Anda datang, Anda melihat bahwa build tadi malam gagal karena kemarin seorang developer membuat perubahan yang berfungsi di sistemnya, tetapi tidak berfungsi di sistem build otomatis. Setiap kali masalah ini terjadi, Anda dapat memperbaikinya dengan mudah. Namun, masalah ini sering terjadi sehingga Anda menghabiskan banyak waktu setiap hari untuk menemukan dan menerapkan perbaikan sederhana ini.
Build menjadi semakin lambat seiring berkembangnya project. Suatu hari, saat menunggu build selesai, Anda menatap dengan sedih desktop rekan kerja yang sedang tidak aktif karena sedang berlibur, dan berharap ada cara untuk memanfaatkan semua daya komputasi yang terbuang itu.
Anda menghadapi masalah klasik terkait skala. Untuk satu developer yang mengerjakan paling banyak beberapa ratus baris kode selama paling banyak satu atau dua minggu (yang mungkin merupakan seluruh pengalaman developer junior yang baru lulus kuliah), compiler adalah semua yang Anda butuhkan. Skrip mungkin dapat membantu Anda lebih jauh. Namun, segera setelah Anda perlu berkoordinasi dengan beberapa developer dan mesin mereka, bahkan skrip build yang sempurna pun tidak cukup karena akan sangat sulit untuk memperhitungkan perbedaan kecil di mesin tersebut. Pada titik ini, pendekatan sederhana ini tidak berfungsi dan saatnya berinvestasi dalam sistem build yang sebenarnya.