美思 [C 語言] 程式設計教學:使用自動化編譯系統 (Build Automation System)

C 語言專案開發工具
Facebook Twitter LinkedIn LINE Skype EverNote GMail Yahoo Email

前言

對於有一定規模的 C 專案,不會把所有的程式碼寫在同一個檔案中,而會將程式碼以模組化的方式細分在不同檔案中,並用自動編譯軟體來管理編譯、測試、安裝等工作流程。

嚴格上來說,C 語言沒有官方的自動編譯系統。在不同系統上各自發展出管理 C 專案的方式。常見的有以下數種方案:

  • IDE 附帶的自動編譯軟體
  • Make
  • Autotools
  • CMake
  • Ninja
  • Bazel

使用 IDE 來管理 C 專案

對於個人開發者來說,直接使用 IDE 來管理專案是最簡單的。因為不需要手動設置專案設定檔,可以馬上開始寫 C 程式碼。所以 Visual Studio 這類整合 C 編譯器和 IDE 的開發工具對於初學者來說很受歡迎。

但對開發團隊來說,使用 IDE 管理軟體專案可能是次佳的選擇,因為這樣限縮團隊中各個開發者可用的開發工具。這裡的團隊不僅是同一公司的軟體工程師,許多自由軟體開發者透過雲端軟體共同管理軟體專案,形成虛擬團隊。

一個常見的例子是使用 Visual Studio 內附的 MSBuild 來管理軟體專案。目前 (西元 2019 年) 來說,純 Windows 專案使用 Visual Studio 來管理是相當常見的選項。但若該專案需要跨多個平台,就不適合用 Visual Studio 來管理。

若要用 IDE 來管理專案,不僅要使用相同 IDE,最好該 IDE 也要相同主版本,以確保專案的相容性。Visual Studio 的專案往往會在升級後無法降級,最後只得手動重建專案。所以不要貿然將專案升級到新版本的 Visual Studio。

使用 Make 管理 C 專案

Make 是自動化編譯軟體的濫觴,在 Unix 及類 Unix 系統上相當流行,在 Windows 上也可見 Make 的移植品。由於 Make 是 POSIX 標準的一部分 (參考這裡),大部分類 Unix 系統上都有某種 Make 的實作品。

使用 Make 的好處在於不綁定任何 IDE,在命令列環境下也可以工作。但使用 Make 需要自行撰寫設定檔 (通常稱為 Makefile),上手比較困難。

要注意 Make 不是單一的軟體,而有數種實作品。不同 Make 實作品的 Makefile 語法會有一些差異。常見的 Make 實作品有 POSIX Make 和 GNU Make 等。目前主流的系統都有 GNU Make 可用,所以不用刻意守在 POSIX Make 的語法。

當專案使用者所在的系統和專案的設定檔相異時,專案使用者得手動編輯 Makefile 。中大型專案的 Makefile 往往也相當複雜,要手動修改相當不方便。於是,出現 Autotools 這種可偵測系統狀態、自動生成 Makefile 的軟體。詳見下一節。

使用 Autotools 管理 C 專案

要維護跨平台的 Makefile 相容不容易。讓專案使用者自行修改 Makefile 也不是很方便的做法。因此,出現 Autotools 這類自動生成 Makefile 的軟體。解決了原本 Makefile 在異質平台間的的相容性議題。

Autotools 在 C 專案中以 configure 這隻命令稿存在。要編譯 C 專案時,先呼叫 configure 命令稿:

$ ./configure

這時候 configure 會自動偵測系統的狀態,生成相對應的 Makefile 。若宿主系統不符合編譯此專案的需求時, configure 會中止並吐出提示訊息。此外,呼叫 configure 時,可額外加入參數,用來改變 configure 的行為。

然後用 make(1) 編譯專案:

$ make

如果要把編譯好的 C 程式安裝到系統目錄,可使用以下指令:

$ sudo make install

在 Unix 或類 Unix 系統上拿到上游 (upstream) 原始碼專案時,通常都是使用這三個步驟來編譯及安裝程式。

但 Autotools 僅限於 Unix 或類 Unix 系統上才能使用,Windows 則無法使用以 Autotools 管理的 C 專案。所以才會出現 MSYS2 這類開發工具,用來解決在 Windows 系統上使用 Autotools 的議題。

但這樣處理算是繞一圈,畢竟 Windows 缺乏原生的 Autotools 支援。因此,出現 CMake 這類跨平台的專案管理軟體。請見下一節。

使用 CMake 管理 C 專案

CMake 和 Autotools 概念相似,但支援更廣。不僅在 Unix 或類 Unix 系統上可生成 Makefile ,在 Windows 上也可生成給 Visual Studio 使用的 MSBuild 設定檔。此外,CMake 還支援一些較少見的專案設定檔格式,像是 Code::Blocks 的設定檔。這裡列出 CMake 所支援的專案設定檔格式。

CMake 在近幾年受到商業公司的注目。像是 CLions 一開始就採用 CMake 管理專案。甚至 Visual Studio 開始接受以 CMake 為基礎的專案 (參考這裡)。微軟主導的 C 和 C++ 套件管理軟體 vcpkg 也以 CMake 管理套件。所以 CMake 的確是值得注意的自動編譯系統。

使用 Ninja 管理 C 專案

註:ninja 在日文中是忍者的意思。

前面數節所述的自動編譯系統算是有點歷史的軟體。相對來說,Ninja 則是較新的自動編譯系統。

Ninja 著重於速度而非易寫性,故不建議直接用 Ninja 來管理 C 專案。甚至 Ninja 官方團隊也列出可以生成 Ninja 專案設定檔的開發工具。前一節介紹的 CMake 就可以生成 Ninja 專案設定檔,所以不需要刻意去學 Ninja 的語法。

使用 Bazel 管理 C 專案

Bazel 原本是 Google 內部使用的自動編譯系統的一部分,後來成為開放原始碼專案。Bazel 可以用來管理 C、C++、Objective-C、Java、Android 等類型的專案。Bazel 主要是針對大型專案而設計,小型專案無法充分感受 Bazel 的益處。

如何選擇?

對於 C 語言學習者來說,一開始用 IDE 來專理專案無妨。因為這個階段寫的 C 專案只有自己撰寫和維護,不需考慮團隊合作。而且,在學習 C 語言的早期,重點應該是 C 語言本身。專案管理算是額外的工作,不用太費心在這上面。

如果要對外發佈的 C 專案,應該認真地考慮使用自動編譯軟體。除非專案只在 Unix 或類 Unix 糸統上編譯和運行,應優先考慮 CMake 而非 Autotools。至於 Visual Studio 則只保留給 Windows 限定的 C 專案。

在後續的文章中,我們會分別用 CMake 建立命令列程式專案和函式庫專案,以展示 CMake 的使用方式。

關於作者

身為資訊領域碩士,美思認為開發應用程式的目的是為社會帶來價值。如果在這個過程中該軟體能成為永續經營的項目,那就是開發者和使用者雙贏的局面。

美思喜歡用開源技術來解決各式各樣的問題,但必要時對專有技術也不排斥。閒暇之餘,美思將所學寫成文章,放在這個網站上和大家分享。