UE 5.8 Source Build'lerinde Unreal Engine UBA Executor UBT Hatasını Giderme
Özet olarak
Bu rehber, Unreal Engine 5.8 source build'lerinde karşılaşılan ve rekürsif UBT çağrılarında tetiklenen UBA executor çökme hatasının nedenlerini ve çözümlerini açıklamaktadır. Sorunun çözümü için BuildConfiguration.xml üzerinden UBA'nın devre dışı bırakılması yöntemi veya motorun C# kaynak kodundaki ExecutorFactory.cs dosyasına uygulanabilecek önerilen kod yaması adım adım sunulmaktadır. Ayrıca build ortamının temizlenmesi, concurrency optimizasyonu ve oyun projenizin backend altyapısını horizOn ile ölçeklendirme konularında pratik geliştirici ipuçları paylaşılmaktadır.
Özellikle kaynak koddan (source) Unreal Engine 5.8.0 derlerken Visual Studio'nun anlaşılmaz bir exception (özel durum) ile durması kadar bir stüdyonun hızını kesen çok az şey vardır. Build, doğrudan UBAExecutor.cs dosyasını işaret eden bir unhandled exception (yakalanamayan hata) ile başarısız olur. unreal engine uba executor ubt error olarak bilinen bu özel engelleyici, derleme işlemini tamamen durdurur. Build graph'ın UnrealHeaderTool gibi kritik yardımcı programların üretimini tamamlamasını engeller. Bu rehberde, Unreal Build Accelerator'ın (UBA) neden iç içe geçmiş (nested) çağrılarda sorun yaşadığını, varsayılan yapılandırmanın nasıl başarısız olduğunu ve çalışan bir build pipeline'ını geri yüklemek için motor kaynak kodunuzu nasıl yamayacağınızı (patch) ele alacağız.
Build System Mimarisini Anlamak
Bu hatanın neden oluştuğunu anlamak için, Unreal Build Tool'un (UBT) derleme işlemini nasıl yönettiğini incelememiz gerekir. Unreal Engine kod tabanları devasa büyüklüktedir ve genellikle on binlerce kaynak dosya içerir. Bunları verimli bir şekilde derlemek için UBT, dependency graph'lar (bağımlılık grafikleri) oluşturan ve derleme eylemlerini (compile actions) dağıtan bir meta-build sistemi olarak görev yapar.
Unreal Build Accelerator Nedir?
Epic Games, eski dağıtım sistemlerinin yerine varsayılan derleme yürütücüsü (compilation executor) olarak Unreal Build Accelerator'ı (UBA) tanıttı. UBA, dosya I/O işlemlerini kesmek için hafif bir sanallaştırılmış dosya sistemi (VFS) kullanarak derlemeyi hızlandırmak üzere tasarlanmıştır. Derleyici görevlerini birden fazla yerel çekirdeğe yönlendirir veya bunları Horde build node'ları arasında dağıtır.
Standart bir 64 çekirdekli build makinesinde UBA, temiz motor derleme (clean engine compilation) sürelerini yaklaşık 90 dakikadan 25 dakikanın altına indirebilir. Ancak UBA, I/O işlemlerini yakalamak için merkezi bir yerel ajana (local agent) güvendiğinden, derleyici süreçlerinin (compiler processes) nasıl başlatıldığı üzerinde sıkı bir kontrol gerektirir.
Rekürsif UBT Çağrılarının Çalışma Mekanizması
Derleme sırasında UBT, ana motor binary dosyaları derlenmeden önce oluşturulması gereken hedeflerle (targets) sık sık karşılaşır. Örneğin, UnrealEditor çalıştırılabilir dosyasını (executable) derlemeden önce, header dosyalarını parse etmek ve yansıma (reflection) meta verilerini oluşturmak için UBT'nin UnrealHeaderTool (UHT) aracını derlemesi gerekir.
Bunu başarmak için birincil UBT süreci (primary UBT process), ön koşul hedefi derlemek üzere iç içe geçmiş, ikincil bir UBT süreci başlatır. Bu iç içe çağırma işlemine rekürsif UBT çağrısı denir. Bir rekürsif UBT çağrısı aktif olduğunda UBT, dahili bir bayrak (internal flag) ayarlar (UnrealBuildTool.IsRecursive = true) ve süreci iç içe geçmiş olarak işaretlemek için ortam değişkenlerini (environment variables) yayar.
UBA Yürütücüsünün (Executor) Rekürsif Çağrılarda Çökme Nedeni
Bu çökme, UBA executor'ın iç içe geçmiş derleme döngülerini (nested compilation loops) destekleyecek şekilde tasarlanmamasından kaynaklanır. Visual Studio'da bu hata meydana geldiğinde UBT tarafından üretilen tipik call stack'e göz atalım:
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 Dosyasındaki Güvenlik Kontrolü
UBAExecutor.Init metodu içinde (UBAExecutor.cs dosyasının yaklaşık 315. satırında), motor açıkça bir rekürsiyon güvenlik kontrolü (recursion safety check) uygular:
// 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...
}
Bu güvenlik kontrolünün bulunmasının kritik bir nedeni vardır. Yerel UBA ajanı (local UBA agent), sanallaştırılmış derleyici yardımcı süreçleriyle (virtualized compiler helper processes) iletişim kurmak için belirli TCP portlarına bağlanır.
Eğer rekürsif bir UBT çağrısı, UBA executor'ın ikinci bir örneğini (instance) başlatmaya çalışırsa, her iki örnek de aynı network socket'lerine bağlanmaya çalışacak ve sanallaştırılmış dosya sistemi kancaları (virtualized file system hooks) üzerinde çakışacaktır. Bu durum soket atama (socket allocation) hatalarına, dosya sistemi bozulmalarına veya süresiz derleme kilitlenmelerine (build deadlocks) yol açacaktır. Bu exception koruyucu bir bariyer görevi görür.
Asıl Sebep: Executor Seçim Hatası
Unreal Engine 5.8.0'ın kaynak kod derlemelerindeki (source builds) asıl hata bu güvenlik kontrolü değildir. Aksine, executor factory mantığının rekürsif çağrıları doğru şekilde yönetememesidir.
UBT hangi executor'ın kullanılacağını belirlerken ExecutorFactory.cs sınıfını sorgular. Fabrika (factory), ana makinede UBA'nın etkinleştirilip etkinleştirilmediğini ve kullanılabilir olup olmadığını kontrol eder.
Ancak, mevcut UBT sürecinin rekürsif bir yürütme (recursive execution) olup olmadığını doğrulamaz. Sonuç olarak, UnrealHeaderTool aracını derlemek için ikincil UBT süreci başlatıldığında, fabrika iç içe geçmiş build için UBAExecutor atamaya çalışır ve bu da Init metodunda çökmeyi tetikler.
XML Yapılandırma Tuzağı
Birçok geliştirici, global BuildConfiguration.xml dosyasını değiştirerek bu sorunu aşmaya çalışır. Eski forum gönderilerindeki standart tavsiye, aşağıdaki etiketi devre dışı bırakarak UBA'yı kapatmaktır:
<?xml version="1.0" encoding="utf-8" ?>
<Configuration xmlns="https://www.unrealengine.com/BuildConfiguration">
<BuildConfiguration>
<bAllowUBA>false</bAllowUBA>
</BuildConfiguration>
</Configuration>
bAllowUBA Değeri Neden UE 5.8'de Yoksayılıyor?
Yukarıdaki XML yapılandırmasını bir Unreal Engine 5.8.0 source build'ine uygularsanız, derleyici yine de UBA'yı başlatmaya çalışacak ve exception fırlatacaktır. Bunun nedeni, motorun build konfigürasyon sisteminin yeniden yapılandırılmış (refactored) olmasıdır.
Eski bAllowUBA bayrağı (flag) kullanımdan kaldırılmıştır (deprecated) ve artık executor seçim mantığıyla eşleştirilmemiştir. Bunun yerine, UBA'nın davranışı iki farklı özellik (property) tarafından kontrol edilir: bAllowUBAExecutor ve bAllowUBALocalExecutor.
UBT, XML dosyanızda bAllowUBAExecutor özelliğini bulamadığı için varsayılan olarak true değerini kabul eder. Bu durum, UBA'yı kapatma girişiminizi sessizce geçersiz kılar.
UBA Yapılandırması için Doğru XML Yapısı
Yapılandırma dosyaları aracılığıyla UBA'yı başarıyla devre dışı bırakmak için güncellenmiş XML özellik adlarını kullanmalısınız. UBT'yi standart yerel executor'lara geri dönmeye (fallback) zorlamak için doğru yapı aşağıda verilmiştir:
<?xml version="1.0" encoding="utf-8" ?>
<Configuration xmlns="https://www.unrealengine.com/BuildConfiguration">
<BuildConfiguration>
<bAllowUBAExecutor>false</bAllowUBAExecutor>
<bAllowUBALocalExecutor>false</bAllowUBALocalExecutor>
</BuildConfiguration>
</Configuration>
Bu yapılandırma UBA'yı başarıyla devre dışı bırakır (bypass). Ancak UBA'yı tamamen kapatmak, birincil build işlemleriniz için sunduğu önemli derleme hızı avantajlarını kaybedeceğiniz anlamına gelir.
Hatayı Düzeltmek için Adım Adım Kılavuz
Çalışma akışınıza (workflow) bağlı olarak bu sorunu, XML yapılandırmanızı değiştirerek global olarak çözebilir ya da rekürsif olmayan derlemeler için build acceleration (derleme hızlandırma) özelliğini korumak adına doğrudan UBT kaynak kodunu yamayabilirsiniz (patch).
Yöntem 1: BuildConfiguration.xml Üzerine Yazma (Override)
Motor kaynak kodunu değiştirmek istemiyorsanız, UBA'yı global olarak devre dışı bırakabilirsiniz. Bu, projenizi derlemeye başlamanın en hızlı yoludur; ancak donanımınıza bağlı olarak clean build derleme sürelerini yaklaşık %40 ila %60 oranında artıracaktır.
- Global
BuildConfiguration.xmldosyanızı bulun veya oluşturun. Windows'ta bu dosya genellikle%AppData%\Roaming\Unreal Engine\UnrealBuildTool\BuildConfiguration.xmldizininde bulunur. Linux'ta ise~/.config/Unreal Engine/UnrealBuildTool/BuildConfiguration.xmlkonumundadır. - XML dosyasını bir metin editöründe açın.
- İçeriği aşağıda gösterilen güncellenmiş XML şemasıyla değiştirin.
- Dosyayı kaydedin ve Visual Studio build işleminizi yeniden başlatın.
<?xml version="1.0" encoding="utf-8" ?>
<Configuration xmlns="https://www.unrealengine.com/BuildConfiguration">
<BuildConfiguration>
<bAllowUBAExecutor>false</bAllowUBAExecutor>
<bAllowUBALocalExecutor>false</bAllowUBALocalExecutor>
</BuildConfiguration>
</Configuration>
Yöntem 2: UBT Kaynak Kodunu Yamama (Önerilen)
Unreal Engine 5.8 sürümünü kaynak koddan (source) derlediğiniz için önerilen çözüm, UBT C# kaynak kodunu yamamaktır (patch). Bu, UBA'nın birincil derleme hedefinizde çalışmasına izin verirken, rekürsif çağrılar sırasında standart ParallelExecutor aracına geri dönülmesini (fallback) zorunlu kılar.
- UBT kaynak dizinine gidin:
Engine/Source/Programs/UnrealBuildTool/Executors/. ExecutorFactory.csdosyasını Visual Studio veya bir metin editöründe açın.Createmetodunu bulun. Bu metot, yapılandırmanızı değerlendirmekten ve uygunActionExecutornesnesini döndürmekten sorumludur.- UBA seçim koşullu ifadesini (conditional statement), rekürsif UBT çalıştırmalarına yönelik bir kontrol içerecek şekilde değiştirin.
// 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);
}
Bu yama (patch), iç içe geçmiş UBT örneğinin (instance) UBA executor'ı seçmesini engeller. Bunun yerine, rekürsif derleme (UnrealHeaderTool build işlemi gibi) yerel ParallelExecutor kullanılarak güvenli bir şekilde çalışırken, birincil motor derlemeniz UBA'nın tüm gücünden yararlanmaya devam eder.
Yöntem 3: Komut Satırı Bayrakları (Command Line Flags)
Build sürecinizi özel komut satırı betikleri (scripts) veya CI/CD pipeline'ları üzerinden yürütüyorsanız, her çağırma bazında UBA'yı devre dışı bırakabilirsiniz. Bu durum, yerel geliştiriciler için UBA'yı etkin tutmak ancak uzak build sunucularında devre dışı bırakmak istediğinizde oldukça kullanışlıdır.
Bunu yapmak için UBT build komutunuzun sonuna -NoUBA bayrağını ekleyin:
# Example command to build the editor without UBA
Engine\Build\BatchFiles\Build.bat UnrealEditor Win64 Development -NoUBA
Alternatif olarak, UBT'yi -Executor bayrağı ile açıkça belirterek standart parallel executor kullanmaya zorlayabilirsiniz:
Engine\Build\BatchFiles\Build.bat UnrealEditor Win64 Development -Executor=Parallel
Build Ortamını Temizleme ve Yeniden Oluşturma
Yukarıdaki düzeltmelerden herhangi birini uyguladıktan sonra UBT, önbelleğe alınmış (cached) assembly dosyaları veya eski intermediate (ara seviye) meta verileri nedeniyle derlenemeyebilir. Düzeltmenin temiz bir şekilde yürürlüğe girmesini sağlamak için, oluşturulan build tool binary'lerini temizlemeli ve proje dosyalarını yeniden üretmelisiniz.
Windows Ortamları İçin
Unreal Engine kaynak dizininizi gösteren bir komut isteminde (command prompt) veya PowerShell oturumunda aşağıdaki komutları çalıştırın:
:: 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 ve macOS Ortamları İçin
Terminalinizde şu komutları çalıştırın:
# Remove cached build tool data
rm -rf Engine/Intermediate/Build/UnrealBuildTool
rm -rf Engine/Binaries/DotNET/UnrealBuildTool
# Regenerate project files
./GenerateProjectFiles.sh
Ortam temizlendikten sonra, oluşturulan solution dosyanızı (UE5.sln) Visual Studio'da açın ve hedefi yeniden derleyin (rebuild). Build işlemi, artık executor exception hatası almadan rekürsif derleme aşamasını başarıyla geçecektir.
Unreal Engine Source Build'leri İçin Uygulanabilir En İyi Pratikler
Kaynak koddan özel bir motor çatalı (engine fork) derlemek; derleme, optimizasyon ve paketleme süreçlerinde çeşitli zorlukları beraberinde getirir. Aşağıdaki en iyi pratikleri uygulamak, kararlı ve yüksek oranda optimize edilmiş bir geliştirme pipeline'ı sürdürmenize yardımcı olacaktır.
1. Bellek Yetersizliğini Önlemek İçin Eşzamanlılığı (Concurrency) Optimize Edin
Modern C++ derleyicileri, derleme iş parçacığı (compilation thread) başına önemli miktarda RAM gerektirir. Büyük motor modülleri oluştururken UBT, sistem RAM'inizin destekleyebileceğinden daha fazla paralel görev başlatabilir ve bu da disk belleği dosyası (page-file) çakışmalarına veya derleyici çökmelerine neden olabilir.
BuildConfiguration.xml dosyanızdaki ParallelExecutor ayarlarını yapılandırarak maksimum işlemci sayısını sınırlayabilirsiniz:
<Configuration xmlns="https://www.unrealengine.com/BuildConfiguration">
<ParallelExecutor>
<MaxProcessorCount>16</MaxProcessorCount>
<ProcessorCountMultiplier>1.0</ProcessorCountMultiplier>
</ParallelExecutor>
</Configuration>
İş parçacığı başına miktarı yaklaşık 2 GB RAM olacak şekilde sınırlayın. Örneğin, 32 GB RAM'e sahip bir makinede MaxProcessorCount değeri 16 ile sınırlandırılmalıdır.
2. Dedicated Server Asset Stripping Konusunda Uzmanlaşın
Oyununuzu buluta dağıtırken (deploy), dedicated server binary dosyanıza gereksiz istemci (client) varlıklarını (UI kaplamaları, sesler ve mesh'ler gibi) dahil etmekten kaçınmalısınız. Bu, sunucu başlangıç sürelerini ve bellek kullanımını (memory footprint) azaltır ki bu da sunucu filolarını verimli bir şekilde ölçeklendirmek için kritik öneme sahiptir.
Build betiklerinizi bu varlıkları hariç tutacak şekilde nasıl yapılandıracağınızı öğrenmek için, Unreal Engine Dedicated Server Asset Stripping hakkındaki ayrıntılı rehberimizi takip edin.
3. Blueprint ve Paket Bütünlüğünü Erken Doğrulayın
Motorun başarıyla derlenmesi, projenizin hatasız bir şekilde paketleneceğini garanti etmez. Eski blueprint'ler veya serileştirme (serialization) hataları, son paketleme aşamasında (packaging phase) sıklıkla çökmelere neden olur.
Bu sorunların sürüm pipeline'ınızı (release pipeline) engellemesini önlemek için, otomatik doğrulama kontrolleri kurmayı anlatan Resolving the Unreal Package HasValidBlueprint Ensure Crash kılavuzumuzu okuyun.
4. UBA VFS Caching Özelliğini Doğru Yapılandırın
C# yaması (patch) ile UBA'yı etkin tutmaya karar verirseniz, derlenmiş object dosyalarını yerel olarak saklamak için sanal dosya sistemi önbelleğini (virtual file system cache) yapılandırın. Bu, dal (branch) değiştirirken değişmemiş kaynak dosyalarını yeniden derlemekten kaçınmanızı sağlar.
Önbelleğe almayı (caching) etkinleştirmek için XML dosyanıza UnrealBuildAccelerator yapılandırma bloğunu ekleyin:
<Configuration xmlns="https://www.unrealengine.com/BuildConfiguration">
<UnrealBuildAccelerator>
<WriteCache>true</WriteCache>
<Cache>127.0.0.1</Cache>
</UnrealBuildAccelerator>
</Configuration>
Güvenlik duvarınızın (firewall), önbellek senkronizasyon döngüsünü yönetmek için kullanılan UBA'nın yerel ağ iletişim portlarını engellemediğinden emin olun.
Backend Mimarinizi Bir Üst Seviyeye Taşıyın
unreal engine uba executor ubt error gibi derleme sorunlarını çözmek, sağlıklı bir geliştirme iş akışını (development workflow) sürdürmek için kritik öneme sahiptir. Ancak, yerel bir derleme ortamı kurmak, modern bir multiplayer oyun geliştirmenin yalnızca ilk adımıdır.
Özel motorunuz derlendikten ve dedicated server'larınız hazır hale geldikten sonra, backend altyapısının karmaşık zorluklarıyla ilgilenmeniz gerekir. Sıfırdan kendi sunucu yönetim sisteminizi (server orchestration), matchmaking algoritmalarınızı ve veri tabanlarınızı yazmak haftalarca geliştirme süresi gerektirir.
Load balancer'lar, database sharding (veri tabanı parçalama) ve SSL sertifikası yönetimi kurmak kolaylıkla 4 ila 6 haftalık yoğun bir çalışma alabilir. horizOn ile bu backend servisleri önceden yapılandırılmış ve ölçeklenmeye hazır olarak sunulur.
Altyapı kodları yazmak yerine; oyuncu verilerini, gerçek zamanlı lobileri (real-time lobbies) ve sunucu ölçeklendirmeyi birkaç basit API çağrısıyla entegre edebilirsiniz. Bu, dedicated server build'lerinizi dağıtmanıza ve sıfır bakım maliyeti (maintenance overhead) ile oyuncu durumunu yönetmenize olanak tanır. Ekibiniz oynanış mekaniklerine ve motor özelliklerine odaklanırken horizOn bulut altyapısını sizin yerinize yönetir.
Sonraki Adımlar
Bu build hatasını çözmek için hızlı XML geçersiz kılma (override) yöntemini seçin veya ExecutorFactory.cs dosyasındaki C# kaynak kod yamasını (patch) uygulayın. Derleme pipeline'ınız sorunsuz çalışmaya başladıktan sonra, dağıtım iş akışınızı (deployment workflow) optimize etmenin yollarını arayın. Özel sunucular barındırmanın getirdiği iş yükü olmadan multiplayer oyununuzu ölçeklendirmek istiyorsanız, horizOn platformunu ücretsiz deneyin veya daha fazla bilgi edinmek için API dokümantasyonumuza göz atın.