.NET MAUI の iOS ビルドで dotnet build -p:ArchiveOnBuild=true を実行すると、xxx.xcarchive が自動的に ~/Library/Developer/Xcode/Archives/ 配下へ生成されます。出力先を任意のフォルダーにしたい場合は、「Windows 側で保持されるアーカイブ」と「Mac 側で Xcode が管理するアーカイブ」を分けて考えると、最短で迷子にならずに解決できます。
.NET MAUI(iOS)の .xcarchive 出力先は 2 つ存在する
まず押さえておきたいのは、ArchiveOnBuild=true で作られる .xcarchive の“置き場所”は、環境によって 2 つの意味を持つことです。
| 観点 | Windows → Mac のリモートビルド | Mac ローカルビルド |
|---|---|---|
Mac 上で実際に生成される .xcarchive | 生成される(Xcode が管理する場所) | 生成される(Xcode が管理する場所) |
| Windows 側にコピーされて保持される“アーカイブ一式” | 保持される(既定パスあり/変更可能) | 存在しない |
| 「出力先を変更したい」の対象になりやすいのは? | Windows 側(変更できる)/Mac 側(基本は Xcode 側で管理) | Mac 側(基本は Xcode 側で管理) |
結論として、dotnet build コマンドだけで「Mac 上に作られる .xcarchive の出力先を任意パスへ直接指定する」手段は基本的に用意されていません。 一方で、Windows からのリモートビルドに限れば、Windows 側に保持されるアーカイブの保存先は MSBuild プロパティで制御できます。
そもそも .xcarchive とは何か(なぜ Xcode のフォルダーに入るのか)
.xcarchive は、iOS アプリを配布(TestFlight/App Store/社内配布など)するために必要な成果物をまとめた “Xcode のアーカイブ” です。中にはアプリ本体(.app)だけでなく、デバッグシンボル(.dSYM)や署名関連の情報、ビルド時のメタ情報などが含まれます。後から Xcode の Organizer で開いて .ipa を書き出したり、再署名・再エクスポートの材料にしたりする前提の形式です。
このアーカイブは Xcode が管理するため、既定では Mac の ~/Library/Developer/Xcode/Archives に日付ごとのサブフォルダーを作って保存されます。Xcode 自体がここを「過去のアーカイブ一覧」として扱うため、dotnet build 側から完全に自由な出力先へ“置き換える”というより、Xcode の管理領域に追加される挙動になります。
質問の核心:dotnet build で .xcarchive の出力先を指定できないか?
期待としては、次のようにコマンド側でパスを渡して、その場所へ xxx.xcarchive を作りたいはずです。
dotnet build -f net8.0-ios -c Release -p:ArchiveOnBuild=true -p:XxxArchivePath=/Volumes/BuildArtifacts/ios
しかし現状の .NET(iOS)/ .NET MAUI のビルドプロパティとして公式に用意されているのは、ArchiveOnBuild(アーカイブを作るかどうか)と、リモートビルド時に Windows 側へ保持する場所を変える ArchiveBasePath です。ArchiveBasePath は Windows 専用で、Mac ローカルビルドのアーカイブ出力先を変えるためのプロパティではありません。
Windows → Mac のリモートビルドなら「Windows 側の保存先」は変えられる
Visual Studio の「ペアリングして Mac でビルド」や、CLI で -p:ServerAddress などを指定してリモートビルドしている場合、ビルドの実体(Xcode ツールチェーンの実行)は Mac 側で動きます。それでも、結果として作られたアーカイブは Windows 側にもコピーされ、後から参照できるようにキャッシュされます。
この Windows 側に保持されるアーカイブの保存先 を変えるのが、MSBuild プロパティ ArchiveBasePath です。既定値は %LocalAppData%\Xamarin\iOS\Archives で、iOS のリモートビルドにのみ適用されます。
ArchiveBasePath をコマンドラインで指定する例
最も手軽なのは、リモートビルドのコマンドにプロパティとして渡す方法です。
dotnet build -f net8.0-ios -c Release ^
-p:ArchiveOnBuild=true ^
-p:ArchiveBasePath="D:\BuildArtifacts\iOS\Archives"
CI などで “成果物フォルダー” を決め打ちしている場合、ここを専用ドライブやワークスペース配下に寄せておくと、後工程(署名、アップロード、バックアップ)が組みやすくなります。
プロジェクト(または Directory.Build.props)で指定する例
毎回コマンドで渡すのが面倒なら、リモートビルド時のみ有効になるよう条件付きで設定しておくと運用が安定します。
<Project>
<PropertyGroup Condition="'$(OS)' == 'Windows_NT' and $(TargetFramework.Contains('-ios'))">
<ArchiveBasePath>D:\BuildArtifacts\iOS\Archives</ArchiveBasePath>
</PropertyGroup>
</Project>
ポイントは、Mac 側の ~/Library/Developer/Xcode/Archives を変える設定ではない ことです。あくまで「Windows が受け取って保持する置き場所」を制御します。
Mac 側で生成される .xcarchive の保存先を変えたい場合は Xcode 側で行う
Mac 上の ~/Library/Developer/Xcode/Archives は、Xcode がアーカイブを管理するための既定フォルダーです。dotnet build(または dotnet publish)でアーカイブを作っても、Xcode が参照する前提の場所に入ります。
保存先を別ドライブ(外付け SSD など)に移したい、あるいはチームの運用上「このボリュームに集約したい」という場合は、Xcode の設定で Archives の場所を変更します。一般的には Xcode の設定画面(Preferences / Settings)の「Locations」から Archives の保存先を変更できます。
また、どのアーカイブがどこにあるのかを確認したいときは、Xcode の Organizer(Archives)から対象を選んで Finder で表示するのが確実です。アーカイブが増えるとフォルダーが日付単位で分割され、名前もタイムスタンプ付きになるため、手探りで探すより Organizer 起点の方が安全です。
現実的な運用:ビルド後に .xcarchive をコピー/移動する
「とにかく毎回このフォルダーに置きたい」「CI の成果物として別フォルダーへ集めたい」といった要件の場合、最も事故が少ないのは ビルド後処理でコピー(または移動)する 方式です。dotnet build 側がアーカイブの出力先を自由に変えられないなら、生成されたものを拾って所定の場所へ寄せる、という考え方です。
Mac ローカルビルドで “最新のアーカイブ” をコピーする例(bash)
以下は、Xcode の Archives フォルダー配下から「最終更新が新しい .xcarchive を 1 つ」取得して、任意フォルダーへコピーする例です。プロジェクト名や日付フォルダー構成が変わっても比較的耐性があります。
#!/usr/bin/env bash
set -euo pipefail
ARCHIVES_DIR="$HOME/Library/Developer/Xcode/Archives"
DEST_DIR="/Volumes/BuildArtifacts/ios/xcarchive"
mkdir -p "$DEST_DIR"
LATEST="$(find "$ARCHIVES_DIR" -maxdepth 2 -type d -name "*.xcarchive" -print0
| xargs -0 ls -td
| head -n 1)"
echo "Latest archive: $LATEST"
cp -R "$LATEST" "$DEST_DIR/"
「移動」にしてしまうと、Xcode 側の管理(Organizer での参照)に影響する可能性があるため、まずはコピー運用が無難です。容量が気になる場合は、コピー後に世代管理(最新 N 件だけ残す)を組み合わせると、ディスク逼迫を避けやすくなります。
Windows → Mac リモートビルドなら “Windows 側のアーカイブ” を拾う方が簡単
リモートビルドの場合、Mac 側の Archives を直接触りに行くより、ArchiveBasePath で指定した Windows 側のフォルダー を成果物ディレクトリとして扱う方が運用が簡単です。後処理(ZIP 化、ネットワーク共有へコピー、CI の Publish Artifacts など)も Windows 上で完結し、権限や接続の問題を減らせます。
「Mac 上のフォルダーに必ず集約したい」事情がある場合は、Windows 側で拾ったアーカイブを、別途 SSH/SMB/rsync 等で Mac の所定ディレクトリへ転送する設計にすると、責務が分離できてトラブルシュートもしやすくなります。
成果物の目的から逆算する:.xcarchive が本当に必要か?
出力先にこだわる背景には「後工程で必要な成果物を確実に確保したい」という目的があるはずです。そこで、.xcarchive に固執せず、最終的に何を残したいのかを整理しておくと、運用が一段ラクになります。
| 残したいもの | 向いている用途 | 保管のコツ |
|---|---|---|
.xcarchive | Xcode での再エクスポート、将来の再署名、dSYM を含む完全セットの保管 | サイズが大きいので世代管理を前提にする |
.ipa | 配布(Ad-hoc/In-house/App Store アップロード前の成果物) | dotnet publish の出力をそのまま成果物化する |
.dSYM(シンボル) | クラッシュ解析(App Store Connect / Crashlytics など) | .ipa と同じビルド番号でセット保管 |
たとえば「最終的に欲しいのは .ipa だけ」というケースなら、dotnet publish の成果物(bin/Release/net8.0-ios/ios-arm64/publish/)を CI で拾う方がスッキリします。Microsoft のドキュメントでも、publish 後に .ipa が所定の publish フォルダーへコピーされることが説明されています。
よくある勘違いとハマりどころ
OutputPath を変えれば .xcarchive も移動する?
しません。bin/ や obj/ の出力先は .NET のビルド成果物(中間生成物・アセンブリ等)に関する設定で、Xcode アーカイブの保存先とは別物です。アーカイブは Xcode の管理領域(既定は ~/Library/Developer/Xcode/Archives)に置かれる設計です。
ArchiveBasePath を Mac で指定すれば、Mac 側の保存先も変わる?
変わりません。ArchiveBasePath は「Windows からのリモートビルドで、Windows 側に保存されるアーカイブ場所」を変えるためのプロパティです。公式ドキュメントでも Windows のリモートビルドに限定される旨が明記されています。
ディスクが急に圧迫される
.xcarchive は想像以上に容量を食います。しかも日付ごとに積み上がっていくため、気づいたら数十 GB になっていることも珍しくありません。不要なアーカイブを削除する運用(または定期クリーンアップ)を組み込むと安心です。アーカイブが保存される既定場所は ~/Library/Developer/Xcode/Archives です。
まとめ:やりたいこと別の最短ルート
| やりたいこと | 推奨アプローチ | 理由 |
|---|---|---|
| Windows → Mac リモートビルドで、Windows 側に保存されるアーカイブ先を変えたい | ArchiveBasePath を設定 | 公式にサポートされていて、運用が安定 |
Mac 側で生成される .xcarchive の保存場所を変えたい | Xcode の設定(Locations の Archives)で変更 | Xcode が管理する領域のため、Xcode 側の設定が筋 |
| 毎回決まったフォルダーに成果物を集めたい(CI/手作業問わず) | ビルド後にコピー/移動するスクリプトを組み込む | dotnet build 側で直接指定できない部分を運用で補える |
最終的に必要なのは .ipa だけ | dotnet publish の publish 出力を成果物にする | 所定フォルダーにまとまって出力され、後工程が簡単 |
「Mac 上の .xcarchive 出力先をコマンドで指定したい」という要求は自然ですが、現状は Xcode の管理領域に寄せる設計が前提です。まずは ArchiveBasePath で“Windows 側の置き場所”を確定させるか、Xcode 側で Archives の保存先を変更するか、あるいは後処理で拾って移すか——この 3 択で考えると、再現性の高い運用に落とし込めます。

コメント