為什麼要建構建構系統?

回報問題 查看原始碼

本資訊頁面說明什麼是建構系統、其用途、為何應使用建構系統,以及當貴機構開始擴充規模時,編譯器和建構指令碼並不是最佳的選擇。本文適用於較不熟悉建構系統的開發人員。

什麼是建構系統?

基本上,所有建構系統都有直接的用途:將工程師編寫的原始碼轉換為可執行的二進位檔,可供機器讀取。建構系統不僅僅是針對使用者撰寫的程式碼,也可讓機器自動建立測試 (無論是用於測試或發布至實際工作環境)。在擁有數千名工程師的組織中,系統通常會自動觸發大部分建構作業,而非由工程師直接觸發。

我不能僅使用編譯器嗎?

建構系統的需求可能不會立即顯現。大多數工程師在學習程式設計時不會使用建構系統:大多數情況下,首先是直接透過指令列叫用 gccjavac 等工具,或是在整合式開發環境 (IDE) 中取得同等的功能。只要所有原始碼都位於同一個目錄中,類似指令就可以正常運作:

javac *.java

這會指示 Java 編譯器擷取目前目錄中每個 Java 來源檔案,並將其轉換為二進位類別檔案。在最簡單的情況下,這就是您需要的所有動作。

不過,只要程式碼展開,小工具就會開始。javac 十分聰明,可以在目前目錄的子目錄中尋找要匯入的程式碼。但無法找出儲存在檔案系統其他部分 (可能是多個專案共用的程式庫) 的程式碼。此外,它還不知道如何建構 Java 程式碼。大型系統通常涉及以各種程式設計語言編寫的不同部分,並在這些片段之間依附網路,這表示單一語言的編譯器可能無法建構整個系統。

當您處理多種語言或多個編譯單元的程式碼時,建構程式碼就不再是單向程序。現在,您必須評估程式碼所依附的元件,並以適當的順序建構這些部分,例如針對各個部分使用不同的工具組合。如果任何依附元件變更,您必須重複這個程序來避免依賴過時的二進位檔。針對具有中等規模大小的程式碼集,這個過程很快就會變得繁瑣且容易出錯。

編譯器也不知道如何處理外部依附元件,例如 Java 中的第三方 JAR 檔案。如果沒有建構系統,只要從網際網路下載依附元件,將其置於硬碟上的 lib 資料夾中,然後設定編譯器,即可從該目錄讀取程式庫,即可管理此功能。隨著時間推移,很難維護這些外部依附元件的更新、版本和來源。

殼層指令碼呢?

假設您的嗜好專案一開始就夠簡單,可以使用編譯器建立專案,但會開始執行先前所述的某些問題。也許您仍然認為自己不需要建構系統,而可以使用一些簡單的殼層指令碼來自動處理繁雜的部分,而這些指令碼會按正確順序建構項目。這能讓您有一段時間的功效,但很快您就會遇到其他問題:

  • 這個過程很繁瑣。隨著系統變得越來越複雜,您開始花費大量時間使用建構指令碼,與實際的程式碼一樣。偵錯殼層指令碼非常困難,而且越來越多的駭客堆疊層疊在一起。

  • 這很慢為避免意外依賴過時的程式庫,您必須讓建構指令碼在每次執行時依照順序建構每個依附元件。您要考慮新增一些邏輯,以偵測需要重新建立的零件,但聽起來有點複雜且容易出錯。或者,您也可以考慮每次要重新建構哪些部分,然後再返回正方形。

  • 好消息,是時候該出版了!最好找出所有要傳遞至 jar 指令所需的引數,以完成最終的建構。記得如何上載檔案並推送至中央存放區。建構及推送說明文件更新,並傳送通知給使用者。嗯,這或許需要另一個指令碼...

  • 災難!現在硬碟會當機,因此您必須重新建立整個系統。您已經夠聰明,可以將所有來源檔案保存在版本管控之中,但下載的資料庫您是否能再次找到這些檔案,並且確認它們與首次下載時的相同版本?指令碼可能需要依靠在特定位置安裝的特定工具,您是否能還原相同的環境,讓指令碼再次運作?您之前設定的所有環境變數,可讓編譯器正常運作,但又沒忘記,該怎麼辦?

  • 儘管存在問題,您的專案也夠成功,您可以開始招聘更多工程師。現在,您發現問題不會導致先前的問題發生,每次新開發人員加入團隊時,都必須執行相同的痛苦的開機程序。雖然您努力做到最好,但每個人的系統中仍有些微差異。通常,某人的機器作業,在另一部機器上無法運作,且每次經過數小時的偵錯工具路徑或程式庫版本,而難以判斷差異之處。

  • 您決定自動化建構系統。理論上來說,就跟使用新電腦並且使用 Cron 設定每晚執行指令碼一樣簡單。您仍然必須完成困難的設定程序,但現在您沒有發現大腦能夠偵測和解決小問題的問題。現在,每天早上您都會看到每次發生簡單的修正,但經常發生,因此每天都花費大量時間來探索並套用這些簡單的修正。

  • 隨著專案的成長,建構作業的速度會變慢。有一天,在等待建構完成時,您會因為同事的閒置桌面而動機動盪,而又希望有一種方法可以運用所有的浪費運算能力。

您遇到了經典規模的問題。如果單一開發人員最多工作兩百行程式碼,最多只有一百週的時間 (可能是已經成為畢業大學初級開發人員的整個經驗),編譯器就是您需要的一切。指令碼可能需要一點點 但是,當您需要在多個開發人員及其機器之間協調時,即使是完美的建構指令碼還不夠,因為對這些機器的微小差異並不容易。此時,這個簡單的方法會細分,現在要投資真正的建構系統。