UE 5.8のソースビルドにおけるUnreal Engine UBA Executor UBT Errorの修正方法
要点まとめ
Unreal Engine 5.8のソースビルドにおいて、再帰的UBT呼び出し時にUBA Executorがクラッシュする問題の原因と解決策を解説します。このエラーはUBA Executorが再帰処理に対応していないために発生し、BuildConfiguration.xmlによるグローバルな無効化、またはExecutorFactory.csへのC#コードパッチの適用によって回避可能です。パッチ適用を行うことで、メインビルドにおけるUBAによる高速化の恩恵を維持したまま、安全にビルドを通すことができます。また、メモリ管理やDedicated Server用アセットのストリッピングなど、ソースビルドの安定化に向けたベストプラクティスも紹介します。
エンジンのビルドが壊れることほど、スタジオの開発モメンタムを低下させるものはありません。特にUnreal Engine 5.8.0をソースからコンパイルしている最中に、Visual Studioが謎の例外を出して停止した場合はなおさらです。ビルドはUBAExecutor.csを直接指し示す未処理の例外で失敗します。unreal engine uba executor ubt errorとして知られるこの特有のブロッカーは、コンパイルを完全に停止させます。これにより、Build GraphがUnrealHeaderToolなどの重要なヘルパープログラムの生成を完了できなくなります。本ガイドでは、Unreal Build Accelerator(UBA)がネストされた呼び出しで問題を起こす理由、デフォルト設定が失敗する仕組み、そしてビルドパイプラインを復旧するためにエンジンソースをパッチする方法について詳しく解説します。
ビルドシステムのアーキテクチャを理解する
このエラーが発生する理由を理解するには、Unreal Build Tool(UBT)がどのようにコンパイルをオーケストレーションしているかを調査する必要があります。Unreal Engineのコードベースは非常に巨大であり、多くの場合、数万ものソースファイルが含まれています。これらを効率的にコンパイルするために、UBTはメタビルドシステムとして機能し、依存関係グラフを生成してコンパイルアクションをディスパッチします。
Unreal Build Acceleratorとは?
Epic Gamesは、古い分散ビルドシステムに代わるデフォルトのコンパイルエグゼキュータとして、Unreal Build Accelerator(UBA)を導入しました。UBAは、軽量な仮想化ファイルシステム(VFS)を利用してファイルI/O操作をインターセプトすることにより、コンパイルを高速化するように設計されています。コンパイラのタスクを複数のローカルコアにルーティングするか、またはHordeビルドノードに分散させます。
標準的な64コアのビルドマシンにおいて、UBAはエンジンのクリーンビルド時間を約90分から25分未満に短縮できます。しかし、UBAはI/Oをインターセプトするために中央集中型のローカルエージェントに依存しているため、コンパイラプロセスの生成方法を厳密に制御する必要があります。
再帰的UBT呼び出しのメカニズム
コンパイルの実行中、UBTはメインのエンジンバイナリをコンパイルする前にビルドしなければならないターゲットに頻繁に遭遇します。例えば、UnrealEditor実行ファイルをコンパイルする前に、UBTはヘッダーファイルをパースしてリフレクションメタデータを生成するためにUnrealHeaderTool(UHT)をコンパイルする必要があります。
これを実現するために、プライマリUBTプロセスはネストされたセカンダリUBTプロセスを生成し、前提条件となるターゲットをビルドします。このネストされた呼び出しは「再帰的UBT呼び出し」と呼ばれます。再帰的UBT呼び出しがアクティブな場合、UBTは内部フラグ(UnrealBuildTool.IsRecursive = true)を設定し、環境変数を伝播させてプロセスがネストされていることをマークします。
なぜUBA Executorは再帰呼び出し時にクラッシュするのか
このクラッシュは、UBAエグゼキュータがネストされたコンパイルループをサポートするようにアーキテクチャ設計されていないために発生します。Visual Studioでこのエラーが発生したときにUBTによって出力される典型的なコールスタックを見てみましょう。
Unhandled exception: Exception: UBA executor is not expected to be invoked from a recursive UBT call.
at UnrealBuildTool.UBAExecutor.Init(IEnumerable`1 targetDescriptors, ILogger logger) in UnrealEngine\Engine\Source\Programs\UnrealBuildTool\Executors\UnrealBuildAccelerator\UBAExecutor.cs:line 315
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
at UnrealBuildTool.UBAExecutor.ExecuteActionsAsync(IEnumerable`1 inputActions, ILogger logger) in UnrealEngine\Engine\Source\Programs\UnrealBuildTool\Executors\UnrealBuildAccelerator\UBAExecutor.cs:line 617
at UnrealBuildTool.ActionGraph.InternalExecuteActions(ActionExecutor Executor, List`1 ActionsToExecute, ILogger Logger) in UnrealEngine\Engine\Source\Programs\UnrealBuildTool\Actions\ActionGraph.cs:line 435
UBAExecutor.csにおけるセーフティチェック
UBAExecutor.Initメソッド内部(UBAExecutor.csの315行目付近)で、エンジンは明示的に再帰セーフティチェックを実行しています。
// Engine/Source/Programs/UnrealBuildTool/Executors/UnrealBuildAccelerator/UBAExecutor.cs
public void Init(IEnumerable<TargetDescriptor> TargetDescriptors, ILogger Logger)
{
if (UnrealBuildTool.IsRecursive)
{
throw new Exception("UBA executor is not expected to be invoked from a recursive UBT call.");
}
// Virtualized file system and network initialization follow...
}
このセーフティチェックが存在するのには、極めて重要な理由があります。ローカルのUBAエージェントは、仮想化されたコンパイラヘルパープロセスと通信するために、特定のTCPポートにバインドします。
もし再帰的なUBT呼び出しがUBA Executorの2つ目のインスタンスを初期化しようとすると、両方のインスタンスが同じネットワークソケットにバインドしようとし、仮想化ファイルシステムのフックをめぐって競合が発生します。これはソケット割り当てエラー、ファイルシステムの破損、または無期限のビルドデッドロックを引き起こすことになります。この例外は保護バリアとしての役割を果たしているのです。
根本原因:Executor選択の失敗
Unreal Engine 5.8.0のソースビルドにおける本当のバグは、このセーフティチェック自体ではありません。むしろ、エグゼキュータファクトリのロジックが再帰呼び出しを正しく処理できていないことにあります。
UBTがどのエグゼキュータを使用するかを決定する際、ExecutorFactory.csクラスを照会します。ファクトリは、ホストマシンでUBAが有効かつ利用可能かどうかを確認します。
しかし、現在のUBTプロセスが再帰的実行であるかどうかは検証しません。その結果、UnrealHeaderToolをコンパイルするためにセカンダリUBTプロセスが起動した際、ファクトリはネストされたビルドにUBAExecutorを割り当てようとし、Initメソッドでクラッシュを誘発します。
XML設定の罠
多くの開発者は、グローバルなBuildConfiguration.xmlファイルを変更することで、この問題を回避しようと試みます。古いフォーラムの投稿における標準的なアドバイスは、以下のタグを無効にしてUBAをオフにすることです。
<?xml version="1.0" encoding="utf-8" ?>
<Configuration xmlns="https://www.unrealengine.com/BuildConfiguration">
<BuildConfiguration>
<bAllowUBA>false</bAllowUBA>
</BuildConfiguration>
</Configuration>
なぜUE 5.8ではbAllowUBAが無視されるのか
上記のXML設定をUnreal Engine 5.8.0のソースビルドに適用しても、コンパイラは依然としてUBAを起動しようとし、例外をスローします。これは、エンジンのビルド設定システムがリファクタリングされたためです。
古いbAllowUBAフラグは非推奨となり、エグゼキュータ選択ロジックにはマッピングされなくなりました。代わりに、UBAの挙動はbAllowUBAExecutorとbAllowUBALocalExecutorという2つの異なるプロパティによって制御されます。
XMLファイル内にbAllowUBAExecutorが見つからないため、UBTはデフォルトでtrueを適用します。これにより、UBAをオフにしようとする試みが暗黙的に上書きされてしまいます。
UBA設定の正しいXML構造
設定ファイルを介してUBAを正常に無効化するには、更新されたXMLプロパティ名を使用する必要があります。UBTを強制的に標準のローカルエグゼキュータにフォールバックさせるための正しい構造は以下の通りです。
<?xml version="1.0" encoding="utf-8" ?>
<Configuration xmlns="https://www.unrealengine.com/BuildConfiguration">
<BuildConfiguration>
<bAllowUBAExecutor>false</bAllowUBAExecutor>
<bAllowUBALocalExecutor>false</bAllowUBALocalExecutor>
</BuildConfiguration>
</Configuration>
この設定により、UBAをバイパスすることに成功します。ただし、UBAを完全に無効化すると、プライマリのビルドアクションで得られるはずだった大幅なコンパイル速度向上という恩恵を失うことになります。
エラー修正のステップバイステップガイド
ワークフローに応じて、XML設定を変更してこの問題をグローバルに解決するか、あるいはUBTのソースコードに直接パッチを適用して、再帰的でないコンパイルに対してビルドアクセラレーション(Build Acceleration)を維持するかを選択できます。
方法1:BuildConfiguration.xmlによる上書き
エンジンのソースコードを変更したくない場合は、UBAをグローバルに無効化できます。これはプロジェクトをコンパイルできるようにする最も手っ取り早い方法ですが、ハードウェアのスペックによっては、クリーンビルドのコンパイル時間が約40%〜60%増加することになります。
- グローバルな
BuildConfiguration.xmlファイルを見つけるか、新規作成します。Windowsの場合、通常は%AppData%\Roaming\Unreal Engine\UnrealBuildTool\BuildConfiguration.xmlにあります。Linuxの場合、~/.config/Unreal Engine/UnrealBuildTool/BuildConfiguration.xmlにあります。 - テキストエディタでXMLファイルを開きます。
- 内容を以下に示す更新されたXMLスキーマに置き換えます。
- ファイルを保存し、Visual Studioのビルドを再開します。
<?xml version="1.0" encoding="utf-8" ?>
<Configuration xmlns="https://www.unrealengine.com/BuildConfiguration">
<BuildConfiguration>
<bAllowUBAExecutor>false</bAllowUBAExecutor>
<bAllowUBALocalExecutor>false</bAllowUBALocalExecutor>
</BuildConfiguration>
</Configuration>
方法2:UBTソースコードのパッチ適用(推奨)
Unreal Engine 5.8をソースからコンパイルしているため、推奨される解決策はUBTのC#ソースコードにパッチを適用することです。これにより、プライマリのコンパイルターゲットでUBAを実行しつつ、再帰呼び出し時には標準のParallelExecutorへのフォールバックを強制できます。
- UBTのソースディレクトリ
Engine/Source/Programs/UnrealBuildTool/Executors/に移動します。 ExecutorFactory.csファイルをVisual Studioまたはテキストエディタで開きます。Createメソッドを見つけます。このメソッドは、設定を評価し、適切なActionExecutorを返す役割を担っています。- 再帰的なUBT実行のチェックを含めるように、UBA選択の条件分岐ステートメントを変更します。
// Engine/Source/Programs/UnrealBuildTool/Executors/ExecutorFactory.cs
public static ActionExecutor Create(BuildConfiguration BuildConfiguration, List<TargetDescriptor> TargetDescriptors, ILogger Logger)
{
// Check if UBA is allowed, available, and NOT running recursively
- if (BuildConfiguration.bAllowUBAExecutor && UBAExecutor.IsAvailable())
+ if (BuildConfiguration.bAllowUBAExecutor && UBAExecutor.IsAvailable() && !UnrealBuildTool.IsRecursive)
{
return new UBAExecutor(BuildConfiguration, Logger);
}
// Fall back to IncrediBuild if configured
if (BuildConfiguration.bAllowXGE)
{
return new XGEExecutor(BuildConfiguration, Logger);
}
// Fall back to standard ParallelExecutor
return new ParallelExecutor(BuildConfiguration, Logger);
}
このパッチにより、ネストされたUBTインスタンスがUBA Executorを選択するのを防ぎます。代わりに、再帰ビルド(UnrealHeaderToolのビルドなど)はローカルのParallelExecutorを使用して安全に実行され、メインのエンジンコンパイルは引き続きUBAのパワーをフルに活用できます。
方法3:コマンドラインフラグ
カスタムコマンドラインスクリプトやCI/CDパイプラインを介してビルドプロセスを実行している場合は、呼び出しごとにUBAを無効にすることができます。これは、ローカルの開発者向けにはUBAを有効にしたままにし、リモートのビルドサーバー上では無効にしたい場合に特に便利です。
これを行うには、UBTのビルドコマンドに-NoUBAフラグを追加します。
# Example command to build the editor without UBA
Engine\Build\BatchFiles\Build.bat UnrealEditor Win64 Development -NoUBA
あるいは、-Executorフラグを使用して明示的に指定することで、UBTに標準のParallel Executorを使用させることができます。
Engine\Build\BatchFiles\Build.bat UnrealEditor Win64 Development -Executor=Parallel
ビルド環境のクリーンアップと再生成
上記の修正を適用した後、キャッシュされたアセンブリファイルや古い中間メタデータが原因でUBTのコンパイルが失敗することがあります。修正を確実にクリーンに適用するために、生成されたビルドツールのバイナリをクリアし、プロジェクトファイルを再生成する必要があります。
Windows環境の場合
Unreal Engine’のソースディレクトリを指すコマンドプロンプトまたはPowerShellインスタンスで、以下のコマンドを実行します。
:: Delete the cached UBT assembly and build binaries
rd /s /q Engine\Intermediate\Build\UnrealBuildTool
rd /s /q Engine\Binaries\DotNET\UnrealBuildTool
:: Regenerate the project files
GenerateProjectFiles.bat
LinuxおよびmacOS環境の場合
ターミナルで以下のコマンドを実行します。
# Remove cached build tool data
rm -rf Engine/Intermediate/Build/UnrealBuildTool
rm -rf Engine/Binaries/DotNET/UnrealBuildTool
# Regenerate project files
./GenerateProjectFiles.sh
環境がクリーンになったら、生成されたソリューションファイル(UE5.sln)をVisual Studioで開き、ターゲットをリビルドします。ビルドはエグゼキュータ例外をスローすることなく、再帰的コンパイルフェーズを無事に通過するはずです。
Unreal Engineソースビルドの実践的なベストプラクティス
ソースからカスタムエンジンのフォークをビルドすると、コンパイル、最適化、パッケージングにおいて様々な課題が生じます。以下のベストプラクティスを適用することで、安定し、高度に最適化された開発パイプラインを維持することができます。
1. メモリ不足を防ぐための並行性の最適化
現代のC++コンパイラは、コンパイルスレッドあたりに大容量のRAMを必要とします。巨大なエンジンモジュールをビルドする場合、UBTはシステムRAMがサポートできる数以上の並行タスクを生成することがあり、これがページファイルのスラッシングやコンパイラのクラッシュを招く原因となります。
BuildConfiguration.xmlファイルでParallelExecutor設定を構成することにより、最大プロセッサ数を制限できます。
<Configuration xmlns="https://www.unrealengine.com/BuildConfiguration">
<ParallelExecutor>
<MaxProcessorCount>16</MaxProcessorCount>
<ProcessorCountMultiplier>1.0</ProcessorCountMultiplier>
</ParallelExecutor>
</Configuration>
スレッドあたり約2 GBのRAMを目安にカウントを制限してください。例えば、32 GBのRAMを搭載したマシンの場合、MaxProcessorCountは16に制限する必要があります。
2. Dedicated Serverのアセットストリッピングのマスター
ゲームをクラウドにデプロイする際、不要なクライアントアセット(UIテクスチャ、オーディオ、メッシュなど)をDedicated Serverのバイナリにコンパイルすることは避けるべきです。これにより、サーバーの起動時間とメモリフットプリントが削減され、フリートを効率的にスケーリングするために不可欠となります。
これらのアセットを除外するようにビルドスクリプトを設定する方法については、Unreal Engine Dedicated Server Asset Strippingに関する詳細なガイドを参照してください。
3. Blueprintとパッケージの整合性を早期に検証する
エンジンビルドが成功したからといって、プロジェクトがエラーなしでパッケージ化されるとは限りません。古いBlueprintやシリアル化エラーは、最終的なパッケージングフェーズで頻繁にクラッシュを引き起こします。
これらの問題がリリースパイプラインをブロックするのを防ぐために、Resolving the Unreal Package HasValidBlueprint Ensure Crashのガイドを読み、自動検証チェックをセットアップしてください。
4. UBA VFSキャッシュを正しく設定する
C#パッチを使用してUBAを有効にしたままにする場合は、コンパイル済みのオブジェクトファイルをローカルに保存するように仮想ファイルシステムキャッシュを設定します。これにより、ブランチを切り替える際に変更されていないソースファイルを再コンパイルするのを避けることができます。
キャッシュを有効にするには、XMLファイルにUnrealBuildAccelerator設定ブロックを追加します。
<Configuration xmlns="https://www.unrealengine.com/BuildConfiguration">
<UnrealBuildAccelerator>
<WriteCache>true</WriteCache>
<Cache>127.0.0.1</Cache>
</UnrealBuildAccelerator>
</Configuration>
ファイアウォールがUBAのローカルネットワーク通信ポートをブロックしていないことを確認してください。これらのポートはキャッシュ同期ループの管理に使用されます。
Backendアーキテクチャの強化
unreal engine uba executor ubt errorのようなビルド問題の解決は、健全な開発ワークフローを維持するために極めて重要です。しかし、ローカルのコンパイル環境を整えることは、現代のマルチプレイヤーゲームを構築するための第一歩にすぎません。
カスタムエンジンがコンパイルされ、Dedicated Serverの準備が整ったら、Backendインフラストラクチャの複雑な課題に取り組む必要があります。独自のサーバーオーケストレーション、Matchmakingアルゴリズム、永続化データベースを一から作成するには、数週間もの開発時間が必要です。
Load Balancingの設定、データベースのシャージング、SSL証明書の管理などには、簡単に4〜6週間の専任作業が必要になります。horizOnを使用すれば、これらのBackendサービスは事前設定済みで、すぐにスケーリングできます。
インフラコードを作成する代わりに、いくつかのシンプルなAPI呼び出しでプレイヤーデータ、リアルタイムのロビー、サーバーのスケーリングを統合できます。これにより、メンテナンスのオーバーヘッドなしでDedicated Serverのビルドをデプロイし、プレイヤーの状態を管理できます。horizOnがクラウドインフラストラクチャを処理する間、開発チームはゲームプレイの仕組みやエンジンの機能に集中できます。
次のステップ
このビルドエラーを解決するには、迅速なXMLの上書きを選択するか、ExecutorFactory.csでC#ソースパッチを適用してください。ビルドパイプラインがスムーズに実行されたら、デプロイワークフローを最適化する方法を探しましょう。カスタムサーバーをホストするオーバーヘッドなしにマルチプレイヤーゲームをスケーリングしたい場合は、horizOnを無料でお試しいただくか、API documentationをご覧になり、詳細を確認してください。