Walaupun saya bisa membuat kode, saya belum punya pengalaman dengan mengerjakan proyek-proyek besar. Apa yang saya lakukan sejauh ini adalah mengkode program kecil yang dikompilasi dalam hitungan detik (berbagai latihan c / c ++ seperti algoritma, prinsip pemrograman, ide, paradigma, atau hanya mencoba api ...) atau mengerjakan beberapa proyek kecil yang dibuat dalam bahasa skrip (python, php, js) di mana tidak diperlukan kompilasi.
Masalahnya adalah, ketika coding dalam bahasa scripting, setiap kali saya ingin mencoba jika sesuatu berfungsi - saya hanya menjalankan skrip dan melihat apa yang terjadi. Jika semuanya tidak berhasil, saya dapat dengan mudah mengubah kode dan mencobanya lagi dengan menjalankan skrip lagi dan terus melakukan itu sampai saya mendapatkan hasil yang saya inginkan .. Maksud saya adalah bahwa Anda tidak perlu menunggu apa saja untuk dikompilasi dan karena itu cukup mudah untuk mengambil basis kode besar, memodifikasinya, menambahkan sesuatu ke dalamnya, atau hanya bermain dengannya - Anda dapat melihat perubahannya secara instan.
Sebagai contoh saya akan mengambil Wordpress. Sangat mudah untuk mencoba dan mencari tahu cara membuat plugin untuk itu. Pertama Anda mulai dengan membuat plugin "Hello World" sederhana, kemudian Anda membuat antarmuka sederhana untuk panel admin untuk membiasakan diri dengan API, kemudian Anda membangunnya dan membuat sesuatu yang lebih kompleks, sementara itu mengubah tampilannya seperti beberapa. kali .. Gagasan harus mengkompilasi ulang sesuatu sebesar WP berulang-ulang, setelah setiap perubahan kecil untuk mencoba "jika berhasil" dan "bagaimana cara kerjanya / terasa" sepertinya tidak efisien, lambat dan salah.
Sekarang, bagaimana saya bisa melakukan itu dengan proyek yang ditulis dalam bahasa yang dikompilasi? Saya ingin berkontribusi pada beberapa proyek open-source dan pertanyaan ini terus menggangguku. Situasinya mungkin berbeda dari proyek ke proyek di mana beberapa dari mereka yang sebelumnya berpikir dengan bijak akan "modular" dalam beberapa cara sementara yang lain hanya akan menjadi satu gumpalan besar yang perlu dikompilasi ulang berulang kali.
Saya ingin tahu lebih banyak tentang bagaimana ini dilakukan dengan benar. Apa saja praktik umum, pendekatan dan desain proyek (pola?) Untuk mengatasinya? Bagaimana "modularitas" ini disebut di dunia programmer dan apa yang harus saya google untuk mempelajari lebih lanjut tentang ini? Apakah sering proyek tumbuh dari proporsi pemikiran pertama mereka yang menjadi masalah setelah beberapa saat? Apakah ada cara untuk menghindari kompilasi yang lama dari proyek yang tidak dirancang dengan baik? Suatu cara untuk memodulasi mereka (mungkin mengecualikan bagian-bagian program yang tidak penting sambil mengembangkan (ada ide lain?))
Terima kasih.
sumber
Jawaban:
Seperti yang telah dikatakan, Anda tidak pernah mengkompilasi ulang seluruh proyek setiap kali Anda membuat perubahan kecil. Alih-alih, Anda hanya mengkompilasi ulang bagian dari kode yang telah berubah, serta semua kode bergantung padanya.
Dalam C / C ++, kompilasi cukup mudah. Anda mengkompilasi menerjemahkan setiap file sumber ke dalam kode mesin (kami menyebutnya file objek * .o) dan kemudian Anda menautkan semua file objek Anda menjadi satu file besar yang dapat dieksekusi.
Sama seperti MainMa disebutkan, beberapa perpustakaan dibangun ke dalam file terpisah, yang akan dihubungkan secara dinamis pada saat run-time dengan executable. Perpustakaan ini disebut Shared Objects (* .so) di Unix dan Dynamically Linked Libraries (DLL) di Windows. Pustaka dinamis memiliki banyak keuntungan, salah satunya adalah Anda tidak perlu mengkompilasi / menautkannya, kecuali jika kode sumbernya berubah secara efektif.
Ada alat otomasi bangunan yang membantu Anda:
Yang paling terkenal (make, ant, maven, ...) dapat mendeteksi secara otomatis bagian mana dari kode yang telah diubah sejak kompilasi terakhir, dan objek / biner apa yang perlu diperbarui.
Namun, ini merupakan biaya (relatif kecil) karena harus menulis "membangun skrip". Ini adalah file yang berisi semua informasi tentang build Anda, seperti mendefinisikan target dan dependensinya, menentukan kompiler mana yang Anda inginkan dan opsi mana yang digunakan, mendefinisikan lingkungan build Anda, jalur perpustakaan Anda, ... Anda mungkin pernah mendengar tentang Makefiles (sangat umum di dunia Unix), atau build.xml (sangat populer di dunia Java). Inilah yang mereka lakukan.
sumber
build.xml
fileAnda tidak mengkompilasi ulang seluruh proyek setiap saat. Misalnya, jika itu adalah aplikasi C / C ++, ada kemungkinan itu akan dipisahkan menjadi pustaka (DLL di Windows), setiap pustaka dikompilasi secara terpisah.
Proyek itu sendiri umumnya dikompilasi setiap hari di server khusus: itu adalah build malam. Proses ini dapat memakan banyak waktu, karena tidak hanya mencakup waktu kompilasi, tetapi juga waktu yang dihabiskan untuk menjalankan tes unit, tes lain, dan proses lainnya.
sumber
Saya pikir apa yang semua jawaban sejauh ini telah singgung juga, adalah bahwa proyek perangkat lunak besar hampir selalu dipecah menjadi potongan-potongan yang jauh lebih kecil. Setiap bagian biasanya disimpan dalam file itu sendiri.
Potongan-potongan ini dikompilasi secara individual untuk membuat objek. Benda-benda tersebut kemudian dihubungkan bersama untuk membentuk produk akhir. [Bisa dibilang, ini seperti membangun barang-barang dari Lego. Anda tidak mencoba untuk mencetak benda terakhir dari selembar plastik besar, sebaliknya Anda menggabungkan banyak potongan kecil untuk membuatnya.]
Memecah proyek menjadi beberapa bagian yang dikompilasi secara individual memungkinkan beberapa hal yang rapi terjadi.
Bangunan Bertambah
Pertama, ketika Anda mengganti satu potong, Anda biasanya tidak perlu mengkompilasi ulang semua bagian. Secara umum, selama Anda tidak mengubah cara bagian lain berinteraksi dengan bagian Anda, yang lain tidak perlu dikompilasi ulang.
Ini memunculkan ide bangunan inkremental . Saat melakukan pembangunan bertahap, hanya potongan-potongan yang dipengaruhi oleh perubahan yang dikompilasi ulang. Ini sangat mempercepat waktu pengembangan. Benar, Anda mungkin masih harus menunggu semuanya untuk ditata kembali, tetapi itu masih penghematan karena harus mengkompilasi ulang dan menautkan kembali semuanya. (BTW: Beberapa sistem / bahasa mendukung penautan tambahan sehingga hanya hal-hal yang diubah yang harus dihubungkan kembali. Biaya untuk ini biasanya dalam kinerja dan ukuran kode yang buruk.)
Pengujian Unit
Hal kedua yang memungkinkan Anda melakukan hal-hal kecil adalah melihat secara individual menguji bagian-bagian tersebut sebelum digabungkan. Ini dikenal sebagai Unit Testing . Dalam Pengujian Unit, setiap unit diuji secara individual sebelum diintegrasikan (dikombinasikan) dengan sisa sistem. Tes unit biasanya ditulis sehingga mereka dapat berjalan dengan cepat tanpa melibatkan sisa sistem.
Kasus yang membatasi penerapan pengujian terlihat di Test Driven Development (TDD). Dalam model pengembangan ini, tidak ada kode yang ditulis / dimodifikasi kecuali untuk memperbaiki tes yang gagal.
Membuatnya Lebih Mudah
Jadi, meruntuhkan hal-hal tampaknya baik, tetapi tampaknya juga banyak pekerjaan yang diperlukan untuk membangun proyek: Anda perlu menentukan bagian kami yang berubah dan apa yang tergantung pada bagian itu, menyusun setiap bagian, dan kemudian menghubungkan semuanya bersama-sama.
Untungnya, pemrogram malas *, sehingga mereka menemukan banyak alat untuk membuat pekerjaan mereka lebih mudah. Untuk itu, banyak alat telah ditulis untuk mengotomatiskan tugas di atas. Yang paling terkenal dari ini telah disebutkan (make, ant, maven). Alat-alat ini memungkinkan Anda untuk menentukan bagian mana yang perlu disatukan untuk membuat proyek akhir Anda dan bagaimana bagian itu saling bergantung (yaitu jika Anda mengubahnya, ini perlu dikompilasi ulang). Hasilnya adalah bahwa mengeluarkan hanya satu perintah tidak menggambarkan apa yang perlu dikompilasi ulang, mengkompilasinya, dan menautkan kembali segalanya.
Tapi itu masih menyisakan bagaimana hal-hal berhubungan satu sama lain. Itu banyak pekerjaan dan seperti yang saya katakan sebelumnya, programmer malas. Jadi mereka datang dengan kelas alat lain. Alat-alat ini telah ditulis untuk menentukan dependensi untuk Anda! Seringkali alat tersebut merupakan bagian dari Integrated Development Environments (IDEs) seperti Eclipse dan Visual Studio, tetapi ada juga beberapa yang mandiri yang digunakan untuk aplikasi umum dan spesifik (makedep, QMake untuk program Qt).
* Sebenarnya, programmer tidak benar-benar malas, mereka hanya suka menghabiskan waktu mereka mengerjakan masalah, tidak melakukan tugas berulang yang dapat diotomatisasi oleh suatu program.
sumber
Inilah daftar barang yang bisa Anda coba mempercepat pembuatan C / C ++:
sumber
Mengeksekusi sesuatu yang ditafsirkan juga sangat tidak efisien dan lambat, dan (bisa dibilang) salah. Anda mengeluh tentang persyaratan waktu pada PC dev, tetapi tidak kompilasi menyebabkan persyaratan waktu pada PC pengguna , yang bisa dibilang jauh lebih buruk.
Lebih penting lagi, sistem modern dapat melakukan pembangunan kembali bertahap yang cukup canggih dan tidak umum untuk mengkompilasi ulang semuanya untuk perubahan kecil - sistem yang dikompilasi dapat mencakup komponen skrip, terutama yang umum untuk hal-hal seperti UI.
sumber
Jika proyek mengimplementasikan ketergantungan kompilasi DAG yang tepat maka Anda dapat pergi dengan hanya mengkompilasi ulang file objek yang mempengaruhi perubahan Anda.
Juga dengan asumsi DAG dependensi kompilasi yang tepat, Anda dapat mengkompilasi menggunakan beberapa proses. Satu pekerjaan per inti / CPU adalah norma.
Anda dapat membuat beberapa file yang dapat dieksekusi untuk pengujian yang hanya menautkan file objek tertentu.
sumber
Selain jawaban MainMa, kami juga baru saja meningkatkan mesin yang sedang kami kerjakan. Salah satu pembelian terbaik yang kami lakukan adalah SSD untuk saat Anda tidak dapat membantu tetapi untuk mengkompilasi ulang seluruh proyek.
Saran lain adalah mencoba kompiler yang berbeda. Kembali pada hari itu, kami beralih dari kompiler Java ke Jikes dan sekarang kami telah beralih menggunakan kompiler yang dibundel dengan Eclipse (tidak tahu apakah ia memiliki nama) yang mengambil keuntungan lebih baik dari prosesor multicore.
Proyek file 37.000 kami membutuhkan waktu sekitar 15 menit untuk dikompilasi dari awal sebelum kami melakukan perubahan ini. Setelah perubahan itu dikurangi menjadi 2-3 menit.
Tentu saja, ada baiknya menyebutkan poin MainMa lagi. Jangan mengkompilasi ulang seluruh proyek setiap kali Anda ingin melihat perubahan.
sumber