位元詩人 [Windows] 程式設計教學:用 vcpkg 安裝 C 或 C++ 函式庫

Facebook Twitter LinkedIn LINE Skype EverNote GMail Yahoo Email

前言

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 上安裝 C 或 C++ 開發所用的工作負載

如果讀者已經安裝過 Visual Studio 2019 了,也不需要移除,只要重新執行 Visual Studio Installer,選擇必要的工作負載即可。

此外,要選擇必要的語言套件「英文」:

在 Visual Studio 2019 中選擇「英文」套件

如果沒有選擇這個項目,在編譯 vcpkg 時會報錯。即使裝了英文的語言套件,介面仍然可以繼續用中文,只是多一個語言套件包。

安裝 vcpkg

在接下來的操作中,會用到 「x64 Native Tools Command Prompt for vS 2019」:

Visual Studio 2019 中的 Visual C++ 的終端機視窗

這個命令列環境除了 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 設定,選擇「時間與語言」:

在 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 目錄中,產生執行檔,點擊即可開啟視窗:

GTK+ 的 Hello World 程式

這裡展示的指令比較複雜,原本的出處在這裡,有需要的讀者可自行參考。

結語

對於使用 C 或 C++ 撰寫應用程式的程式人來說,vcpkg 的出現,解決了 Windows 系統下缺乏套件管理軟體的情形,日後要使用 C 或 C++ 撰寫應用程式應該會更加容易。不過,vcpkg 算是一個相對新穎的專案,目前沒有辦法像 Homebrew 等成熟的套件管理軟體般易用,要多多試誤和除錯。我們希望微軟能持續地維護 vcpkg,社群也多給予使用上的回饋,讓 vcpkg 發展得更好。

關於作者

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

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