利用Vcpkg輕鬆集成開源第三方庫


1. 爲什麼要用Vcpkg

1.1. 傳統使用開源庫的方法

Windows下開發C/C++程序,少不了編譯開源的第三方庫。比如用於網絡連接的高性能庫libcurl、用於壓縮解壓的zlib等等。使用這些庫開發極大的方便了程序員,使得我們不必重複造輪子。但是使用這些庫必須要處理以下問題。

1.1.1. 編譯工具

由於這些開源庫絕大部分都來源於Linux系統,導致其工程文件、編譯系統都使用gnu系列工具,使得將其移植到Windows的VC開發環境下一直是難點。儘管最近幾年很多開源庫都支持了跨平臺的cmake,但是編譯過程仍然複雜和多樣化。

常見的編譯方式有:

編譯方式 特點 舉例
configure、make 需要msys這樣的unix環境纔可以編譯 ffmpeg
自定義編譯工具 需要學習特定的編譯命令和工具 openssl、boost
cmake 相對簡單輕鬆 libcurl
VC工程文件 這種最簡單,直接拿來即可編

1.1.2. 編譯類型

當了解了這些還不夠,我們還需要考慮預先編譯出哪種類型的開源庫程序。比如:Debug還是Release、動態庫還是靜態庫、MD還是MT、32位還是64位。光是這三種組合就有16種可能性。如果像libcurl這種還要考慮是否引用其他開源庫的功能,那麼編譯類型的組合會更多。管理起來很麻煩。

1.1.3. 工程目錄設定

由於多樣的編譯類型,工程目錄也必須仔細設定才能保證自己的軟件項目能夠正常編譯。

1.2. Vcpkg的優點

  • 自動下載開源庫源代碼
  • 源碼包的緩存管理和版本管理,可以升級版本
  • 輕鬆編譯
  • 依賴關係檢查(比如編譯libcurl,會自動下載zlib、openssl進行編譯)
  • 無縫集成Visual Studio,不需要設置庫文件、頭文件的所在目錄,自動集成。
  • Visual Studio全平臺支持,不僅支持Debug/Release、x86/x64編譯,還支持UWP、ARM平臺的編譯。

2. 獲取Vcpkg

2.1. 下載Vcpkg

Vcpkg的官方源碼站點爲:

https://github.com/microsoft/vcpkg

一般地,你可以使用git命令克隆一個當前版本下來,或者直接下載壓縮包。

git clone https://github.com/microsoft/vcpkg1

2.2. 編譯Vcpkg

注意:

Vcpkg大量使用的psl腳本,所以官方強烈推薦使用PowerShell而不時CMD命令行來執行各種操作。儘管在使用的時候兼容CMD,但是在編譯這一步,請使用PowerShell。

編譯很簡單,使用PowerShell執行Vcpkg工程目錄下的“bootstrap-vcpkg.bat”命令,即可編譯。編譯好以後會在同級目錄下生成vcpkg.exe文件。編譯期間,腳本會自動下載vswhere組件。

3. 使用Vcpkg

3.1. 查看Vcpkg支持的開源庫列表

執行命令

.\vcpkg.exe search1

3.2. 安裝一個開源庫

這裏的“安裝”其實是指下載和編譯。

比如我們需要安裝常用的jsoncpp庫,那麼執行命令

.\vcpkg.exe install jsoncpp1

輸出:

The following packages will be built and installed:
    jsoncpp[core]:x86-windows
Starting package 1/1: jsoncpp:x86-windows
Building package jsoncpp[core]:x86-windows...
-- CURRENT_INSTALLED_DIR=H:/Repos/vcpkg/installed/x86-windows
-- DOWNLOADS=H:/Repos/vcpkg/downloads
-- CURRENT_PACKAGES_DIR=H:/Repos/vcpkg/packages/jsoncpp_x86-windows
-- CURRENT_BUILDTREES_DIR=H:/Repos/vcpkg/buildtrees/jsoncpp
-- CURRENT_PORT_DIR=H:/Repos/vcpkg/ports/jsoncpp/.
-- Downloading https://github.com/open-source-parsers/jsoncpp/archive/1.8.1.tar.gz...
-- Downloading https://github.com/open-source-parsers/jsoncpp/archive/1.8.1.tar.gz... OK
-- Testing integrity of downloaded file...
-- Testing integrity of downloaded file... OK
-- Extracting source H:/Repos/vcpkg/downloads/open-source-parsers-jsoncpp-1.8.1.tar.gz
-- Extracting done
-- Configuring x86-windows-rel
-- Configuring x86-windows-rel done
-- Configuring x86-windows-dbg
-- Configuring x86-windows-dbg done
-- Build x86-windows-rel
-- Build x86-windows-rel done
-- Build x86-windows-dbg
-- Build x86-windows-dbg done
-- Performing post-build validation
-- Performing post-build validation done
Building package jsoncpp[core]:x86-windows... done
Installing package jsoncpp[core]:x86-windows...
Installing package jsoncpp[core]:x86-windows... done
Elapsed time for package jsoncpp:x86-windows: 47.81 s

Total elapsed time: 47.81 s

The package jsoncpp:x86-windows provides CMake targets:

    find_package(jsoncpp REQUIRED)
    target_link_libraries(main PRIVATE jsoncpp_lib)123456789101112131415161718192021222324252627282930313233343536

我們大致可以瞭解到install會經歷這幾個過程:

  • 環境初始化
  • 下載源代碼(如果已經在cache中,則不下載)
  • 校驗文件有效性
  • 解壓縮源代碼
  • 利用配套工具配置源碼工程,在這裏是使用的是cmake(如果是ffmpeg,則用msys2)
  • 編譯源碼。一般會同時編譯Release和Debug版本。
  • 把編譯好的文件拷貝到相關目錄中去(一般是installed目錄)

注意點:

如果電腦中沒有安裝cmake,vcpkg會自動下載portable版本的cmake。但是由於各種原因,下載的網速很慢,所以建議先自行下載安裝msi版本的cmake。最好是下載最新版本的cmake。

3.3. 指定編譯某種架構的程序庫

如果不指定安裝的架構,vcpkg默認把開源庫編譯成x86的Windows版本的庫。那vcpkg總共支持多少種架構呢?我們可以使用如下命令便知:

.\vcpkg.exe help triplet1

我們可以看到會列出如下清單:

  • arm-uwp
  • arm-windows
  • arm64-uwp
  • arm64-windows
  • x64-uwp
  • x64-windows-static
  • x64-windows
  • x86-uwp
  • x86-windows-static
  • x86-windows

這個清單以後隨着版本的迭代還會再增加。vcpkg不僅支持x86架構,還支持arm架構。注意:這裏的arm架構特指類似於surface這種運行在arm處理器上的Win10平臺,而並非我們傳統意義上的Linux或android的ARM平臺。

那如果要安裝編譯某一個架構的開源庫,我們該怎麼寫呢?我們只需要在需要安裝的包後面指定相應的triplet即可。例如我們需要編譯64位版本的jsoncpp,那麼執行如下命令即可。

.\vcpkg.exe install jsoncpp:x64-windows

3.4. 移除一個已經安裝(編譯)的開源庫

如果移除一個已經安裝的開源庫,那麼執行remove指令即可。比如我們要移除jsoncpp,那麼執行命令:

.\vcpkg.exe remove jsoncpp1

注意:

  • 這個時候只是移除了默認的x86-winodws版本的文件,如果有其他平臺的版本需要移除,需要制定相應的triplet。
  • 移除也只是移除了二進制程序庫而已,源碼包和解壓縮的源碼並沒有刪除。

如果想要一鍵移除“過時”的包,執行命令:

.\vcpkg.exe remove --outdated1

3.5. 列出已經安裝的開源庫

執行list指令即可,例如:

.\vcpkg.exe list1

3.6. 更新已經安裝的開源庫

一般有兩種更新方式。一個是update指令,可以顯示可以升級的開源庫的列表。另一個是upgrade的指令,會重新編譯所有需要更新的包。

3.7. 導出已經安裝的開源庫

有的時候,一個項目組中有很多人,不需要每個人都參與編譯。一個人編譯好所有開源庫後到處給別人即可。有的時候也是出於備份的目的,也會導出已經安裝的開源庫。導出可以執行export指令。例如,我要導出jsoncpp庫,那麼執行:

.\vcpkg.exe export jsoncpp --7zip1

注意,導出時必須指定導出的包格式。vcpkg支持5種導出包格式,有:

參數 格式
–raw 以不打包的目錄格式導出
–nuget 以nuget包形式導出
–ifw 我也不知道這是啥格式
–zip 以zip壓縮包形式導出
–7zip 以7z壓縮包形式導出

一般地,導出包的格式爲:vcpkg-export-<日期>-<時間>

默認情況下只會導出x86-windows的包,如果要導出所有包,那需要制定相應的triplet。比如,如果同時導出x86和x64版本的jsoncpp,那執行命令:

.\vcpkg.exe export jsoncpp jsoncpp:x64-windows --7zip1

這個命令等價於:

.\vcpkg.exe export jsoncpp:x86-windows jsoncpp:x64-windows --7zip1

如果要指定輸出目錄和特定文件名,需使用”–output=”參數

3.8. 導入備份的開源庫

導入比較簡單,執行import指令即可。例如:

.\vcpkg.exe import xxx.7z1

4. Vcpkg和Visual Studio的集成

4.1. 什麼是集成?

上面我們已經安裝了一些第三方庫,那如何使用呢?常規情況下,我們需要設置include目錄、lib目錄等,會有很多工作量。Vcpkg提供了一套機制,可以全自動的適配目錄,而開發者不需要關心已安裝的庫的目錄在哪裏,也不需要設置。這是Vcpkg的一大優勢。

4.2. 集成到全局

“集成到全局”適用於Visual Studio開發環境和msbuild命令行。執行命令:

.\vcpkg integrate install1

當出現“Applied user-wide integration for this vcpkg root.”字樣的時候,說明已經集成成功。這時候可以在任意的工程中使用安裝好的第三方庫。

4.3. 移除全局集成

移除全局集成只要執行下列命令即可:

.\vcpkg integrate remove

4.4. 集成到工程

上面已經可以集成到全局,爲什麼還要“集成到工程”呢?因爲在大部分情況下,我們不希望集成到全局,畢竟有很多第三方庫我們希望自定義處理一下,或者乾脆不想集成第三方庫。那麼集成到工程是最靈活的處理方式。也是工程級項目推薦的處理方式。

“集成到工程”是整個vcpkg中最複雜的一項,它需要利用Visual Studio 中的nuget插件來實現。我們接下來一步一步來說。

4.4.1. 生成配置

執行命令

.\vcpkg integrate project1

這時候會在“\scripts\buildsystems”目錄下,生成nuget配置文件.

其中是指vcpkg實際所在目錄。

4.4.2. 基本配置

打開Visual Studio,點擊菜單“工具->NuGet包管理器->程序包管理器設置”,進入設置界面,點擊“程序包源”。
在這裏插入圖片描述
點擊“加號”增加一個源。修改源的名字爲vcpkg。在“源”的選項中點擊右側的”…”選擇vcpkg目錄下的“scripts\buildsystems”目錄,然後點擊右側的“更新按鈕”。

點擊“確定”,關閉設置對話框。

到此,全局性的設置已經完成,以後不必再重複設置了。

4.4.3. 工程配置

用Visual Studio 打開一個工程或解決方案。右鍵點擊需要設置的工程,選擇“管理NuGet程序包”。在右上角的“程序包源”中選擇剛剛設置的“vcpkg”。這樣在“瀏覽”選項卡中就可以看到“vcpkg.H.Repos.vcpkg”。點擊最右側的“安裝”。這樣就可以集成到某個工程了。
在這裏插入圖片描述
在這裏插入圖片描述

4.5. 集成到CMake

最新的Visual Studio 2015和2017大力支持CMake工程,所以對cmake的支持當然不能少。在cmake中集成只要在cmake文件中加入下面這句話即可。

-DCMAKE_TOOLCHAIN_FILE=/scripts/buildsystems/vcpkg.cmake”

其中是指vcpkg實際所在目錄。

4.6. 集成靜態庫

Vcpkg默認編譯鏈接的是動態庫,如果要鏈接靜態庫,目前還沒有簡便的方法。需要做如下操作

  1. 用文本方式打開vcxproj工程文件
  2. 在xml的段裏面增加如下兩句話即可
<VcpkgTriplet>x86-windows-static</VcpkgTriplet>
<VcpkgEnabled>true</VcpkgEnabled>12

在CMake中集成靜態庫,需要額外指令

cmake … -DCMAKE_TOOLCHAIN_FILE=…/vcpkg.cmake -DVCPKG_TARGET_TRIPLET=x86-windows-static1

5. 使用Vcpkg時的注意點

  • Vcpkg僅支持Visual Studio 2015 update 3及以上版本(包括Visual Studio 2017),究其原因,很可能和c++11的支持度以及集成原理有關係。
  • 目前Vcpkg編譯靜態庫,默認只支持MT模式。

6. 小結

Vcpkg目前還在不斷的完善中,但不可否認,它已經極大的減少了我們在項目啓動時,準備第三方庫的時間。提高了工作效率。按照時髦的話來說,就是避免了重複造輪子。目前Vcpkg已經集成了上百個常用的開源庫,而且數量還在不停增長。畢竟是微軟旗下的開源項目,質量還是可以得到保障的,完全可以在工業級項目中得以使用。源代碼託管在github上,github社區很活躍,有興趣的朋友也可以參與進來。

發佈了77 篇原創文章 · 獲贊 14 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章