[vcpkg/CMake] バージョンを指定してパッケージを導入する (マニフェストモード)
vcpkgについて
C/C++向けのパッケージマネージャです。[1]
サクッと使う分には簡単に始められます。以下はboostを使う例です。多くのvcpkgに関する情報で見られるこの使い方を「クラシックモード」と言い、本記事では省略します。
vcpkg install boost:x64-windows
vcpkg integrate install
この方法の課題は、導入するパッケージのバージョン指定が(2022年現在)できない [2] ことです。それを可能にする方法がだいぶ癖があり、メモしておきます。
以下を参考にしました。
- https://github.com/Microsoft/vcpkg/issues/1681
- https://vcpkg.readthedocs.io/en/latest/users/manifests/
- https://github.com/microsoft/vcpkg/blob/master/docs/users/versioning.md
- https://kenkyu-note.hatenablog.com/entry/2021/06/22/212309
筆者の環境
- Windows 11
- vcpkg (https://github.com/microsoft/vcpkg/commit/6f7ffeb18f99796233b958aaaf14ec7bd4fb64b2)
- CMake 3.24.3
- Visual Studio 2022 17.4.0
以下のコマンド入力はPowerShellを想定しています。(PowerShellである必要はありません。)
事前準備
例として、OpenCVを利用するプログラムをビルドしたい、という課題とします。
例題のソースコード
OpenCVのビルド情報を見るだけの、画像処理要素ゼロの簡単コードです。
#include <opencv2/opencv.hpp>
#include <iostream>
int main()
{
std::cout << cv::getBuildInformation() << std::endl;
return 0;
}
CMake
上のコードをビルドするためのCMakeを設定します。CMakeLists.txt
という名前で、C++ソースコードの隣に置きます。
cmake_minimum_required(VERSION 3.0.0)
project(my-opencv-sample)
find_package(OpenCV REQUIRED)
include_directories(
${OpenCV_INCLUDE_DIRS}
)
add_executable(
${PROJECT_NAME} main.cpp
)
target_link_libraries(
${PROJECT_NAME} ${OpenCV_LIBRARIES}
)
もしCMakeの導入がまだであれば、以下から入手しインストールします。Release CandidateでもStableでもどちらでもほぼ問題ないと思われます。
過去の導入から時間が経っている場合も再インストールをお勧めします。Visual Studioの活発な更新のため、古いCMakeでは「ビルドツールセットが見つかりません」といったエラーになることがあります。
vcpkg
公式の手引き通り導入します。
> git clone https://github.com/microsoft/vcpkg
> .\vcpkg\bootstrap-vcpkg.bat
本記事では C:/lib/vcpkg
に置いたものと仮定しています。
OpenCVという例題に起因する話でもありますが、vcpkgはディスクをかなり消費しがちで、ディスク容量は潤沢に確保しておいてください。今回であれば最低10GBくらいは欲しいです。
マニフェストモード
vcpkgのもう一つの使い方がマニフェストモードといいます。vcpkgのパッケージデータをマシン上の1か所で集中管理ではなく、各プロジェクト単位で管理するという方式です。RustのCargo, Rubyのbundler, Pythonのpyproject.toml のようなものでしょうか。
vcpkgでは、vcpkg.json
というJSONファイルにパッケージ設定を書きます。CMakeLists.txt
の隣に置きます。
{
"name": "my-opencv-project",
"version-semver": "1.0.0",
"builtin-baseline":"6f7ffeb18f99796233b958aaaf14ec7bd4fb64b2",
"dependencies": [
{ "name": "opencv4", "version>=": "4.5.5" }
],
"overrides": [
{ "name": "opencv4", "version": "4.5.5" }
]
}
2点、注意があります。
builtin-baselineとは?
謎のハッシュ値がありますね。一度指定せずに後述のCMake実行してみると、以下のように怒られ、答えを教えてくれます。とりあえずはそれをコピペしましょう。ですので初めての実行であれば空欄にでもしておきましょう。
> cmake -S . -B build
- Building for: Visual Studio 17 2022
-- Running vcpkg install
the top-level builtin-baseline () was not a valid commit sha: expected 40 hexadecimal characters.You can use the current commit as a baseline, which is:
"builtin-baseline": "6f7ffeb18f99796233b958aaaf14ec7bd4fb64b2"
vcpkgリポジトリのコミットハッシュ値らしいです。後日vcpkgを更新したい場合は、最新のpullだけでなくこの値も要更新ですね。
なぜバージョンを2回書いている?
以下が参考になります。変な仕様ですね。
突如として出現したフィールド"overrides"の中に"dependencies"のバージョンを上書きする情報を記入する。何この謎仕様。ここに記入されたバージョンは"builtin-baseline"や"version>="よりも優先され、boostは1.64.0に固定される。fmtの方はoverridesには何も記されていないので、バージョンは固定されず"builtin-baseline"以上のものがインストールされる。
完全に固定しなくてよいなら、overridesのほうを省いても良いです。
CMakeの実行
vcpkg.json を置いたら、cmake
を実行します。DCMAKE_TOOLCHAIN_FILE
にvcpkgのツールチェインパスを指定することで、自動的にvcpkgを使ってくれます。
> cmake `
-S . `
-B build `
-G "Visual Studio 17 2022" `
-A x64 `
-D CMAKE_TOOLCHAIN_FILE=C:\lib\vcpkg\scripts\buildsystems\vcpkg.cmake
長時間かかります。OpenCVの依存から本体まで、自動的にダウンロードしてはビルドしていきます。終わると、build/
以下にビルド用の各種ファイルが生成されます。今回の場合はVisual Studio向けの.vcxproj
などの構成ファイルです。
.vcxprojファイルを開いてGUIからビルドしても構いません。コマンドのまま進めたければ例えば以下のようにします。
> cmake --build build
これで念願の.exeが出来上がりました。
> ./build/Debug/my-opencv-sample.exe
General configuration for OpenCV 4.5.5 =====================================
Version control: unknown
Platform:
Timestamp: 2022-11-13T02:22:38Z
Host: Windows 10.0.19044 AMD64
(以下略)
2022年11月現在、vcpkgで普通にopencv4を取得すると4.6.0が入るはずのところ、4.5.5にできているのが確認できました。
思うところ・注意点
- いまのところvcpkg.jsonは手打ちしかないと理解しています。コマンドでのサポートが欲しいですね。
- バージョン固定はこれで完璧、と言いたいところですが、現実にはうまくいかない例が多いです。例えばOpenCVでは、本記事で述べた4.5.5はできるのですが、4.5.1や4.5.2等はvcpkgによる依存ライブラリのビルドにてエラーになります。特定の番号にこだわりなく、何でもよいから固定しておきたいのであればよいですが、訳あって決め打ちのバージョンが欲しい場合は運次第です。
-
Microsoftが出していることや、"vc" という名づけに関わらず、Windows以外でも利用可能です。 ↩︎
-
公式の最新vcpkgを取得してシンプルに使う場合 ↩︎
-
コメントの例1: https://github.com/Microsoft/vcpkg/issues/1681#issuecomment-487154857 ↩︎
-
コメントの例2: https://github.com/Microsoft/vcpkg/issues/1681#issuecomment-933054175 ↩︎
Discussion