[C++][vcpkg]vcpkgに関する備忘録。

疑問が解決する度に追記していきたい。基本的にWindowsで使用することを想定している。

デフォルトのtripletを変更する

環境変数VCPKG_DEFAULT_TRIPLETの値を任意のtripletにすればよい。いちいちpackage名のあとにtripletを入力する手間が省ける。
個人的には、64bit用を開発するのなら、x64-windows-static-mdにするのが無難じゃないかと思っている。何故かオフィシャルなtripletにしてくれないらしいけど。

インストール先はできるだけパスが短くなるように。

vcpkg本体のインストールは、C:\vcpkg\のような極めてパスの短い場所にしておかないと後々困ることがある。私の場合、C:\vcpkg\vcpkg_myenv\みたいな場所にvcpkg本体を置いておき、そこにQt WebEngineをインストールしようとしたところ、「パスが長すぎる」というエラーが表示され失敗した。
……尤も、Qt6の場合はC:\vcpkgという最低限の長さのパスを与えてもなお失敗した。比較的新しいバージョンでは、--x-buildtrees-root=C:\buildtreeのように、ビルドツリー用に十分短いパスを与えておけばなんとかビルドできるようだった(ver-2023.02.24で確認)。

static、dynamicのパッケージを混在させたい時

例えばオープンソース版のQtは基本的にLGPLライセンスであるため、大抵はdynamic linkが選択されるだろうが、その他のライブラリはstatic linkが好まれるのではないかと思う。これらを混在させる場合、tripletを編集する必要がある。 %VCPKG_ROOT%\triplets(%VCPKG_ROOT%はvcpkgをインストールしたフォルダ)がtriplet設定の置き場であるので、ここに自作の設定ファイルを追加すればよい。例えばx64-windows-staticをベースに、Qt5のみをdynamicに変更した自前の環境を用意してみる。

  1. x64-windows-static.cmakeをコピペし、任意のファイル名(x64-windows-myenv.cmakeとか)に変更する。
  2. 次のように書き換える。
set(VCPKG_TARGET_ARCHITECTURE x64)
set(VCPKG_CRT_LINKAGE static)
set(VCPKG_LIBRARY_LINKAGE static)

if(${PORT} MATCHES "^(qt5).*")
    set(VCPKG_LIBRARY_LINKAGE dynamic)
endif()

${PORT}にはインストールしようとしているパッケージの名前が入っているらしい。これが"qt5"から始まる名前の時だけ、VCPKG_LIBRARY_LINKAGEをdynamicに修正している。 あとはパッケージをインストールする際にpackage:x64-windows-myenvのように作成した設定のファイル名を指定すればよい。もちろん、上のVCPKG_DEFAULT_TRIPLETに指定してもよい。

なお、vcpkgでQtをインストールすると死ぬほどエラーに遭遇するので、私個人的には推奨しない。

Visual Studioがインクルードディレクトリなどを解決してくれない時

Visual Studio 2019で確認。
Visual Studioと統合するにはvcpkg integrate installを実行せよ、としか説明されていないが、このときVisual Studioはtripletがx86-windowsまたはx64-windowsであると想定しているらしい。もしこれ以外のtripletでインストールした場合、インクルードしようとしているファイルは見つからない。
プロジェクトのプロパティを開き、構成プロパティ->vcpkg->Tripletに該当するtripletを指定すればよい。
Visual Studioのデフォルト設定を変更できないかとも思ったが、今の所見つけられていない。

CMakeで指定のtripletを使う

CMakeではデフォルトでx86-windowsかx64-windowsが使われるらしく、これ以外を使う場合はVCPKG_TARGET_TRIPLETの値を対象とするtriplet名に変更する必要があるらしい。 CMAKE_TOOLCHAIN_FILEVCPKG_TARGET_TRIPLETの2つを指定することで、ようやくfind_packageが機能するようになった。

Visual StudioのCMake Project中でvcpkgを無効にする

vcpkgはvcpkg integrate installを実行すると基本的にすべてのVisual Studio上のプロジェクトでvcpkgを有効にしてしまう。が、場合によってはvcpkgでインストールしたものではなく、それ以外の場所に用意したライブラリを使いたいときもあるだろう。
もし通常のプロジェクトなら単にプロジェクトのプロパティ中でUse Vcpkgの項目をいいえにするだけでよい。CMake Projectの場合は一見方法が分からないが、VS_GLOBAL_VcpkgEnabledという変数を定義し、値をfalseに設定すればよい。Visual StudioならCMakeSettings.json中に変数を追加すれば事足りる。これでvcpkgは実質無効となる。

--x-install-rootは機能していない

インストール先を指定するオプションだが、vcpkgのコマンド一覧でExperimentalと書かれているように、バグだらけでパッケージのインストールさえままならないので、2021年5月1日現在使ってはいけない。

コマンドプロンプトでエラーが出る?

これについては私も確認不十分で、しかもネット上でほとんど情報がなかったので、全く確証はないのだが……
vcpkgの2023.04.15とその近辺のバージョンを使っていたとき、次のようないずれかのエラーが出ることがあった。

error: this vcpkg instance requires a manifest with a specified baseline in order to interact with ports. Please add 'builtin-baseline' to the manifest or add a 'vcpkg-configuration.json' that redefines the default registry.
error: Could not locate a manifest (vcpkg.json) above the current working directory. This vcpkg distribution does not have a classic mode instance.

私の場合、一度コマンドプロンプト上でvcpkg install ___というコマンドを実行し、その後同じ窓で引き続きvcpkgのコマンドを打ち込むと、このエラーに遭遇した。コマンドプロンプトを立ち上げ直すと再びコマンドを受け付けるようになるのだが、vcpkg install ___を実行するたびに再発した。クラシックモードがとうとう使えなくなったのかとも思ったが、そのような記述をドキュメント内で見つけられなかった。
このエラー、私の環境では、コマンドプロンプト上で実行すると発生するのだが、PowerShell上では発生しなかった。何故かは不明であるし、全くの偶然かもしれないし、別の要因で抑制されたのを勘違いしているだけかもしれないし、私の環境特有のエラーかもしれない。が、ひょっとしたら参考になるか、一時的な解決法になる人がいるかも知れないので、ここに記しておく。似たような事例があれば情報共有してほしい。