為什麼要建構系統?

本頁面說明什麼是建構系統、其功用、為何應使用建構系統,以及為何在貴機構開始擴充規模時,編譯器和建構指令碼並非最佳選擇。適合沒有建構系統經驗的開發人員使用。

什麼是建構系統?

基本上,所有建構系統都有直接的用途:將工程師編寫的原始碼轉換為可由機器讀取的可執行二進位檔。建構系統不只可以用於人為撰寫的程式碼,也能讓機器自動建立版本,無論是用於測試或發布實際工作環境都沒問題。在擁有數千名工程師的機構中,大部分的建構作業都是由系統自動觸發,而不是由工程師直接觸發。

不能只使用編譯器?

建構系統的需求可能不會立即顯而易見。在學習寫程式時,大多數工程師都不會使用建構系統,大多數的工程師都是直接透過指令列叫用工具,例如 gccjavac,或者在整合式開發環境 (IDE) 中叫用類似的工具。只要所有原始碼都在同一個目錄中,類似下方的指令即可正常運作:

javac *.java

這會指示 Java 編譯器擷取目前目錄中的每個 Java 來源檔案,並將其轉換成二進位類別檔案。最簡單的方式就是這樣

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

處理多種語言或編譯單元的程式碼後,建構程式碼不再是一個步驟。現在,您必須評估程式碼的依附項目,並依照正確的順序建構這些片段,或者可能會針對每種部分使用不同的工具組合。如有任何依附元件變更,您必須重複執行這項程序,以免依附於過時的二進位檔。對於同樣大小的中等程式碼集,這項程序很快就變得繁瑣且容易出錯。

編譯器也不知道如何處理外部依附元件 (例如 Java 中的第三方 JAR 檔案)。在沒有建構系統的情況下,若要管理此設定,請從網際網路下載依附元件,將依附元件貼到硬碟的 lib 資料夾中,然後設定編譯器,從該目錄讀取程式庫。隨著時間過去,我們很難維持這些外部依附元件的更新、版本及來源。

如何處理殼層指令碼?

假設您的興趣專案一開始很簡單,因此只要使用編譯器,就可以建構專案,但開始遇到先前所述的部分問題。也許您依然認為自己不需要建構系統,而且可以使用一些簡單的殼層指令碼,按照正確順序處理建構項目,藉此自動化處理繁瑣的部分。這項功能有助於持續運作,但您很快就能開始遇到更多問題:

  • 真是相當枯燥乏味。隨著系統越來越複雜,您會開始投入大部分的時間在建構建構指令碼時,就像使用實際程式碼一樣。對殼層指令碼進行偵錯很方便,因為駭客層層層把更多入侵。

  • 速度緩慢。為避免意外仰賴過時的程式庫,您要讓建構指令碼在每次執行時依序建構每個依附元件。您會考慮加入一些邏輯來偵測哪些部分需要重建,但對指令碼來說聽起來不夠複雜且容易出錯。或者,您也考慮指定每次需要重建哪些部分,但之後要回到正方形。

  • 好消息:是時候發布了!建議您更精確地找出需要傳遞至 jar 指令的所有引數,以便建立最終版本。別忘瞭如何上傳,並將其推送到中央存放區。然後建構並推送說明文件更新,並向使用者傳送通知。嗯,也許這就是另一個指令碼的作用...

  • 太慘了!硬碟當機,現在必須重新建立整個系統。您的聰明程度已足以將所有來源檔案保存在版本管控系統中,但您下載的程式庫呢?您是否能再次找到這些內容,並確保這些項目與首次下載時的版本相同?您的指令碼可能依賴於特定位置安裝的特定工具,您是否可以還原相同的環境,讓指令碼再次運作?如果您很久以前就設定這些環境變數讓編譯器正常運作,但又忘記了呢?

  • 儘管出現問題,您的專案已順利完成,您就能夠開始僱用更多工程師。現在,您瞭解到讓先前的問題不再發生災難,因此每當有新的開發人員加入團隊,都必須執行相同的啟動程序。儘管盡了最大努力,但每個人的系統仍有些微差異。通常,在某個人電腦上運作的功能無法在其他電腦中運作,且每次都會需要數小時的偵錯工具路徑或程式庫版本,才能找出差異所在。

  • 您決定要自動建構建構系統。理論上,這非常簡單,只要在取得新電腦後,讓電腦每天使用 Cron 執行建構指令碼即可。您仍需完成複雜的設定程序,但現在沒有人腦可以偵測並解決小問題的好處。現在,您每天早上開始作業後,您會發現昨晚建構失敗,因為開發人員昨天做出了適用於其系統,但不適用於自動化建構系統的變更。每次的修正都是簡單的修正,但往往每天會花很多時間找出和應用這些簡單的修正方法。

  • 隨著專案成長,建構速度會越來越慢。有一天,當您等待建構作業完成時,您目睹了同事在閒置的桌面上看見正在休假的同事,並希望有一種方法能夠充分運用所有如此耗時的運算能力。

您已經遇到體重計的典型問題。對於在最多一週或兩行程式碼工作上處理約幾百行程式碼的開發人員而言,這可能就一直是到大學畢業生的初級開發人員經驗。編寫指令碼也許需要一點時間不過,當您需要協調多個開發人員及其機器時,即使只是完美的建構指令碼還不夠,因為要考量這些機器之間的細微差異並不容易。此時,這個簡單的做法會中斷,接著要投資真正的建構系統。