Visual Studio 2022でビルドすると「Cannot open source file … No such file or directory」。ファイルは存在するのに、名前やフォルダ名を少し短くすると成功する…。原因は相対パスではなく、プロジェクトの場所まで含めた“完全パス長”がMAX_PATH制限を超えているケースが多いです。この記事では仕組みと現実的な回避策をまとめます。
現象:ビルド時に「Cannot open source file … No such file or directory」が出る
Visual Studio 2022でプロジェクトをビルドしたとき、次のようなエラーで止まることがあります。
Cannot open source file '...': No such file or directory- (C/C++の場合)
fatal error C1083: Cannot open include file: '...': No such file or directory
厄介なのは「ファイルが本当に無い」のではなく、エクスプローラーで見ると確かに存在しているのに、ビルドだけが失敗するケースがあることです。質問例では、対象ファイルのパス(相対パス側)は約124文字で、ファイル名やフォルダ名を短くして120文字以下にするとビルドが通る、という状況でした。
この挙動は、Visual Studioの設定で「特定の長さ以上のパスを禁止している」のでは?と疑いたくなりますが、実際はもう少しややこしく、“現在位置(プロジェクトの場所)+相対パス”で作られる完全パスが上限を超えていることが原因になりがちです。
原因:制限されているのは「完全パス長(MAX_PATH)」
Windowsや周辺ツールには、昔から知られるMAX_PATH(最大パス長)の制限があります。標準的なWin32 APIの扱いでは、パスは概ね260文字まで、という前提で実装されている箇所が残っています。
ポイントは、エラー判定に使われるのが「あなたが見ている相対パスの文字数」ではなく、次のようにして解決された完全パス(フルパス)の長さだという点です。
| 項目 | 内容 | なぜ問題になる? |
|---|---|---|
| カレントディレクトリ | ビルド時の作業ディレクトリ(例:プロジェクト/ソリューションの場所) | ユーザー名やOneDrive配下、深い階層だとここだけで長くなる |
| ファイルへの相対パス | ..\..\src\foo\bar\... のような相対参照 | フォルダ名が長い/階層が深いと増えやすい |
| 完全パス(フルパス) | 上記を結合して正規化したもの(例:C:\Users\...\repo\src\...) | この合計が260文字付近を超えると失敗するツールがある |
質問例のように「相対パスだけ見れば124文字」でも、プロジェクトが例えば C:\Users\ユーザー名\Documents\Visual Studio 2022\Projects\... のような場所にあり、そこに長い相対パスがぶら下がっていると、結合後の完全パスが260文字を超えることがあります。その結果、ツール側はファイルが存在していても開けず、表面的には「No such file or directory」と表示されます。
具体例:相対パスが短く見えても、完全パスで超えてしまう
「ファイル自体のパスは124文字しかないのに…」という疑問は自然です。ここで言う124文字が“相対パス部分”だとすると、次のようにベース(プロジェクトの場所)と足し算になるため、簡単に上限へ到達します。
| 要素 | 例 | 文字数のイメージ |
|---|---|---|
| プロジェクトの場所(ベース) | C:\Users\<User>\Documents\Visual Studio 2022\Projects\MySolution\ | 長くなりがち(ユーザー名・同期フォルダ・深い階層) |
| ファイルへの相対パス | src\Application-Protocols\network_transport\tcp_sockets_wrapper\...\foo.cpp | 説明的な命名だと増えやすい |
| 完全パス(結合後) | 上の2つをつないだフルパス | 合計が260文字付近を超えると失敗する可能性 |
さらに、ビルドでは obj や bin、生成コード、キャッシュなど「開発者が普段見ない場所」にも深いパスが作られます。見えているソースのパスが短くても、生成物側で先に限界を超えることもある点が落とし穴です。
目安:240文字を“危険ライン”として監視する
上限は“260文字”と説明されることが多いですが、実務では240文字あたりから危険と考えておくのが安全です。理由は、ビルド中にパスが付け足されたり、ツールごとに扱いが微妙に違ったりして、ギリギリ運用が破綻しやすいからです。
| 完全パス長の目安 | 状態 | おすすめの対応 |
|---|---|---|
| 〜200文字 | だいたい安全 | 通常運用でOK |
| 201〜239文字 | 注意 | 今後伸びそうなら早めに短縮策を検討 |
| 240〜260文字付近 | 危険 | 配置場所や生成物の出力先を短くしてバッファを確保 |
| 260文字超 | 高確率で失敗 | 根本の短縮が必要(移動、subst、mklink、出力先変更など) |
なぜ“存在するのに無い”と言われるのか
多くのコンパイラやビルドツールは、内部でWin32 APIを使ってファイルを開きます。ところが、古い前提(MAX_PATH)で作られた処理では、パスが長すぎるとAPI呼び出しに失敗します。このとき、失敗理由が「パスが長すぎる」ではなく「開けない(=見つからない)」に丸められてしまうことがあり、結果として“無いと言われる”状態になります。
MAX_PATHの基本:260文字の壁と「長いパス」
MAX_PATHの「260」は、厳密には終端のヌル文字なども含めた歴史的な都合に由来します。Windowsでは、\\?\ というプレフィックス(拡張パス)を使うことで、理論上はもっと長いパス(最大約32,767文字)も扱える仕組みがあります。
ただし重要なのは、OSが仕組みを持っていることと、あなたが使っているアプリやツールチェーンがそれに対応していることは別問題、という点です。Visual Studio 2022のビルドは、IDE本体だけで完結しておらず、MSBuild、コンパイラ、リンカ、SDK、NuGet、各種タスクなど多くの部品が関わります。そのどこかに“長いパス非対応”が残っていると、最終的にビルドが落ちます。
Visual Studio 2022で長いパス問題が起きやすい典型パターン
「ソースの相対パスが長い」だけが原因ではありません。開発スタイルやフレームワークによって、ビルド中に生成されるパスが急激に伸びることがあります。
| パターン | 具体例 | パスが伸びる理由 |
|---|---|---|
| ユーザープロファイル配下で開発 | C:\Users\<User>\Documents\... や OneDrive 配下 | ベースが長い。さらにリポジトリ名/ブランチ名が長いとすぐ限界 |
| .NET/SDKスタイルのプロジェクト | obj\Debug\net8.0\... や生成物が多い | 中間生成フォルダが深く、ファイル名も長くなりやすい |
| NuGetパッケージが深い | .nuget\packages\<package>\<version>\lib\... | 依存が多いほど階層が増え、ベースフォルダが長いと刺さる |
| クロスプラットフォーム開発 | XCFramework、.NET MAUI 等で生成・展開物が増える | 生成されるサブディレクトリ名が機械的に長くなりやすい |
| CMake/外部ビルドディレクトリ | ビルド用フォルダに構成名が付いて長い | 構成ごとに深いディレクトリが切られ、フルパスが増える |
質問に出てくるような Application-Protocols\network_transport\tcp_sockets_wrapper\ports\freertos_plus_tcp\ といった「説明的で長いフォルダ名」は、設計意図としては分かりやすい反面、Windowsの制約と相性が悪いことがあります。特に外部ライブラリや生成物が絡むと、フォルダ名を短縮するだけでは追いつかないこともあります。
まずはここを確認:原因切り分けチェックリスト
「本当に長いパスが原因か」を早く見極めるために、次の観点でチェックします。
- エクスプローラーで開けるか(開けても、ビルドツールが開けるとは限りません)
- 完全パスをコピーして長さを確認(文字数が260付近/超過していないか)
- ビルド中に参照しているのが“どのファイル”か(ソース本体だけでなく、生成物・一時ファイル・ヘッダやリソースも対象)
- どのツールが失敗しているか(MSBuildのタスク、コンパイラ、リンカ、パッケージ復元など)
PowerShellで“最長パス”をざっくり調べる例
リポジトリ直下で次のように実行すると、ファイルの完全パス長の最大値を確認できます(ファイル数が多いと時間がかかります)。
Get-ChildItem -Recurse -File |
Select-Object -ExpandProperty FullName |
ForEach-Object { $_.Length } |
Measure-Object -Maximum
特定の閾値(例:240文字以上)を超えているファイル一覧を出すなら、次のようにします。
$threshold = 240
Get-ChildItem -Recurse -File |
Where-Object { $_.FullName.Length -ge $threshold } |
Sort-Object { $_.FullName.Length } -Descending |
Select-Object @{Name='Length';Expression={$_.FullName.Length}}, FullName
「自分が開けないのはこのファイルだけ」と思っていても、実際には obj 配下やパッケージ配下の別ファイルが閾値を超えていることも多いので、まずは全体像をつかむのが近道です。
ビルドログで「どのパスが長いのか」を特定する
長いパス問題は、エラーメッセージに出ているファイルが“犯人”とは限りません。たとえば、C/C++のインクルード解決、生成コード、リソース変換、NuGet復元など、別工程で先に失敗していることがあります。
次のいずれかでログを増やし、実際にどのフルパスで失敗しているかを確認すると、対策の優先順位が付けやすくなります。
- Visual Studioの出力詳細を上げる:「ツール」→「オプション」→「プロジェクトおよびソリューション」→「ビルド/実行」→「MSBuild プロジェクト ビルド出力の詳細」を「詳細」または「診断」にする
- コマンドラインでMSBuildを診断出力:
msbuild /v:diag(ログは巨大になりやすいので注意) - バイナリログを取る:
msbuild /blで.binlogを出し、ログビューアで検索する(文字列検索がしやすい)
ログでフルパスが見えるようになると、「ソースのフォルダ名を短くすべきか」「それとも obj/packages の出力先を変えるべきか」が判断しやすくなります。
Visual Studio 2022では“決定的な解決策が無い”と言われる理由
Windows側には長いパスを扱う仕組みがある一方で、Visual Studioのビルドは複数の実行ファイル・タスク・SDKを経由します。すべてが完全に長いパス対応になっていない限り、どこかで詰まります。
実際、開発者コミュニティなどでも「長いパスでもビルド・実行・デバッグまで通るようにしてほしい」という要望は継続的に出ています。これは裏を返すと、現時点では“設定ひとつで完全解決”という状態ではない、ということでもあります。
そのため、当面はパスを短くする方向のワークアラウンドが現実的です。次章では、効果が出やすい順に対策を整理します。
現実的な回避策:まずは「根本を短くする」
プロジェクトをルートに近い場所へ移動する(最も効く)
一番確実で、チームにも展開しやすいのが「プロジェクトの置き場所」を短くすることです。例えば次のように、開発用の固定フォルダを作ります。
| 例 | メリット | 注意点 |
|---|---|---|
C:\src\<repo>\ | 短い・覚えやすい・多くのツールで相性が良い | 会社PCの運用ルール(保存場所制限)に注意 |
D:\work\<repo>\ | 容量の大きいドライブに逃がせる | ドライブ文字が人によって違うと手順書がブレる |
C:\_w\<repo>\ | さらに短い。CIやローカル検証で便利 | フォルダ名が意味不明になりすぎないように注意 |
質問例のように「相対パス側が124文字」でも、ベースが短ければフルパスは余裕を持てます。逆に、ベースが長いと少しの追加で限界を超えます。迷ったら、まずはリポジトリを C:\src\ のような短い場所へ移動してください。
substで仮想ドライブを作って“見かけ上のパス”を短くする
「会社のルールで場所を動かせない」「OneDrive配下に置く必要がある」などで移動が難しい場合、subst で長いパスをドライブレターに割り当てる方法があります。
subst X: "C:\Users\<User>\OneDrive\Documents\Very\Long\Path\To\Repo"
この状態で X:\ からソリューションを開くと、フルパスの見かけが短くなり、ツールが通ることがあります。
- メリット:元のフォルダを移動せずに短縮できる
- デメリット:再起動で解除されることが多い(ログオン時に再設定が必要)
mklink /J(ジャンクション)やシンボリックリンクで短い入口を作る
もう少し永続的にしたい場合は、NTFSのリンク機能を使って短いパスの入口を作る方法があります。
mklink /J C:\src\repo "C:\Users\<User>\Documents\Very\Long\Path\To\Repo"
以後は C:\src\repo 側から開発します。リンク運用はチームルールに合わせてください(セキュリティ設定や管理者権限が絡む場合があります)。
生成物が長い場合の対策:obj/binやパッケージの場所を短縮する
プロジェクトを移動しても、obj や bin、依存パッケージの展開先が原因で限界を超える場合があります。ここでは“ビルドが作るパス”を短くする方法をまとめます。
MSBuild(.NET)で中間出力パスを短くする
SDKスタイルのプロジェクトでは、デフォルトで obj\<Configuration>\<TFM>\ のような深い階層が作られます。全プロジェクトに適用したい場合、リポジトリ直下に Directory.Build.props を置き、次のように中間出力のベースを短い場所に寄せます。
<Project>
<PropertyGroup>
<!-- 例:C:\_build\obj\ に集約(チームで揃える) -->
<BaseIntermediateOutputPath>C:\_build\obj\</BaseIntermediateOutputPath>
<!-- 生成物も短縮したい場合 -->
<BaseOutputPath>C:\_build\bin\</BaseOutputPath>
</PropertyGroup>
</Project>
この方法は効果が大きい反面、PCごとに書き込み権限やクリーン手順を揃える必要があります。チーム開発では「開発環境セットアップ手順」に必ず明記し、CI(ビルドサーバー)でも同じポリシーにすると事故が減ります。
NuGetのグローバルパッケージフォルダを短くする
NuGetは既定でユーザープロファイル配下の長い場所にパッケージを展開します。依存が多いと、パッケージ配下の深い階層でMAX_PATHに引っかかることがあります。
対策としては、環境変数 NUGET_PACKAGES でグローバルパッケージフォルダを短い場所へ移す方法が定番です。
setx NUGET_PACKAGES C:\nugetpkgs
または、リポジトリに nuget.config を置いてチームで揃える方法もあります。
<configuration>
<config>
<add key="globalPackagesFolder" value="C:\nugetpkgs" />
</config>
</configuration>
Gitのクローン先を短くする(チェックアウト問題の予防にも)
Windowsでは、ビルド以前に「Gitが長いパスのファイルをチェックアウトできない」問題も起きます。リポジトリを短い場所(例:C:\src)にクローンするだけで、ビルドとチェックアウト両方のトラブルを減らせます。
加えて、Git for Windowsでは設定 core.longpaths が関係する場合があります。これは「Gitが長いパスを扱えるか」に影響する設定で、ビルドツール側の制限とは別物です。長いパスが絡むリポジトリでは、チェックアウト段階の問題切り分けに役立ちます。
Windowsの設定「長いパスを有効化」はどこまで効く?
Windows 10/11やWindows Serverには、Win32長いパスを有効化する設定があります。これを有効にすると、長いパス対応(longPathAware)なアプリでは、260文字を超えるパスが扱えるようになります。
| 項目 | 期待できること | 期待しすぎない方がよいこと |
|---|---|---|
| Win32長いパスの有効化 | 対応済みアプリでは長いパス操作が可能になる | 非対応ツール(または一部コンポーネント)では相変わらず失敗する |
| Visual Studio / ツールチェーン | 一部の操作が改善する可能性 | ビルド全体が完全に通る保証にはならない |
設定の入口は環境によって異なりますが、代表例としては次のようなものがあります。
- ローカルグループポリシー:
コンピューターの構成 > 管理用テンプレート > システム > ファイルシステム > Win32 の長いパスを有効にする - レジストリ:
HKLM\SYSTEM\CurrentControlSet\Control\FileSystemのLongPathsEnabledを1
ただし、繰り返しになりますが、Visual Studioのビルドは“全部が長いパス対応である必要がある”ため、ここだけで完全解決できないことが多いです。先に紹介した「配置場所を短くする」「生成物の場所を短くする」ほうが、再現性と効果が高いケースが目立ちます。
フォルダ構成の見直し:短くしても意味が伝わる命名のコツ
長いフォルダ名は、設計意図や役割が伝わるメリットがあります。一方でWindowsのパス制限を踏むと、開発効率が一気に落ちます。ここでは“短くしても破綻しない”ためのコツをいくつか挙げます。
- 重複語を削る:
application_protocols\protocols\のような重複は1つに - 略語を決めて統一:
transport→tp、wrapper→wrapなど、プロジェクト内ルールで固定 - 階層を“用途”でまとめる:細かい分類を深く掘るより、用途フォルダに集約して深さを減らす
- 外部依存は入口を短く:サードパーティは
3rdやextに集約し、必要ならリンクで逃がす
チーム開発・CIでの再発防止策
この問題は、個人PCでは回避できても、別のメンバーやCI環境で再発しやすいのが特徴です。次のような運用を入れておくと、後工程での炎上を防げます。
開発ルートを標準化する
オンボーディング手順に「必ず C:\src 配下で作業する」などのルールを明記し、全員が同じ“短い根本”から始めるようにします。これだけで、MAX_PATH起因の不具合は体感で大幅に減ります。
“長すぎるパス”を検出するスクリプトを用意する
リポジトリにPowerShellスクリプトを同梱し、しきい値(例:240文字)を超えるファイルが増えたら通知する仕組みを入れると、深い階層が静かに増殖するのを防げます。CIでのチェックにも向きます。
生成物・キャッシュの置き場所を固定化する
NUGET_PACKAGES や BaseIntermediateOutputPath をチームで揃え、環境差によるパスの伸びを抑えます。特に .NET MAUI や複数ターゲット(TFM)を扱うプロジェクトでは効果が出やすいです。
よくある質問
ファイルパスが124文字なのに、なぜ制限に引っかかるの?
見えているのが相対パス(または一部のパス)で、ビルドツールが実際に扱うのは「カレントディレクトリ+相対パス」で解決された完全パスだからです。プロジェクトの置き場所が長いほど、簡単に上限へ到達します。
Windowsで長いパスを有効にすれば全部直る?
対応済みのアプリでは改善しますが、Visual Studioのビルドは複数ツールの集合体なので、どこかが非対応だと落ちます。まずは「ルートを短くする」「生成物の場所を短くする」の2本立てが確実です。
相対パスを絶対パスに変えれば解決する?
多くの場合、絶対パスはむしろ長くなるため逆効果です。根本(リポジトリの配置場所)を短くするほうが再現性が高いです。
クロスプラットフォーム開発(XCFrameworkやMAUI)だと限界がある
生成物や依存の展開でパスが伸びやすく、単純な短縮だけでは厳しいケースがあります。そのため、製品側(IDE/ツールチェーン)の改善を待っている開発者が多い状況です。とはいえ現時点では、短いルートへ移動し、キャッシュや中間出力を短い場所へ寄せるのが現実的な落とし所になります。
まとめ:まず“根本を短くする”が最短ルート
Visual Studio 2022で長いパスが原因の「Cannot open source file」系エラーが出る場合、制限されているのは相対パスの見た目ではなく、結合後の完全パス長(MAX_PATH)である可能性が高いです。
- 最優先:リポジトリ/ソリューションを
C:\srcなど短い場所へ移す - 次点:
substやmklinkで短い入口を作る - 生成物対策:
BaseIntermediateOutputPath、NUGET_PACKAGES等で“ビルドが作るパス”も短くする
「パスを短くする」は地味ですが、最も再現性が高く、チーム・CIまで含めて効く対策です。まずはベースの置き場所を見直し、必要なら生成物の置き場所も含めて短縮してみてください。

コメント