前言
C 和 C++ 的函式庫 (library) 並沒有套件 (package) 的概念,而是以標頭檔 (header) 和二進位檔 (binary file) 的形式來發佈。至於 GNU/Linux 或其他類 Unix 系統上常見的函式庫套件並不是 C 或 C++ 工具鍵 (toolchain) 原本的功能,而是後來才外加上去的檔案格式。
原本 Windows 不太注重套件的概念,開發者就自行將標頭檔和二進位檔複製到 C 或 C++ 專案中即可。後來微軟試著想弄搭配 Visual Studio 用的套件管理軟體;一開始是用 NuGet,推廣得不太成功;至於 vcpkg 則是這陣子推出的方案。筆者以為 vcpkg 在理念上是好東西,但這東西還很新,文件相對少;使用上不一定都很順利,碰到問題要有耐心除錯。
在本文中,我們以 GTK+ 版本的 Hello World 程式為範例,展示 vcpkg 的使用方式。GTK+ 原本是 GNU/Linux 上的圖形介面函式庫,以 C 語言實作,後來移植到 Windows 在內的多個平台上,算是一個成熟的圖形介面函式庫。
安裝 Visual Studio 2019
經筆者實測,使用 Visual Studio 2017 或 Visual Studio 2019 皆可,此處以 Visual Studio 2019 為例。在安裝時要選擇必要的工作負載 (workload)「使用 C++ 的桌面開發」:
如果讀者已經安裝過 Visual Studio 2019 了,也不需要移除,只要重新執行 Visual Studio Installer,選擇必要的工作負載即可。
此外,要選擇必要的語言套件「英文」:
如果沒有選擇這個項目,在編譯 vcpkg 時會報錯。即使裝了英文的語言套件,介面仍然可以繼續用中文,只是多一個語言套件包。
安裝 vcpkg
在接下來的操作中,會用到 「x64 Native Tools Command Prompt for vS 2019」:
這個命令列環境除了 Windows 終端機原本的功能外,還對終端機做了一些額外的設定,所以在該終端機內可以用 Visual C++ 編譯 C 和 C++ 原始碼。vcpkg 本身和該專案所發布的套件都是以原始碼的形式發佈,下載後需要再重新編譯成二進位檔。
在 vcpkg 裡面有許多套件都來自於自由軟體,在 Windows 上沒有 shell 環境要怎麼編譯這些套件呢?vcpkg 的做法是幫這些套件重新寫 CMake 設定檔,就可以繞過在 Windows 上無法用 Autotools (GNU Build System) 的問題。其實這樣有點重造輪子,因為這些套件在類 Unix 系統上已經可以編譯了,但微軟肯花時間維護這些自由軟體的 CMake 設定檔,基本上還算佛心。
在本文中,我們將 vcpkg 安裝到 C:\tools 目錄中,讀者可自己更改到其他位置。這裡用 Git 將整個 vcpkg 專案拷貝 (clone) 下來:
C:\tools> git clone https://github.com/Microsoft/vcpkg.git
C:\tools> cd vcpkg
輸入以下指令以編譯 vcpkg:
C:\tools\vcpkg> .\bootstrap-vcpkg.bat
該命令稿內部會自行呼叫 PowerShell 來執行編譯的動作,所以在傳統的 Windows 終端機內也可以使用。編譯 vcpkg 的時間並不會太久,稍微等一下即可。
接著,將 vcpkg 整合到 Visual Studio 中:
C:\tools\vcpkg> .\vcpkg.exe integrate install
Applied user-wide integration for this vcpkg root.
All MSBuild C++ projects can now #include any installed libraries.
Linking will be handled automatically.
Installing new libraries will make them instantly available.
CMake projects should use: "-DCMAKE_TOOLCHAIN_FILE=c:/tools/vcpkg/scripts/buildsystems/vcpkg.cmake"
之後 Visual Studio 就會自動偵測到 vcpkg 內的套件。不過,筆者只是拿 Visual C++ 來編譯套件,沒有用到 IDE 的部分,有興趣的讀者可自行嘗試。
安裝 GTK+
在編譯 gtk 時,要修改「系統地區設定」,這是為了編譯 glib 套件的緣故,而 glib 是 gtk 的相依套件 (參考這裡)。
進入 Windows 設定,選擇「時間與語言」:
在「地區與語言」這個子類別中選擇「系統管理語言設定」 (要稍微向下捲一下視窗):
選擇「變更系統地區設定」:
將「系統地區設定」調成「英文 (美國)」:
調整完後,需要重新開機,讓更動生效。編譯 gtk 後,可再將「系統地區設定」重新調回原本的語系,只是在編譯程式時會跳警告訊息,但仍可編譯成功。
重回 Visual C++ 的終端機環境,使用以下指令編譯 gtk:
C:\tools\vcpkg> .\vcpkg install gtk:x64-windows
預設情形下,vcpkg 會編譯 32 位元的套件,但在 64 位元的系統上,不一定要守著 32 位元的機械碼,故此處改用 64 位元的套件。
建置 GTK+ 版本的 Hello World 專案
接下來,應該要寫一些小程式來試試 gtk 套件;為了節省各位讀者的時間,筆者寫了一個 GTK+ 版本的 Hello World 程式,讓讀者省下寫程式的時間,專心學 vcpkg 的用法即可。讀者要自己重寫範例程式也可以,但要注意一定要寫相對應的 CMake 設定檔,因為 vcpkg 相關的設定檔也是用 CMake 寫的。
將工作目錄移動到專案所在的根目錄後,建立 build 子目錄:
C:\path\to\project> mkdir build
C:\path\to\project> cd build
若使用 Visual Studio 2017,則輸入以下的 CMake 指令:
C:\path\to\project\build> cmake .. -G"Visual Studio 15 2017" -DVCPKG_TARGET_TRIPLET=x64-windows -Ax64 -DCMAKE_PREFIX_PATH="C:/tools/vcpkg/installed/x64-windows" -DCMAKE_TOOLCHAIN_FILE="C:\tools\vcpkg\scripts\buildsystems\vcpkg.cmake" -DCMAKE_GENERATOR_PLATFORM=x64
這個指令比較長,建議讀者不要硬背這個指令,而要去拆解該指令每個參數的意義,之後才能根據自己的需求去變化。
-G
代表指定 CMake 的 generator。CMake 跨平台的秘訣在於可以生成對應不同平台和編譯環境的專案設定檔。此處使用 "Visual Studio 15 2017"
,代表生成 Visual Studio 2017 的專案設定檔。
-D
代表專案的設定,在這個指令中,這些專案相關設定會傳到 Visual Studio 2017 的專案設定檔中。VCPKG_TARGET_TRIPLET
是設定 vcpkg 所用的目標架構 (參考這裡),此處選擇 x64-windows
,代表是 64 位元的 Windows 平台。
CMAKE_PREFIX_PATH
是設定 vcpkg 中安裝套件所在的位置。由於 Windows 沒有採用類似於類 Unix 系統的 /user/include 或 /usr/lib 等系統目錄,而是把套件集中在同一個目錄中,所以我們要自行指定該目錄所在的位置。如果讀者前往該目錄觀看,會發現該目錄內的架構很像類 Unix 系統中的系統目錄。
CMAKE_TOOLCHAIN_FILE
則是指定工具鍵所在的設定檔,這樣 CMake 才能吃到 vcpkg 的設定檔。同樣也是要自行指定 vcpkg 所在的目錄。
CMAKE_GENERATOR_PLATFORM
則是指定 generator 的平台,此處設為 x64
,表示採用 64 位元架構。
若使用 Visual Studio 2019,只要修改 generator 的部分即可:
C:\path\to\project\build> cmake .. -G"Visual Studio 16 2019" -DVCPKG_TARGET_TRIPLET=x64-windows -Ax64 -DCMAKE_PREFIX_PATH="C:/tools/vcpkg/installed/x64-windows" -DCMAKE_TOOLCHAIN_FILE="C:\tools\vcpkg\scripts\buildsystems\vcpkg.cmake" -DCMAKE_GENERATOR_PLATFORM=x64
如果 Visual Studio 內附的 CMake 不夠新的話,會無法產生適用於 Visual Studio 2019 的專案,這時候可自行安裝新版的 CMake。
生成 Visual Studio 專案設定檔後,要手動修改專案的 VcpkgEnabled 屬性 (參考這裡):
<PropertyGroup Label="Globals">
...
<VcpkgEnabled>true</VcpkgEnabled>
</PropertyGroup>
筆者無法確定為什麼 Visual Studio 要把這項屬性關閉,請手動調一下設定檔。
以本範例程式來說,要將 vcpkg/installed/x64-windows/lib/gtk-3.0.lib 複製一份,命名為 gtk.lib 並放在相同的目錄。要不然編譯時會報錯。
最後輸入以下指令即可編譯此範例程式:
C:\path\to\project\build> cmake --build . -- /t:Rebuild /p:Configuration=Release /p:Platform=x64
最後在 build/Release 目錄中,產生執行檔,點擊即可開啟視窗:
這裡展示的指令比較複雜,原本的出處在這裡,有需要的讀者可自行參考。
結語
對於使用 C 或 C++ 撰寫應用程式的程式人來說,vcpkg 的出現,解決了 Windows 系統下缺乏套件管理軟體的情形,日後要使用 C 或 C++ 撰寫應用程式應該會更加容易。不過,vcpkg 算是一個相對新穎的專案,目前沒有辦法像 Homebrew 等成熟的套件管理軟體般易用,要多多試誤和除錯。我們希望微軟能持續地維護 vcpkg,社群也多給予使用上的回饋,讓 vcpkg 發展得更好。