為什麼要建構系統?

回報問題 查看來源

本頁面會討論建構系統、其用途、為何應使用建構系統,以及為什麼在貴機構開始擴充時,編譯器和建構指令碼並不是最佳選擇。此版本適用於在建構系統上沒有太多經驗的開發人員。

什麼是建構系統?

基本上,所有建構系統都有直接的用途:將工程師編寫的原始碼轉換為可由機器讀取的可執行二進位檔。建構系統不只適用於人為編寫的程式碼,還能讓機器自動建立建構作業,無論是測試或發布正式版都一樣。在擁有數千名工程師的機構中,大多數版本往往會自動觸發,而非由工程師直接觸發。

不能只使用編譯器?

建構系統的需求未必能立即顯而易見。大多數工程師在學習編寫程式碼時不會使用建構系統,最常見的做法是直接透過指令列叫用 gccjavac 等工具,或是在整合式開發環境 (IDE) 中採用同等功能。只要所有原始碼都位於同一個目錄中,這類指令就能正常運作:

javac *.java

這會指示 Java 編譯器取得目前目錄中的每個 Java 來源檔案,並將其轉換成二進位類別檔案。在最簡單的情況下 只需要以上即可

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

當您要處理多種語言或多個編譯單元的程式碼時,建構程式碼不再只是一步驟就能完成。現在,您必須評估程式碼依附的內容,並按照適當順序建構這些部分,例如針對各部分使用不同的工具組合。如果有任何依附元件變更,您必須重複執行這項程序,避免依賴過時的二進位檔。對於平均中等大小的程式碼集,這項程序會快速變得繁瑣且容易出錯。

編譯器也不知道如何處理外部依附元件,例如 Java 的第三方 JAR 檔案。如果沒有建構系統,如要管理這項設定,可以從網際網路下載依附元件,將依附元件保存在硬碟的 lib 資料夾中,並設定編譯器從該目錄讀取程式庫。隨著時間過去,要維護這些外部依附元件的更新、版本和來源並不容易。

殼層指令碼呢?

假設興趣專案一開始就足夠簡單,只要使用編譯器即可進行建構,但您開始遇到前述的部分問題。也許您還是認為自己不需要建構系統,可以藉由一些簡單的殼層指令碼,以正確順序建構內容,將繁瑣的部分自動化。這種做法有一段時間可執行 但很快就會開始遇到更多問題

  • 這就會變得很繁瑣。隨著系統日漸複雜,您開始花費在建構指令碼上的時間幾乎就會和處理實際程式碼一樣。對殼層指令碼偵錯很麻煩,有很多入侵事件層層層疊出許多入侵行為。

  • 這類速度相當慢。為確保您不會意外使用過時的程式庫,請在每次執行建構指令碼時依序建構每個依附元件。您想新增一些邏輯來偵測哪些部分需要重新建構,但這聽起來好像很複雜,而且容易出錯。或者,您可以考慮指定每次需要重新建構的部分,但恢復為正方形。

  • 好消息:現在要發布新聞稿了!這樣更容易知道需要傳遞至 jar 指令來完成最終建構。另外,還記得如何上傳並推送至中央存放區以及建構及推送說明文件更新,並向使用者傳送通知。嗯,也許這次的呼叫是另一個指令碼...

  • 太慘了!您的硬碟當機,現在您需要重新建立整個系統。你夠聰明,能將所有來源檔案存放在版本管控系統中,但你下載的程式庫該怎麼處理呢?您可以再次找出所有這些項目,並確保這些項目與首次下載時相同版本嗎?您的指令碼可能依賴安裝在特定位置的特定工具,您能否還原相同的環境,好讓指令碼再次運作?請想想您很早之前設定的所有環境變數,讓編譯器能正常運作,但卻忘了執行呢?

  • 儘管出現問題,但您的專案已成功聘僱更多工程師。現在,您瞭解到上述問題不會引起任何災難,每當有新開發人員加入團隊時,您都必須經歷相同的啟動程序。儘管已盡最大努力,每個人的系統仍有些微差異。每個人的機器上通常會有運作無礙,而且每次都要花費幾小時的偵錯工具路徑或程式庫版本才能找出差異處。

  • 決定您需要讓建構系統自動化。理論上來說,這項操作非常簡單,您只需取得新電腦,然後利用 Cron 設定每晚執行建構指令碼即可。您仍然需要完成痛苦的設定程序,但現在沒有人腦的好處,無法偵測和解決小問題。現在,在您早上登入後,都會發現昨晚的建構失敗,因為開發人員昨天做出了可在自家系統上執行的變更,但並未在自動化建構系統上運作。每次您只是一個簡單的修正方法,卻常常發生在每天花大量時間尋找並套用這些簡單的修正。

  • 隨著專案規模的成長,建構速度會變慢。有一天,在等待建構完成的期間,您會欣然望向同事的閒置桌面,他們正在休假,希望找到能夠充分運用所有浪費運算能力的方法。

您遇到了一個常見的規模問題,對一名開發人員在最多一週或兩週內處理將近數百行程式碼 (可能只具備剛進大學的初級開發人員) 而言,只需使用編譯器即可。指令碼也許會稍微停用但當您需要跨多個開發人員及其機器協調時,即使是完美的建構指令碼也不夠了,因為要考量這些機器上的細微差異會變得非常困難。此時,這個簡單的方法就會細解,可以應投資到實際的建構系統。