🦋

vcpkg を用いた Win/Mac/Linux用 c++プログラムの cmake & vscode 実行例

2023/08/12に公開

vcpkg は Microsoft のオープンソースの c/c++ ライブラリ用のパケージ管理ツールです。

ライブラリのStatic/Sharedの選択が簡単にできたり、VS 統合や専用の cmake スクリプトを用いることでヘッダや .lib のファイル&ディレクトリ設定が簡素化できたりします。

MSのサイトにvcpkg のドキュメント(英語版)があるので、MS公式感はあります。

リポジトリをみると 2016 年からのプロジェクトで、2023-08 現在ざっくり 2000 ライブラリ以上に対応しているようです。

vcpkg は Visual Studio(2017~2022) との統合ができ vc 用ツールとして便利なモノですが、Mac・Linux にも対応しており、cmake ビルドを行えるようにすれば vscode でのデバッグ実行も楽に行えるので、マルチプラットフォームのソフト開発にもよさそうです。

ということで、wxwidgets の hello サンプルを、cmake を用いて vc, Mac, Linux でビルドしたり、vscode で実行したりしたときのメモ書です。(VS統合でのメモ書はこちら)


vcpkg のインストール

Windows / Visual Studio でのインストール

※以下は Windows 10 x64 に Visual Studio 2022 Community, git for Windows をインストールした環境で行いました。

git コマンドと、Visual Studio(2015upd3~2022) が 1つはインストールされている PC にて、コマンドプロンプトを開きます。

任意のディレクトリでよいですが、ここでは、c:\vcpkg にインストールするとして、

cd /d c:\
git clone https://github.com/microsoft/vcpkg
cd vcpkg
bootstrap-vcpkg.bat

を実行すれば、vcpkg をクローンして vcpkg.exe が作成されます。

複数の Visual Studio が PC にインストールされている場合、vcpkg.exe の作成やライブラリのビルドでは、PC にインストールされた中で最新の vc が使用されるようです。

VS2015(vc14.0)~ VS2022(vc14.3)はわりと互換があるので、新しい vc でビルドしたライブラリも古い vc で使用できたりしますが、ものによってはランタイムライブラリのバージョンの違いでリンクエラーが発生することもあるため、ライブラリ・インストール時と同じ環境を使うほうが良さそうです。

環境変数の頁を見ると VCPKG_VISUAL_STUDIO_PATH あたりで vc を選択できそうですが、未確認。

Mac でのインストール

arm64 mac、macos 13.3.1 で試しました。

c/c++ 開発に必要な Xcode 関係一式インストール済み、brew 等で cmake 等メジャーなツールがインストール済みとします。

vcpkg は ~/vcpkg にインストールするとします。

ホーム ~/ ディレクトリにて

git clone https://github.com/microsoft/vcpkg
cd vcpkg
./bootstrap-vcpkg.sh

で vcpkg がインストールされます。

Linux(ubuntu) でのインストール

Linux は ubuntu 23.04 amd64 で試しました。

debian 系ならそう違わないと思いますが、インストール済みのライブラリ&ツールは環境依存なものなので違いはあるでしょう。試したのは 2023-05 頃なので同じ環境でも状況が変わっているかもしれません。

まず開発ツールをインストールします。

sudo apt install build-essential tar curl zip unzip
sudo apt install g++ make cmake ninja bison python3 pip

vcpkg は ~/vcpkg にインストールするとします。
※ pip は vcpkg で必須ではないですが、wxwidgets (が利用するライブラリ)のビルドで必要だったのでインストールしています。

ホーム ~/ ディレクトリにて

git clone https://github.com/microsoft/vcpkg
cd vcpkg
./bootstrap-vcpkg.sh

で vcpkg がインストールされます。

環境変数 VCPKG_ROOT

vcpkg をインストールしたディレクトリ・パスを環境変数 VCPKG_ROOT に設定しておくと、vcpkg コマンド や vcpkg.cmake で参照されるようになります。

運用の仕方にもよりますが、vcpkg ディレクトリを一つ固定で用意して常時使うならば、

  • Windows
    「システムのプロパティ」→「環境変数」で、VCPKG_ROOT に c:\vcpkg を設定.
  • Mac (zsh)
    ~/.zshrc に export VCPKG_ROOT=~/vcpkg を追記、source ~/.zshrc 実行.
  • Linux (bash)
    ~/.bashrc に export VCPKG_ROOT=~/vcpkg を追記、source ~/.bashrc 実行.

のように設定しておくとよいかもしれません。

クラシック・モードでの利用

vcpkg の使い方として、

  • vcpkg ディレクトリにライブラリをインストールするクラシック・モード、と、
  • プロジェクトごとに vcpkg.json ファイルを用いて、バージョンを固定し、プロジェクト・ディレクトリ下にライブラリをインストールするマニフェスト・モード

があります。

最終的にマニフェスト・モードを使うことになるかもしれませんが、マニフェスト・モードは応用例みたいなものなので、まずはクラシック・モードで使ってみます。

ライブラリのインストール

以下は基本的に Windows 環境で例示します。
Mac、Linux では、パス区切りの \ を / に読み替えてください。

まず vcpkg ディレクトリでコマンドプロンプトを開きます。

クラシック・モードでの、ライブラリのインストールは、

.\vcpkg install パッケージ名

.\vcpkg install パッケージ名:【TRIPLET】

のようになります。

実行すると、パッケージ名のモノと、それが利用しているライブラリ・パッケージが芋づる式にインストールされます。

【TRIPLET】は "x64-windows" や "arm64-osx" のような、CPUやOS・ライブラリの静動・C/C++ランタイムライブラリの静動を指定するための名前です。
【TRIPLET】の指定がない場合はデフォルトの【TRIPLET】が使われます。
Windows ではデフォルトは x86 向けのため、x64 用にインストールする場合は【TRIPLET】を指定したり環境変数を設定することになります。(詳しくは後述)

インストール先は vcpkg/installed/【TRIPLET】ディレクトリになります。

ディレクトリ 補足
include ヘッダ
lib ライブラリ
debug/lib Debugビルド用ライブラリ
bin Sharedライブラリ(dll,so)(static版では無し)
tools/【ライブラリ名】 ツール等実行ファイル
share アプリ側 cmake で使うパッケージ情報等

のようになっており、include パス指定やライブラリパス指定がしやすくなっています。
(おかげで、VS統合や cmake スクリプトを使わない場合でも、ある程度楽に設定できます)

ライブラリのインストールでは、ライブラリのビルドが行われ、一旦 vcpkg/packages ディレクトリにバイナリが作られたあと、installed にコピーされるようです。

ただ、デフォルト設定ままのビルド等、サーバーに登録(キャッシュ)されたビルド済みバイナリが有れば、それをダウンロードしてインストールするようです。

ライブラリを探す

何をインストールできるかの一覧が欲しい場合は

.\vcpkg search

で、全対応パッケージ一覧を出力できます。

また vcpkg/ports/ 下のサブディレクトリに各パッケージの情報があるので、そのディレクトリ名も参考になるでしょう。

パッケージ名がある程度わかっているなら

.\vcpkg search 文字列

で探すことができます。

たとえば minizip を探すと

minizip                  1.2.13#2         Minizip zip file manipulation library
minizip[bzip2]                            Support compression using bzip2 library
minizip[tools]                            Install tools
(その他minizipを含む項目)

が見つかります。
[]が付かないのは基本のライブラリ、[]で追加要素や付属ツール有りの指定になります。

インストールで[]付の指定は

.\vcpkg install minizip[bzip2,tools]

のように一度に複数を指定することもできます。

vcpkgディレクトリにインストール済みのライブラリは

.\vcpkg list

で一覧表示することができます。

2023-08 現在、'vcpkg search' をすると 4700 強ほど。
vcpkg/ports 下にはリポジトリ単位のライブラリ情報が 2200 強あり、ただ巨大ライブラリだと複数リポジトリのもの(boostだと150程)もあるので、対応ライブラリ数はざっくり 2000 以上といったところでしょうか。

TRIPLET

【TRIPLET】で、ターゲットのCPUやOS、ライブラリやC/C++ランタイムライブラリ(CRT)の静的(Static)/動的(Dynamic,Shared) を指定できます。

たとえば、

.\vcpkg install wxwidgets:x64-windows-static-md

のように

.\vcpkg install パッケージ名:【TRIPLET】

で行なえます。

あるいは、

環境変数 VCPKG_DEFAULT_TRIPLET

に【TRIPLET】を設定しておけば vcpkg 使用時に省略できます。

Windows/vc プログラムでは

  • 単一の実行ファイルなら、Static CRT の Static ライブラリ
  • dll を使うなら、Shared(dll) CRT の Static ライブラリ
  • 複数の実行ファイルや dll で構成され それらから共通で使われるライブラリなら、Shared CRT の Shared ライブラリ

のような選択をしたいのですが、【TRIPLET】を用いて

TRIPLET 補足
x64-windows-static Static ライブラリで CRT も static 版
x64-windows-static-md Static ライブラリで CRT は dll 版
x64-windows 可能なら Shared ライブラリ化(CRT は dll 版)

のように指定できます。(x86ならx64の部分を置換)

TRIPLET 名は vcpkg/triplets ディレクトリの .cmake ファイル名になっています。
例えば x64-windows-static-md.cmake は

set(VCPKG_TARGET_ARCHITECTURE x64)
set(VCPKG_CRT_LINKAGE dynamic)
set(VCPKG_LIBRARY_LINKAGE static)

のように設定されています。

ディレクトリ直下の *.cmake は公式管理のもの、community ディレクトリ下は有志/コミュニティ管理のものとのことですが、公式+αを並べてみると

TRIPLET CRT Library 公/非
x64-windows Shared Shared 公式
x64-windows-static Static Static 公式
x64-windows-static-md Shared Static community
x86-windows Shared Shared 公式
x86-windows-static Static Static community
x86-windows-static-md Shared Static community
arm64-windows Shared Shared 公式
x64-uwp Shared Shared 公式
arm-uwp Shared Shared 公式
x64-osx Shared Static 公式
arm64-osx Shared Static community
x64-linux Shared Static 公式
x86-linux Shared Static community
arm64-linux Shared Static community
x64-android Static Static 公式
arm64-android Static Static 公式
arm-neon-android Static Static 公式

のようなものがあります。(2023-08現在)

※ android版は少し前まで community でしたが、最近公式になった模様。

上記の community版は極一部で、community ディレクトリには 60 前後の cmake があり、mingw 用やら ios、xbox系、freebsd や openbsd、ターゲットCPUも arm, arm64, riscv32, riscv64, ppc64, s390, wasm32 等々、いろいろあるようです。

ただサポートの具合はマチマチのようで、x64-windows は一通りサポートされていそうですが、x64-windows-static や x64-windows-static-md だと基本のライブラリは大丈夫でも、[追加]インストールの類で対応不十分なことがありしました。このへんは実際に試して確認するしかなさそうです。

ライブラリの削除や更新

ライブラリのアンインストールは

.\vcpkg remove ライブラリ名:【TRIPLET】

になります。

vcpkg や ライブラリの更新については、まず

git pull

しておき、

.\vcpkg upgrade

で更新のあった vcpkg 自体やライブラリのチェックが行われます。

場合によっては bootstrap-vcpkg.bat (….sh) の再実行を即されることがあるので、それに従って更新します。

変更のあったライブラリをまとめて更新したい場合は

.\vcpkg upgrade --no-dry-run

で各ライブラリの削除&再インストールがまとめて行われます。

個別の更新もできなくはなさそうですが、ライブラリ同士の依存関係を思うと、一括更新が無難でしょうか。

※ ひとつのライブラリの複数バージョンやコンパイルオプション違いを、一つのvcpkgディレクトリで扱うのは困難なようなので、本格的に使うならばプロジェクトごとに vcpkg ディレクトリを用意するか、マニフェスト・モードを利用することになりそうです。


サンプル・ビルド

cmake で、サンプルを Windows:vc、Mac:apple-clang、Linux(ubuntu):g++ でビルドしてみます。

サンプルは、マルチプラットフォーム GUI ライブラリ wxWidgetsHello Worldサンプル を c++11 化& UTF-8 文字列の日本語メッセージ化し好みに編集したものを用います。

実行サンプル

wx_hello.cpp
// Hello World with wxWidgets and c++11
// Original source : https://docs.wxwidgets.org/trunk/overview_helloworld.html
#include <wx/wx.h>

class MyFrame : public wxFrame {
    enum { ID_Hello = 1 };
public:
    MyFrame()
        : wxFrame(nullptr, wxID_ANY, _T("Hello World"))
    {
        wxMenu *menuFile = new wxMenu();
        menuFile->Append(ID_Hello, _T("ハロー(&H)...\tCtrl-H"),
                         _T("ステータスバーにこのメニュー項目の説明を表示します"));
        menuFile->AppendSeparator();
        menuFile->Append(wxID_EXIT);

        wxMenu *menuHelp = new wxMenu();
        menuHelp->Append(wxID_ABOUT);

        wxMenuBar *menuBar = new wxMenuBar();
        menuBar->Append(menuFile, _T("ファイル(&F)"));
        menuBar->Append(menuHelp, _T("ヘルプ(&H)"));

        SetMenuBar( menuBar );

        CreateStatusBar();
        SetStatusText(_T("wxWidgets にようこそ!"));

        Bind(wxEVT_MENU, [](wxCommandEvent& event) {
            wxLogMessage(_T("wxWidgets でハローワールド!"));
        }, ID_Hello);

        Bind(wxEVT_MENU, [](wxCommandEvent& event) {
            wxMessageBox(_T("これは wxWidgets を使った 'Hello World' サンプルです"),
                         _T("Hello World について"), wxOK | wxICON_INFORMATION);
        }, wxID_ABOUT);

        Bind(wxEVT_MENU, [this](wxCommandEvent& event) {
            Close(true);
        }, wxID_EXIT);
    }
};

class MyApp : public wxApp {
public:
    bool OnInit() override {
        MyFrame *frame = new MyFrame();
        frame->Show(true);
        return true;
    }
};

wxIMPLEMENT_APP(MyApp);

クラシック・モードで cmake ビルドするとして、ファイル&フォルダは

 wx_hello/
  src/wx_hello.cpp
  build/
  CMakeLists.txt

のように配置するとします。

※ VS向け含むサンプル一式を以下においているので必要なら clone するなり Download ZIP するなりしてください。(cloneだと他のサンプルも混ざっているかもしれません)

https://github.com/tenk-a/samples/blob/wx_hello/


CMakeLists.txt

wx_hello ディレクトリ直下の CMakeLists.txt は以下のようにしています。

vcpkg が用意している vcpkg.cmake を CMAKE_TOOLCHAIN_FILE に設定して用いることで、vcpkg でインストールしたライブラリ関係の設定が楽になります。

CMakeLists.txt
# cmake の最低バージョン指定.
cmake_minimum_required(VERSION 3.18)

# CMAKE_TOOLCHAIN_FILE が無指定なら、環境変数 VCPKG_ROOT を元に設定.
if(NOT DEFINED CMAKE_TOOLCHAIN_FILE AND DEFINED ENV{VCPKG_ROOT})
    set(CMAKE_TOOLCHAIN_FILE "$ENV{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake")
endif()

# VCPKG_TARGET_TRIPLET が無指定なら、環境変数 VCPKG_DEFAULT_TRIPLET で設定.
if(NOT DEFINED VCPKG_TARGET_TRIPLET AND DEFINED ENV{VCPKG_DEFAULT_TRIPLET})
    set(VCPKG_TARGET_TRIPLET "$ENV{VCPKG_DEFAULT_TRIPLET}")
endif()

# プロジェクト名設定.
project(wx_hello)

# c++11 以降を使う指定.
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# vc ならソース&charを UTF-8 で扱う指定.
if(WIN32 AND MSVC)
    add_compile_options(-utf-8)
endif()

# wxWidgets を使う指定.
find_package(wxWidgets REQUIRED COMPONENTS core base)

# wxWidgts の準備(setup.h 生成)
include(${wxWidgets_USE_FILE})

# ソース・ファイルの設定.
add_executable(${PROJECT_NAME}
    src/wx_hello.cpp
)

# ターゲット別のリンクに関する設定.
if(WIN32 AND MSVC)
    # vc で GUI アプリにするリンカオプション指定.
    target_link_options(${PROJECT_NAME} PRIVATE /SUBSYSTEM:WINDOWS)
else()
  if(APPLE)
    # Mac で Cocoa を使う指定.
    target_link_libraries(${PROJECT_NAME} PRIVATE "-framework Cocoa")
  endif()
endif()

# include ディレクトリ設定.
target_include_directories(${PROJECT_NAME} PRIVATE
    ${CMAKE_CURRENT_SOURCE_DIR}/src
    ${wxWidgets_INCLUDE_DIRS}
)

# ライブラリ・ディレクトリ設定.
target_link_libraries(${PROJECT_NAME} PRIVATE
    ${wxWidgets_LIBRARIES}
)

色々見よう見まね、慣れぬ cmake で、こなれた書き方とはいきませんが、とりあえずクラシック・モード、マニフェスト・モード双方で使えるようにしています。
設定順、むずかしい...

cmake 実行での引数指定をなるべくせずに済むよう、無指定なら環境変数 VCPKG_ROOT, VCPKG_DEFAULT_TRIPLET を参照しています。

設定している内容は順に、

  • cmake の最低バージョン指定。
  • CMAKE_TOOLCHAIN_FILE が無指定なら、環境変数 VCPKG_ROOT を元に設定。
    project(プロジェクト名) 指定に先立って設定されている必要があります。
  • VCPKG_TARGET_TRIPLET が無指定なら、環境変数 VCPKG_DEFAULT_TRIPLET で設定。
    クラシック・モードでは不要なのですが、マニフェスト・モードだと VCPKG_DEFAULT_TRIPLET が参照されないようなので、このタイミングで設定。
  • プロジェクト名設定。
  • c++11 以降を使う指定。
  • vc ならソース&charを UTF-8 で扱う指定。
    add_executable に先立って指定する必要があるよう。
  • wxWidgets を使う指定。
    wxWidgets_??? 変数 が使えるようになります。
  • wxWidgts の準備(setup。h 生成)
  • ソース・ファイルの設定。
  • ターゲット別のリンクに関する設定。
  • include ディレクトリ設定。
    • vc で GUI アプリにするリンカオプション指定。
      MS link.exe が基本、大文字オプション指定であることを忘れているとドはまりします。
    • Mac で Cocoa を使う指定。
  • include ディレクトリ指定。
    wxWidgets関係は ${wxWidgets_INCLUDE_DIRS} にお任せ。
  • ライブラリ・ディレクトリ指定。
    wxWidgets関係は ${wxWidgets_LIBRARIES} にお任せ。

多少プラットフォーム別の設定は必要ですが、パッケージ別変数を用いてディレクトリやファイルの指定が、かなり簡略化して記述できるのは便利です。

Windows x64 / vc での cmake サンプル・ビルド

vcpkg は c:\vcpkg にインストールしたとします。

サンプルの wx_hello ディレクトリでコマンドプロンプトを開けて、

"%ProgramFiles(x86)%\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvarsall.bat" x64

を実行して x64版の vc ツールを使えるようにします。
※ VS2022用。Profetional 版 や Enterprise 版なら Community の部分を置換。

TRIPLET は x64-windows,x64-windows-static,x64-windows-static-md 何れでも構わないのですが、ここでは x64-windows-static-md を選択することにします。

なるべく引数指定せず cmake したいため、環境変数経由でオプションを渡すことにします。
※ vscode でビルドする場合は環境変数設定済で cmake できたほうがよさそうなこともあり。

環境変数を設定していないならば

set VCPKG_ROOT=c:\vcpkg
set VCPKG_DEFAULT_TRIPLET=x64-windows-static-md

で設定し、

vcpkg install wxwidgets

で、wxwidgets をインストールします。連動して他のライブラリが結構インストールされます。
※ マニフェスト・モードの場合はこのインストールは不要です。

cd build
cmake ../
msbuild wx_hello.sln -p:Configuration=Release

で cmake で wx_hello.sln 生成して msbuild で(Release)ビルドします。
あるいは msbuild のかわりに VS でビルドします。

※ TRIPLET=x64-windows で Shared ライブラリ化した場合は、exe と同じディレクトリにライブラリの .dll がコピーされます。

今回の CMakeLists.txt は環境変数 VCPKG_ROOT,VCPKG_DEFAULT_TRIPLET を参照していますが、CMakeLists.txt をそう作っていない場合や、環境変数を用いない場合は、cmake の引数で

cmake -DCMAKE_TOOLCHAIN_FILE=c:/vcpkg/scripts/buildsystems/vcpkg.cmake ^
      -DVCPKG_TARGET_TRIPLET=x64-windows-static-md ^
      ../

のように CMAKE_TOOLCHAIN_FILE と VCPKG_TARGET_TRIPLET を指定します。

Mac での cmake サンプル・ビルド

vcpkg をインストールした環境で作業します。

デフォルトの TRIPLET まま使います。
Arm64(M1,M2) Mac では arm64-osx、Intel Mac ならば x64-osx です。Shared CRT の Static ライブラリになります。

まず wxWidgets インストールで必要になる

brew install pkg-config

をしておきます。

vcpkg ディレクトリにて

./vcpkg install wxwidgets

で、wxwidgets をインストールします。連動して他のライブラリが結構インストールされます。
※ マニフェスト・モードの場合はこのインストールは不要です。

もしエラーがでたら直してリトライ。

サンプルの wx_hello ディレクトリにて

export VCPKG_ROOT=~/vcpkg
cd build
cmake ../
make

で cmake で Makefile 生成して make します。

Xcode でビルド&実行したい場合は

cmake -G Xcode ../

で wx_hello.xcodeproj を生成します。

Linux(ubuntu) での cmake サンプル・ビルド

vcpkg をインストールした環境で作業します。

デフォルト TRIPLET の x64-linux まま使います。Shared CRT の Static ライブラリになります。

まず、wxWidgets で要求される外部ライブラリが必要とするものを

sudo apt install libdbus-1-dev libxi-dev libxtst-dev
sudo apt install libx11-dev libxft-dev libxext-dev
sudo apt install libxrandr-dev

でインストールします。

vcpkg ディレクトリにて

./vcpkg install wxwidgets

で、wxwidgets をインストールします。連動して他のライブラリが結構インストールされます。
※ マニフェスト・モードの場合はこのインストールは不要です。

エラーが出たら指示に従い、あるいは調査修正してやりなおします。

先に apt install してたものは、その結果です。
apt install ??? と教えてくれることもあれば、わからないエラーもありました。
エラーは、一見、別原因に見えたとしても、結局、vcpkg 管理外のツールかライブラリが足りてないことによるものでした。

サンプルの wx_hello ディレクトリにて

export VCPKG_ROOT=~/vcpkg
cd build
cmake ../
make

で cmake で Makefile 生成して make します。

wx_hello 実行時に「canberra-gtk-module がない」とか曰われた場合は

export GTK_PATH=/usr/lib/x86_64-linux-gnu/gtk-3.0

をして実行すれば消せるかもしれません。
https://jp.mathworks.com/help/matlab/matlab_env/remove-canberra-gtk-module-and-pk-gtk-module-messages.html
を参考。設定した GTK_PATH ディレクトリ下に canberra-gtk-module.so があったので、説明にある apt install は行わず。

※ 実行時、他にもエラーログが出ているかもしれませんが、サンプルゆえ深く追求せず見なかったことにします。


マニフェスト・モード

設定ファイル vcpkg.json を用いると、特定の vcpkg のリビジョンを指定して

  • プロジェクトの cmake 時に、ライブラリのインストールや更新を一緒に行う
  • 各ライブラリのバージョンをある程度制御できる

ようになります。

cmake ビルドを行うときに、CMakeLists.txt と同じ階層に vcpkg.json が有れば「マニフェスト・モード」、無ければ「クラシック・モード」となるようです。

build フォルダで cmake ../ をする場合、ライブラリのインストール先は、

  • "【vcpkgディレクトリ】/installed"
    → "【プロジェクト】/build/vcpkg_installed"

に変わります。
※ 【vcpkgディレクトリ】/installed にインストール済のライブラリがあっても、それは用いられません。

vcpkg.json は、簡単なものなら、以下のようになります。

vcpkg.json
{
  "name": "project-name",
  "version": "1.0.0",
  "builtin-baseline": "【ハッシュ値】",
  "dependencies": [
    "libraryname1",
    "libraryname2"
  ]
}

project-name は、小文字英数と'-'で記述します。('_'は使えない)

"builtin-baseline" の【ハッシュ値】は、vcpkg の git リビジョン/ハッシュ値を指定します。
各ライブラリは、vcpkg の【ハッシュ値】時点のバージョンが用いられることになります。

今現在をそのまま使うならば、vcpkg ディレクトリにて

git rev-parse HEAD

で出力されたものを指定します。
あるいは vcpkg.json で "builtin-baseline": "" のようにハッシュ値を空にしてビルド、エラーメッセージ中の "builtin-baseline": "ハッシュ値" から抜き出します。

【ハッシュ値】における全パッケージのバージョン一覧が

vcpkg/buildtrees/versioning_/baselines/【ハッシュ値】/baseline.json

にあります。

ライブラリのバージョン指定

"dependencies" にて各ライブラリの最低バージョンを指定することができます。
これを用いれば、"builtin-baseline" でのライブラリ・バージョンより、特定のライブラリだけ新しいバージョンを指定できます。

先の例で libraryname1 の builtin-baseline でのバージョンが 2.0 だとすると、

  "dependencies": [
    { "name" : "libraryname1", "version>=" : "3.0" },
    "libraryname2"
  ]

のように書き換えれば、libraryname1 の最低バージョンを 3.0 にできます。

逆に、"builtin-baseline" でのライブラリ・バージョンより、古いバージョンにライブラリを固定したい場合は、"overrides" を追加します。

builtin-baseline でのバージョンが 2.0 だとすると、

  【略】
  "dependencies": [
    "libraryname1",
    "libraryname2"
  ],
  "overrides": [
     { "name": "libraryname1", "version": "1.0" }
  ]

のようにすれば、libraryname1 のバージョンを 1.0 に固定できます。

version 指定は無差別に行えるというわけでなく、build-baseline で許容できる範囲に限られるようです。安易に build-baseline を新しいものにしたら、cmake時に overrides していたライブラリでエラーになることがありました。(この辺はやってみないとわからない…)

なおライブラリごとに指定可能なバージョンは、vcpkg/version 下に情報があるようです。

例えば wxwidgets なら、

  • vcpkg/versions/w-/wxwidgets.json

に情報があります。

マニフェスト・モードでの vcpkg ディレクトリ

マニフェスト・モードは、一つの vcpkg ディレクトリのまま複数のプロジェクトで使えるように思います。軽く、近いリビジョン違いで試した範囲では、ですが。

マニフェスト・モードでビルドを行っても vcpkg/packges 以外のvcpkgディレクトリは変更されないようで、packges ディレクトリもライブラリのビルド過程で作業領域的に?使ってるだけにみえるので……しらんけど。

ただ、vcpkg ディレクトリに対し builtin-baseline のリビジョンが大きく離れていた場合に整合が取れるのか、破綻しないのか、は、わかりません。

安全を取るなら、プロジェクトごとに vcpkg ディレクトリを用意したほうがよさそうに思います。(が、サンプルではそこまでせず)

マニフェスト・モードでのサンプル・ビルド

vcpkg.json として

vcpkg.json
{
  "name": "wx-hello",
  "version": "1.0.0",
  "builtin-baseline": "a8f69d8eff3785c621b4282d2f7e5cc18e08d7f7",
  "dependencies": [
    "wxwidgets"
  ]
}

を wx_hello ディレクトリの直下に置き、

  wx_hello/
    src/wx_hello.cpp
    build/
    CMakeLists.txt
    vcpkg.json

のように配置します。

後は、wxwidgets のインストールを手動で行わない以外は、クラシック・モードでのサンプル・ビルドと同じ手順を行います。

※ 場合によっては "builtin-baseline" は git rev-parse HEAD の値で更新してもらったほうがよいかもしれません。


vscode でのサンプル・ビルド&デバッグ

vscode は常用しているわけでなく、できるかできないか程度の確認ですが、試してみました。

Windows, Mac, Linux いずれでも vscode をインストールし、アドオンの

  • Microsoft の C/C++ Extension Pack (C/C++, CMake Tools 等)

もインストールしておきます。

Windows(10) の場合は、OS 標準装備のものより新しい PowerShell (pwsh.exe) を、winget か Microsoft Store 等からインストールしておきます。(ひょっとすると python3 も必要だったかもしれません)

実行は、前出のサンプル・ビルドをした環境 wx_hello ディレクトリで行います。
環境変数 VCPKG_ROOT、VCPKG_DEFAULT_TRIPLET が未設定なら設定しておきます。

cmake の実行は vscode から行われますが、最初なので wx_hello/build ディレクトリにて、

cmake ../

が成功することを確認しておきます。

問題なければ CMakeLists.txt のある wx_hello ディレクトリ直下に移り、

code ./

で vscode 起動。

コマンドプロンプトで PATH の通ったところに code がない場合、vscode 上で command+shift-P して "shell command:install 'code' command in PATH" を選択&実行すれば使えるようになります。
あるいは環境変数 VCPKG_ROOT、VCPKG_DEFAULT_TRIPLET が設定された状態でvscodeを起動できるなら wx_helloフォルダを基点にオープンすればよいはず。

初回は

Select a kit for プロジェクト名

と入力を即されるので、vcpkg install で用いたコンパイラ(か互換のあるモノ)を選択します。
選択したあと cmake が実行されます。

ソース編集画面の、ステータスバーに、CMake や build、プログラム実行・デバッグのボタンがあるので、それを用いて開発が行なえます。

ボタン 内容
CMake Debug,Release,MinSizeRel,RelWithDebInfo から選択して cmake を実行
ツールチェイン名 ツールチェイン(コンパイラ)の選択。
ライブラリビルド時と同じか互換のあるものを選ぶ
Build ビルドを行う (ninja や msbuild が使われる)
ビルドターゲット [ALL_BUILD] [プロジェクト名] [ZERO_CHECK] の選択
🐞(虫マーク) デバッグ実行。
ビルド成功すればエディタ上方にデバッグ用のパネル出現
そのままプログラム実行


デバッグ実行中は、

  • ソース行番号左側でブレークポイントを置いたり、
  • 上辺に出現するパネルで停止や再開・ステップ実行ができたり、
  • 左サイドの🐞▷ボタンで変数・ウォッチ式・コールスタック・ブレークポイント一覧が表示できたり

等、一通りのことはできるようです。

ウォッチポイント(データのブレークポイント)を貼るのは用意されてなさそうですが、gdb や lldb なら最悪デバッグコンソールで(-exec コマンド使って)何とでもなりそう。
ただ本格的にデバッグするなら Windows なら VS, Mac なら Xcode を使えるなら使ったほうが便利でしょうね…

2023-12 追記

今現在は、ステータスバーの「CMake」「ツールチェイン名」ボタンは無くなり、明示的に launch.json を作成する必要があるようです。

.vscode/launch.json の無い状態で、左サイドの「実行とデバッグ」ボタン(🐞▷)を選び、「launch ファイル作成」でツールチェインを選択、出来た launch.json のページの右下の「構成の追加」ボタンから使いたい構成を選ぶと "configurations" に設定項目の雛形が挿入されるので、必要な箇所を書き換えます。

構成は複数設定できるので、Debugビルド用 Release ビルド用 等必要に応じて追加できます。

項目にツールチップが表示されたりで、カスタマイズはし易いと思います。

ただ、VC用な "(Windows) 起動" でも最低限 "program" に実行ファイルのパスを設定する必要があり、"(GDB) 起動" だとさらにデバッガパスとか...
以前の自由度ないけどおまかせ設定一発に比べると ちと面倒くさくはあります。
json なので、コマンドライン引数指定も json の配列で書かないといけないし。


おわりに

  • vcpkg を用いてライブラリ構築
  • cmake スクリプトを用いて Windows, Mac, Linux でのライブラリ&アプリ・ビルド
    • vcpkg.json を用いてのプロジェクトごとのライブラリ・インストール
  • その cmake 環境で vscode によるデバッグ実行

が、わりと簡単に行えました。

サンプルゆえ簡単に行える範囲で済ませているというのもありますが。

利用については、とりあえずサンプルの延長で一つの vcpkg でVS統合し、マニフェストモードでぼちぼち使っている感じです。(外部ライブラリが必要なものを何本も作っていないので…)

個人的には TRIPLET で、ライブラリの Static/Shared、CRT の Static/Shared を選べるのが気に入っています。

ライブラリが公式に Windows/vc 対応していても、このへんの設定はライブラリごとにマチマチで、設定の変更も make や cmake の引数指定だけで済むことは少なく、ビルドスクリプト等を修正することも少なくなく、で。
自分で複数ライブラリ・ビルドをしていてバッチをつくり、だんだんパッケージ・ツールぽくなり、しかし更新面倒くさく放置した身としては、vcpkg はホントありがたく思うのでした。

なお、今回は cmake でしたが、VS統合についてはこちら で補足しています。

Discussion