Zpět na domů

Native AOT v .NET: zkušenost s implementací v CoreBus

Článek popisuje praktickou zkušenost s implementací Native AOT do krosplatformové .NET aplikace CoreBus. Jsou zváženy klíčové problémy: kompilovatelné vazby v Avalonia, serializace bez reflexe, specifika krosplatformového sestavování, trimování a falešné poplachy antivirů.

CoreBus a Native AOT: reálné potíže a řešení
Advertisement 728x90

# CoreBus a Native AOT: praktické zkušenosti s kompilací multiplatformního terminálu

Kompilace aplikací .NET s použitím Native AOT slibuje zrychlení spuštění a zmenšení velikosti distribuce, ale v praxi je spojena s řadou technických omezení. V článku se rozebírá reálný případ integrace Native AOT do CoreBus — multiplatformního terminálu pro práci s COM porty a protokoly Modbus.

Proč Native AOT?

Hlavní důvody přechodu — pomalé studené spuštění na slabých PC a velký objem instalačního balíčku. Po migraci z WPF na Avalonia UI se velikost aplikace zmenšila o ~60 MB, avšak cíl kolem 10 MB zůstal nedosažitelný. Native AOT se zdál logickým dalším krokem, zejména pro aplikaci zaměřenou na průmyslové zařízení a vestavěné systémy, kde jsou zdroje často omezené.

Nicméně již v fázi sestavení se ukázalo, že podpora Native AOT vyžaduje přepracování architektury vazeb, serializace a strategie publikování.

Google AdInline article slot

Problém 1: kompilované vazby v Avalonia

Avalonia ve výchozím nastavení používá dynamické vazby prostřednictvím reflexe, což je nekompatibilní s Native AOT. Pro řešení je nutné zapnout předem zkompilované vazby:

<AvaloniaUseCompiledBindingsByDefault>true</AvaloniaUseCompiledBindingsByDefault>

To vyžaduje explicitní uvedení typu dat v každém XAML souboru prostřednictvím atributu x:DataType na kořenovém prvku (Window, UserControl) a uvnitř DataTemplate. Chybějící tento atribut vede buď k chybě kompilace (Dynamic code generation is not supported on this platform), nebo k pád aplikace hned po spuštění.

V projektu CoreBus bylo nutné upravit veškerou XAML rozložení, což zabralo značný čas, ale umožnilo vyhnout se runtime výjimkám.

Google AdInline article slot

Problém 2: serializace bez reflexe

Nastavení a presetů CoreBus se ukládají do JSON souborů s použitím System.Text.Json. Standardní metody serializace jsou označeny atributy RequiresUnreferencedCode a RequiresDynamicCode, což vyvolává varování IL2026 a IL3050 při sestavování s Native AOT.

Řešení — použití source-generated JSON serializátorů prostřednictvím JsonSerializerContext. Příklad správné implementace:

var options = new JsonSerializerOptions
{
    WriteIndented = true,
    Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
    TypeInfoResolver = SerializerContext.Default
};

using var stream = new FileStream(correctFilePath, FileMode.Open);
var jsonTypeInfo = options.TypeInfoResolver.GetTypeInfo(typeof(T), options);

if (jsonTypeInfo == null)
{
    throw new Exception($"Not succeeded nayti type {typeof(T)} in obyavlenii konteksta serializatsii.");
}

JsonSerializer.Serialize(stream, data, jsonTypeInfo);

Pro deserializaci se používá analogický přístup:

Google AdInline article slot
var data = (T?)JsonSerializer.Deserialize(stream, typeof(T), SerializerContext.Default);

To úplně vylučuje reflexi a zaručuje kompatibilitu s trimmingem a AOT.

Problém 3: multiplatformní sestavení

Native AOT vyžaduje nativní sestavení pro cílovou OS a architekturu. Pritom verze jádra Linux a glibc kriticky ovlivňují kompatibilitu:

  • Sestavení na Ubuntu 24.10 (jádro 6.11) se nespouštělo na Astra Linux CE (jádro 5.15).
  • Sestavení na Ubuntu 18.04 (glibc 2.27) nefungovalo na Astra Linux CE (glibc 2.24) kvůli chybějící zpětné kompatibilitě knihovny C.

Finální strategie:

  • Windows: sestavení na Windows 11, testování na Windows 7/10 — úspěšná kompatibilita.
  • Linux: sestavení přímo na Astra Linux CE s jádrem 5.4 a glibc 2.24.

To zajišťuje maximální přenositelnost, ale komplikuje CI/CD proces.

Problém 4: trimming a závislé sestavení

Trimming (odstranění nepoužívaného kódu) přináší hlavní úsporu pouze v hlavním spustitelném projektu. Pomocné knihovny šetří dohromady méně než 300 KB.

Nicméně agresivní trimming může odstranit nezbytné zdroje Avalonia, zejména styly. Doporučuje se explicitně vyloučit témata z ořezávání:

<ItemGroup>
    <TrimmerRootAssembly Include="Avalonia.Themes.Fluent" />
</ItemGroup>

Ačkoli v Avalonia 11.3.x to nemusí být nutné, lepší je nastavení zachovat jako pojistku.

Problém 5: falešné poplachy antivirů

Aplikace sestavené s Native AOT + trimming jsou často rozpoznány jako škodlivé. Windows Defender označoval instalátor jako Trojan:Win32/Bearfoos.B!ml, a přenosnou verzi jako Trojan:Script/Wacatac.B!ml.

Jedná se o známý problém spojený se změnou struktury binárníku a chybějícím digitálním podpisem. Řešení — projití ověření v Microsoft SmartScreen a přidání digitálního podpisu.

Co je důležité

  • Native AOT vyžaduje úplné odmítnutí reflexe a dynamické generace kódu.
  • Kompilace musí probíhat na cílové platformě s ohledem na verze jádra a systémových knihoven.
  • Source-generated serializace je povinná pro práci s JSON.
  • Trimming může poškodit UI zdroje — vylučujte klíčové sestavení ručně.
  • Antiviry často falešně poplachují na AOT binárníky bez podpisu.

— Editorial Team

Advertisement 728x90

Číst dál