- Windowsネイティブ開発は Visual Studioのインストール依存 により複雑で非効率
- 数十GBのインストール容量、不透明なコンポーネント管理、バージョン不一致の問題 などが開発者の生産性を低下させる
- これを解決するため、軽量CLIツール
msvcup を開発し、MSVCツールチェーンとWindows SDKを バージョン別・分離された形で自動インストール 可能にした
msvcup は JSONマニフェストの解析、自動環境設定 (autoenv)、ロックファイル対応 などを通じて再現可能なビルド環境を提供
- このアプローチにより、Visual Studio Installerに依存せず スクリプトベースの完全自動化ビルド体制 を実現できる
Windowsネイティブ開発の問題点
- Visual Studioをインストールしなければならない従来方式は、複雑なインストール手順と不安定な依存関係管理 により開発者の負担になっている
- 「Desktop development with C++」ワークロードや特定のSDKバージョンなど、細かな選択が必要で、誤るとビルド失敗が発生する
- インストール容量は50GBに達し、削除後も レジストリの残存項目やバックグラウンドサービス が残る
- Linux ではパッケージマネージャのコマンド一発でツールチェーンを導入できる一方、Windowsでは数千ものコンポーネントを手動で選ばなければならない
- Visual Studioは エディタ、コンパイラ、SDKが絡み合った単一構造 で、バージョン管理や環境再現が難しい
- その結果、「自分のPCでは動く」という類いの不一致が頻発し、これは ネイティブ開発の参入障壁 として作用する
msvcup: 新しいアプローチ
- msvcup は、Visual Studioをインストールせずに MSVCツールチェーンとWindows SDKを直接ダウンロード・インストール するオープンソースのCLIツール
- 各バージョンは
C:\msvcup\ 配下の 分離されたディレクトリ にインストールされ、バージョン間の衝突なく並行利用できる
- インストールは 数分以内に完了 し、ARMクロスコンパイルツールも自動で含まれる
msvcup install コマンドは必要なパッケージを導入し、autoenv コマンドは 自動環境ディレクトリ を生成する
- このディレクトリには、環境変数を自動設定する ラッパー実行ファイル と
toolchain.cmake ファイルが含まれ、CMakeプロジェクトも追加設定なしでビルドできる
build.bat スクリプト例では、msvcup を通じて “Hello, World” プログラムを Visual Studioなしで ビルドできる
- Windows 10以降の環境で
curl と tar さえあれば動作する
内部動作の仕組み
- Microsoftが配布する Visual StudioコンポーネントのJSONマニフェスト を解析し、必要なパッケージだけを特定
- コンパイラ、リンカ、ヘッダ、ライブラリなどの中核要素のみをMicrosoft CDNから直接ダウンロードする
- インストール済みコンポーネントは ロックファイル (lock file) で管理され、同一バージョンのパッケージをチーム全体で共有できる
install および autoenv コマンドは 冪等性 (idempotent) を持ち、すでにインストール済みなら数ミリ秒で完了する
実際の適用事例
- Tuple(ペアプログラミングアプリ)は
msvcup をCIビルドシステムに統合し、Visual Studioの事前インストール要件を排除
- WebRTCを含む数百のC/C++プロジェクトを同一のツールチェーン/SDKでビルドできる
- x86_64とARMビルドの両方をサポート
- 利点
- バージョン別ディレクトリへのインストールにより 並行バージョン管理と容易な再インストール が可能
- クロスコンパイルを自動サポート し、追加設定が不要
- ロックファイルベースで再現性を保証 し、Microsoft側の変更も即座に把握できる
- 高速な実行速度、不要な再インストールなし
制限と拡張
msvcup は コンパイル用ツールチェーン中心 に設計されており、Visual Studio IDE自体が必要な場合は公式インストールが依然として必要
- しかし大半のネイティブ開発ワークフローでは、IDEなしでも完全なビルド環境 を提供できる
- 例として示された raylibビルドスクリプト は、Visual StudioなしでもSDKとツールチェーンを自動インストールしてプロジェクトをビルドする
- GUIなしでコマンドラインだけによる 完全自動化ビルドプロセス を実行
結論
5件のコメント
Hacker Newsの意見
自分がやっていることより、これはもっと複雑に見える。
単に LTSC Visual Studio Build Tools をインストールして、
cl yourprogram.c /link user32.lib advapi32.lib ...のようなコマンドを cmd ファイルに入れればいい。自分は vim で編集して、こういう形でいろいろなユーティリティをビルドしてきた。
Visual Studio のツールチェーンには LTSC と安定版 があるが、たいていの人はそれを知らない。
協業環境なら、公式リリース履歴ドキュメント にある固定バージョンを使うのがよい。
昔のように、会社全体で同じツールチェーンのバージョンに固定して使っていた時代のように。
なので学生や趣味の開発者は知らないことが多い。
一方で、会社で VS を使っている人はたいてい知っている。
いつ出るか知っている人はいる?
Linux のツールチェーンも 依存関係地獄 から自由ではない。
npm パッケージをインストールしていたら cmake が必要になったり、glibc のバージョン衝突が起きたり、最新の boost を要求する C++ プロジェクトがあったり……。
heartbleed のときに openSSL にパッチを当てていた記憶も残っている。
Visual Studio も不便だが、本当の地獄は .NET Framework のバージョン混乱 だ。
Windows のバージョンごとにインストールされている .NET のバージョンが違い、アプリがどのランタイムで動くのかもはっきりしない。
そのため大規模配布では、C++ で .NET バージョン確認用の shim を作って、正しいランタイムで実行されるようにしなければならない。
glibc チームは 下位・上位互換性 に非常に厳格だ。
LWN の記事 を見ると、最後に互換性が壊れた時点がわかる。
問題は、人々が glibc のバージョンを誤って固定(pinning)してしまうことだ。
glibc はバージョン固定してはいけない。
GCC は何度か互換性を壊したことがあるが、そのほとんどは C++ 標準の変更が理由だった。
.NET Framework はすでに レガシー で、.NET 5 以降ではこうした問題はない。
ただし、いまだに旧バージョンに依存するアプリは多い。
問題は解決したが、同時に 新しい複雑さ も生み出した。
ときどき、ただシステムパッケージマネージャの時代に戻りたくなる。
組み込み環境では rust + probe-rs のほうがずっと快適だ。
Visual Studio インストーラーは コマンドライン引数 で無人インストールが可能だ。
公式ドキュメント に説明がある。
2018 年にインターネットが遅い衛星回線環境で働いていたとき、オフラインインストールパッケージを作る必要があって、この方法を使った。
スクリプトを見ると、
curl -L -o msvcup.zip https://github.com/marler8997/msvcup/releases/...こんな感じになっている。
だが、出所不明の GitHub アカウントの実行ファイル をハッシュ検証もなしにインストールするのは気が進まない。
Windows の状況はブログで言うほど悪くはないが、これは解決策というより、また別の危険なインストールスクリプトに見える。
ただスクリプトを 自分で読んで確認 すればいい。
curl|sh 方式も結局はソースコードを取得するだけで、実行ファイルをそのままインストールするより危険というわけではない。
彼のプロジェクト zigwin32 は Microsoft の win32metadata からもリンクされている。
つまり信頼できる人物だ。
この記事、AI が書いたように 感じる。
“it’s not just X, but Y” のような文構造や強調リストが、典型的な LLM スタイルだ。
このプロジェクトがどれだけ人間によって作られたものなのか気になる。
リスト構造がぎこちなく、一貫性も足りなかった。
でももし LLM が書いたのだとしたら、最近の LLM の品質がかなり上がっている証拠 かもしれない。
Grammarly のようなツールの影響かもしれない。
そのほうが読者にとって読みやすいから。
ただ、AI を使ったかどうかは率直に明かしてほしい。
Visual Studio DX を改善しようとする試みとして、msvcup は本当に新鮮だ。
昔、大学時代にこういうものがあればよかったのにと思う。
代替案としては、コンテナに Build Tools をインストールする 方法もある。
単に winget でインストールすればいい。
winget install --id Microsoft.VisualStudio.2022.BuildToolsWinRT 機能が必要なら
winget install --id Microsoft.WindowsSDK.10.0.18362winget install --id Microsoft.WindowsAppRuntime.1.8を追加できる。どの workload をインストールするかも指定しなければならず、プロジェクトを知らないと試行錯誤が多くなる。
.vsconfigが多少助けてくれるが、完璧ではない。オープンソースプロジェクトが MinGW 対応 を妨げないでほしい。
追加 DLL なしでもよく動く、優れたコンパイラだ。
オープンソースがなぜわざわざ独占的なコンパイラを強制するのか理解できない。
WIL はカーネル開発者が好んで使うライブラリで、コードの安全性と利便性を大きく高めてくれる。
たとえば Steamworks SDK は MinGW でビルドできるが、ランタイムでクラッシュする。
このブログ記事でも言及すらされていなくて残念だ。
単に Clang + MSVC STL + WinSDK の組み合わせのほうがずっときれいだ。
あるいは、こんなふうにシンプルにもできる。
"winget install Microsoft.VisualStudio.BuildTools""winget install Microsoft.WindowsSDK.10.0.26100"手間に対する安定性 が高いので好んでいる。
すべての言語に Python uv のようなバージョン分離ツール があればいいのにと思う。
Bing、Copilot、広告のようなものは批判されて当然だが、ほとんどは 無効化可能 だ。
私も Ubuntu 24.04 でビルドして CentOS 6 か 7 で実行しようとしたら、glibc の依存性の問題が発生しました。
デフォルトでビルド環境の glibc バージョンを持っていってしまうのが問題のようです。
glibc はどうしても依存せざるを得ませんね..
python/jv/.net/js のようなスクリプト言語ではない以上、glibc への依存は避けられません
ディストリビューションごとにライブラリを配布する理由でもありますね
少なくとも glibc でビルドしたものは、特別な依存関係がなければ、より上位バージョンの別ディストリビューションでも十分実行可能です
WSL2 で Ubuntu を使うことで、Windows でもかなり開発しやすくなりましたよね。ただ、VSCode ではなく Visual Studio 環境なら、これはそれなりに役立ちそうです。でも、
chocoやwingetのようなパッケージマネージャーでは Windows 上でできないみたいですね。パッケージマネージャーは、SDKよりも最終成果物に重点を置いているようではありますね。
vcredistのようなものは、たいていの開発者がパッケージマネージャーのスクリプト内でインストールするように設定しているようですが、ビルド環境は少し話が違います。