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


1. 為什么要用Vcpkg

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

    1.1.1. 編譯工具

    1.1.2. 編譯類型

    1.1.3. 工程目錄設定

  1.2. Vcpkg的優點

2. 獲取Vcpkg

  2.1. 下載Vcpkg

  2.2. 編譯Vcpkg

3. 使用Vcpkg

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

  3.2. 安裝一個開源庫

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

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

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

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

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

  3.8. 導入備份的開源庫

4. Vcpkg和Visual Studio的集成

  4.1. 什么是集成?

  4.2. 集成到全局

  4.3. 移除全局集成

  4.4. 集成到工程

    4.4.1. 生成配置

    4.4.2. 基本配置

    4.4.3. 工程配置

  4.5. 集成到CMake

  4.6. 集成靜態庫

5. 使用Vcpkg時的注意點

6. 小結

 

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

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

常見的編譯方式有:

 

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

2.2. 編譯Vcpkg

注意:

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

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

3. 使用Vcpkg
3.1. 查看Vcpkg支持的開源庫列表
執行命令

.\vcpkg.exe search

輸出:

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)

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

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

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

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

.\vcpkg.exe help triplet

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

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 jsoncpp

注意:

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

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

.\vcpkg.exe remove --outdated

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

執行list指令即可,例如:

.\vcpkg.exe list

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

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

.\vcpkg.exe export jsoncpp --7zip

 

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

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

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

這個命令等價於:

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

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

3.8. 導入備份的開源庫

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

.\vcpkg.exe import xxx.7z

4. Vcpkg和Visual Studio的集成

4.1. 什么是集成?


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

4.2. 集成到全局


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

 .\vcpkg integrate install

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

4.3. 移除全局集成

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

 .\vcpkg integrate remove

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

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

4.4.1. 生成配置
執行命令

 .\vcpkg integrate project

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

其中<vcpkg_dir>是指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=<vcpkg_dir>/scripts/buildsystems/vcpkg.cmake" --好像不好使 20220326
SET(CMAKE_TOOLCHAIN_FILE "D:/code/github/vcpkg/scripts/buildsystems/vcpkg.cmake")

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

4.6. 集成靜態庫

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

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

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

cmake .. -DCMAKE_TOOLCHAIN_FILE=.../vcpkg.cmake -DVCPKG_TARGET_TRIPLET=x86-windows-static

5. 使用Vcpkg時的注意點
Vcpkg僅支持Visual Studio 2015 update 3及以上版本(包括Visual Studio 2017),究其原因,很可能和c++11的支持度以及集成原理有關系。
目前Vcpkg編譯靜態庫,默認只支持MT模式。
6. 小結
Vcpkg目前還在不斷的完善中,但不可否認,它已經極大的減少了我們在項目啟動時,准備第三方庫的時間。提高了工作效率。按照時髦的話來說,就是避免了重復造輪子。目前Vcpkg已經集成了上百個常用的開源庫,而且數量還在不停增長。畢竟是微軟旗下的開源項目,質量還是可以得到保障的,完全可以在工業級項目中得以使用。源代碼托管在github上,github社區很活躍,有興趣的朋友也可以參與進來。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM