vcpkg の x86-windows-static-md triplet について

2 min read読了の目安(約1800字

vcpkg-rs を使うためにいくつか調べたのでメモ。microsoft/vcpkg は "C++ Library Manager for Windows, Linux and MacOS" ですが今回はこれの説明はしません。

Target Triplet in vcpkg

vcpkg にはライブラリを静的にリンクするか動的にリンクするかを指定するために x64-windows-staticx64-windows というビルドターゲット文字列 (triplet) を使います。例えば

vcpkg install openblas --triplet x64-windows

例えばこれで OpenBLAS が動的ライブラリ (.dll) としてビルドされ、

vcpkg install openblas --triplet x64-windows-static

これで OpenBLAS が静的ライブラリ (.a) としてビルドされます。

OpenBLAS は独自に BLAS と LAPACK の一部を最適化した C (+asm) のコードと netlib の LAPACK 実装をそのまま流用している部分があり、後者は Fortan 実装になります。上の方法は vcpkg -> cmake -> msbuild で Visual Studio の C compiler を用いて C 部分だけをコンパイルするため netlib 由来の Fortran 部分はコンパイルしません。
詳しくは OpenBLAS Wiki 及び GitHub の該当 issue を参照してください。

実はここにもう一つ種類があって x64-windows-static-md というものがあります

vcpkg install openblas --triplet x64-windows-static

これはライブラリ(この場合 OpenBLAS)は static に C Runtime (CRT) は dynamic にリンクします。これによりビルド成果物に CRT 分が含まれないのでサイズが小さくできます。代わりに実行時に CRT を検索する事になります。

この Triplet は vcpkg 本家ではなくコミュニティ管理になっています。Why should x64-windows-static-md not be the preferred triplet on Windows? この辺が詳しいです。

vcpkg-rs は 3 通りともサポートしており環境変数 VCPKGRS_DYNAMICRUSTFLAGS を見て処理を切り替えます。Rust 側で CRT を静的リンクしたい場合RUSTFLAGS=-Ctarget-feature=+crt-static と指定しますが、vcpkg-rs はこの時 x64-windows-static を使用するように切り替えます。