🦋

vcpkg で c/c++ライブラリを使う VS の例

2023/08/12に公開

「vcpkg を用いた Win/Mac/Linux用 c++プログラムの cmake & vscode 実行例」 からはみ出した、Visual Studio で使ったときのメモ書です。

vcpkg のインストールやら、ライブラリのインストールやら、TRIPLET やら、クラシック・モード/マニフェスト・モードやらについては、そちらを見てやってください。


Visual Studio 統合

プロジェクト単位でなくユーザー環境全体での設定になります。

cmake編でインストールした vcpkg ディレクトリにて

vcpkg integrate install

をすればPCにインストール済みの Visual Studio 2017,2019,2022 それぞれに統合され、プロジェクトのプロパティに vcpkg のページが増えます。
※ VS 2015upd3では現れず

VSプロジェクト・プロパティでのvcpkg

キャプチャ画像は、何も設定していないときのデフォルトの状態です。

  • Use Vcpkg

で、vcpkg の使用の有無を設定します。使わないプロジェクトでは 'いいえ' にします。

使う場合は 'はい' にして、追加で

ライブラリの種類 設定項目
x64 Shared(dll)ライブラリ Triplet x64-windows
x64 Staticライブラリ
Static CRT版
Use Static Libraries
Triplet
はい
x64-windows-static
x64 staticライブラリ
Shared(dll) CRT版
Use Static Libraries
Use Dynamic CRT
Triplet
はい
はい
x64-windows-static-md

のように使うライブラリに合わせて設定を変更します。

Static CRT 版を使う場合は、さらに c/c++コード生成の設定の「ランタイムライブラリ」を、
・ Release ビルドなら「マルチスレッド(/MT)」
・ Debug ビルドなら「マルチスレッドデバック(/MTd)」
のように変更します。

これで vcpkg でインストールしたライブラリが使えるようになります。

まれに、インストールしたライブラリが vcpkg 管理外のライブラリを必要とすることがあり、その場合は(リンクエラー見ながら)必要なライブラリを リンカーの入力に追加します。

Shared ライブラリ化した場合の dll ですが、これはビルド成功時に exe のあるディレクトリにコピーされるようです。

なお vcpkg の設定は、プロジェクト名.vcxproj に <PropertyGroup Label="Vcpkg" …> で保存されます。Use Vcpkg を いいえ にした場合も、'いいえ' にしたという設定が保存されます。それが嫌な場合はVS統合を解除するしかなさそうです。

VS統合を解除するには

vcpkg remove integrate

です... が、これしても vcpkg の項が現れるような?
インストールしていた vcpkg ディレクトリを移動なり変名なり削除なりして、パスを無効にすると、vcpkgの頁は消えました。

VS統合でのマニフェスト・モード

VS 統合では vcpkg のプロパティ・ページで、

Use Vcpkg manifest : はい

にすることで、プロジェクト・ディレクトリ直下に置かれた vcpkg.json が使われるようになります。

このときライブラリのインストール先は、

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

に変わります。


サンプル・ビルド

サンプルはcmake編と同じ、wxWidgetsの Hello World サンプルを改造したものです。

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

においているので、試す場合は、 clone するか Download ZIP でダウンロードしてください。(cloneだと他のサンプルが混ざっているかもしれません)

ファイルは

 wx_hello/
  src/wx_hello.cpp
  build/
  build_vc143vcpkg/*
  build_vc143env/*
  CMakeLists.txt
  vcpkg.json

のように配置しています。

cmakeでのマルチプラットフォーム対応もあって、vc でソース & char 文字列を UTF-8 扱いにする -utf-8 を wx_hello.sln(vcxproj), に追加しています。

また TRIPLET は x64-windows-static-md(Shared CRT のStatic ライブラリ)を選択するので、クラシック・モード向けに

vcpkg install wxwidgets:x64-windows-static-md
vcpkg install wxwidgets:x86-windows-static-md

で wxwidgets をインストールしておきます。(x86 版を試さないなら2行目は不要)

VS統合でのサンプル・ビルド

VS統合のサンプルは VS2022 用の vc143vcpkg/wx_hello.sln になります。

プロジェクトのプロパティ設定の vcpkgページでまず

項目
Use Vcpkg はい

vcpkg を使う設定にします。

項目
Use Vcpkg manifest いいえ / はい

vcpkg ディレクトリに wxwidgets をインストール済みなら、'いいえ' のクラシック・モードでビルド可能です。

manifest を 'はい' にしてマニフェスト・モードにすれば、ビルド時に wxwidgets が一緒にインストール(ビルド)されるようになります。

'はい' のときの vcpkg.json は、cmake編の「マニフェストモード」の説明で例示したモノを使っています。

他のプロジェクトプロパティ設定は、vcpkg では

項目
Use Static Libraries はい
Use Dynamic CRT はい
Triplet x64-windows-static-md

で TRIPLET=x64-windows-static-md 用に変更しています。
(※ Win32 の設定では Triplet : x86-windows-static-md)

ソース&char型を UTF-8 で扱うため、c/c++→コマンドライン→追加のオプションに

  • -utf-8

を追記しています。
また、そのままではリンクエラーになったため

  • リンカー入力: Comctl32.lib;Rpcrt4.lib;【元からの設定】

にdllを追加しています。

これらを x64 Release, x64 Debug, Win32 Release, Win32 Debug の4つに設定しています。

VS統合しない場合のサンプル・ビルド

サンプル vc143env/wx_hello.sln は、VS統合していないか Use Vcpkg を いいえ にした環境で、通常の外部ライブラリとして使う場合の設定例です。

※ 外部ライブラリ(installed)ディレクトリの作成に vcpkg を使うけれど、プロジェクトとしては vcpkg に依存したくない場合を想定。

wxwidgets インストール済みで、環境変数 VCPKG_ROOT に vcpkg ディレクトリが設定されているとして、

設定項目 内容
c/c++全般:追加のインクルードディレクトリ(/I) $(VCPKG_ROOT)\installed\【TRIPLET】\include
c/c++コマンドライン→追加のオプション -utf-8
リンカー全般:追加のライブラリディレクトリ(/LIBPATH) Release 用 $(VCPKG_ROOT)\vcpkg\installed\【TRIPLET】\lib
リンカー全般:追加のライブラリディレクトリ(/LIBPATH) Debug 用 $(VCPKG_ROOT)\vcpkg\installed\【TRIPLET】\debug\lib
リンカー入力(Relase用) wxbase32u.lib; wxmsw32u_core.lib; nanosvgrast.lib; nanosvg.lib; libpng16.lib; zlib.lib; Comctl32.lib; Rpcrt4.lib;【元からの設定】
リンカー入力(Debug用) wxbase32ud.lib; wxmsw32ud_core.lib; nanosvgrast.lib; nanosvg.lib; libpng16d.lib; zlibd.lib; Comctl32.lib; Rpcrt4.lib;【元からの設定】

のようにプロジェクトのプロパティをデフォルト状態に対し変更しています。

【TRIPLET】は x64用は x64-windows-md、Win32用は x86-windows-md です。

これらを x64 Release, x64 Debug, Win32 Release, Win32 Debug, の4つに行います。

一度やってしまえば開発中そうそう変動しないものですし、複数のライブラリを使う場合に指定するディレクトリが統一されていて便利ですが、リンカー入力対象ファイルの指定等やはり面倒ではあり、また今回は避けましたが Shared ライブラリ化していた場合は その dll のコピー等も必要なので、VS統合のお手軽さは魅力です。

※ライブラリによっては vc の
#pragma comment(lib,"ライブラリ名")
を設定してくれて、ライブラリ・ファイルの追記をしなくてすむモノもありますが...

cl.exe で直にサンプル・ビルド

ついでに 直接 cl.exe で x64-windows-static-md の Release ビルドを行う例も。
x64用 vc ツールのパスを通し、wx_hello/build ディレクトリにて

cl -O2 -DNDEBUG -utf-8 -D_UNICODE -DUNICODE -EHsc -MD -I%VCPKG_ROOT%\installed\x64-windows-static-md\include ..\src\wx_hello.cpp -link /MACHINE:X64 /SUBSYSTEM:WINDOWS /LIBPATH:%VCPKG_ROOT%\installed\x64-windows-static-md\lib wxbase32u.lib wxmsw32u_core.lib nanosvgrast.lib nanosvg.lib libpng16.lib zlib.lib Comctl32.lib Rpcrt4.lib kernel32.lib user32.lib comdlg32.lib gdi32.lib advapi32.lib shell32.lib ole32.lib winspool.lib

を実行。


蛇足: VS統合でプロジェクト・ディレクトリ下の vcpkg を使う

MSBuild integration (Visual Studio) をみると、統合時の vcpkg ディレクトリとは別の vcpkg ディレクトリを VS 統合で使う方法があります。

※ クラシック・モードままプロジェクト別に vcpkg ディレクトリを使いたい、とか、マニフェスト・モードでもvcpkgディレクトリ下の個々のライブラリの設定ファイルをいじったり?とか... あまり使うことはなさそうですが。

すでに vcpkg integrate install でVS統合が機能した状態とします。
プロジェクト・ディレクトリ直下(.git のあるディレクトリ?) に

Directory.build.props
<Project>
 <Import Project="$(MSBuildThisFileDirectory)vcpkg\scripts\buildsystems\msbuild\vcpkg.props" />
</Project>
Directory.build.targets
<Project>
 <Import Project="$(MSBuildThisFileDirectory)vcpkg\scripts\buildsystems\msbuild\vcpkg.targets" />
</Project>

のような Directory.build.props と Directory.build.targets を配置することで、VS統合のvcpkgディレクトリとは別の、そこに設定した vcpkgパス(のファイル) が使われるようになります。

※ 元々 .vcxproj ごとに <Import Project=… /> を設定できるようで、Directory.build.* はそれを纏めて指定する方法のようです。

vcpkg もプロジェクト・ディレクトリ直下に配置したとして、ざっくり以下のような構成で試して動きました。[1]

【プロジェクト】/
    .git
    build/【.sln 等】
    src/【ソース】
    vcpkg/…
    Directory.build.props
    Directory.build.targets

脚注
  1. サンプル wx_hello にて wxwidget を VS 統合の vcpkg ディレクトリにインストールせず xml ファイルを追加しない状態でビルド失敗を確認、xml追加&プロジェクト下のvcpkg でライブラリを追加してビルド成功を確認 ↩︎

Discussion