Open joined72 opened 1 year ago
Godot still uses reflection in many places and NativeAOT requires trimming. You didn't share your csproj but I'm assuming you didn't root the assemblies.
AOT isn't fully supported on Godot, so it requires special configuration. Can you show us your .csproj file
AOT isn't fully supported on Godot, so it requires special configuration. Can you show us your .csproj file
I just updated the bug description with much more info...
Godot still uses reflection in many places and NativeAOT requires trimming. You didn't share your csproj but I'm assuming you didn't root the assemblies.
I shared many data, bug just updated.
What do you mean with "root the assemblies" and how I can work to activate AOT?
Rooting the assemblies mean that you are telling the trimmer that those assemblies are used so they shouldn't be trimmed. Try this:
<Project Sdk="Godot.NET.Sdk/4.2.0-rc.2">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<EnableDynamicLoading>true</EnableDynamicLoading>
<!-- Use NativeAOT. -->
<PublishAOT>true</PublishAOT>
</PropertyGroup>
<ItemGroup>
<!-- Root the assemblies to avoid trimming. -->
<TrimmerRootAssembly Include="GodotSharp" />
<TrimmerRootAssembly Include="$(TargetName)" />
</ItemGroup>
</Project>
Also, it seems you're getting errors when linking the native binary:
/usr/bin/ld.bfd: cannot find crti.o: No such file or directory
/usr/bin/ld.bfd: cannot find -ldl: No such file or directory
/usr/bin/ld.bfd: cannot find -lz: No such file or directory
/usr/bin/ld.bfd: cannot find -lrt: No such file or directory
/usr/bin/ld.bfd: cannot find -lm: No such file or directory
So there may be something broken in your setup. Try using lld
as the linker (I think this should be the default in .NET 8.0 if it's installed, otherwise it falls back to bfd
).
Rooting the assemblies mean that you are telling the trimmer that those assemblies are used so they shouldn't be trimmed. Also, it seems you're getting errors when linking the native binary. So there may be something broken in your setup.
Thanks a lot for your REALLY GREAT support, finally I managed to Activate and Build AOT...
These are the steps I followed:
1)... to install missing dependencies I used the command...
sudo apt install gcc-multilib libz-dev clang llvm
2)... using the following .csproj
file...
<Project Sdk="Godot.NET.Sdk/4.2.0-rc.2">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<EnableDynamicLoading>true</EnableDynamicLoading>
<!-- Use NativeAOT. -->
<PublishAOT>true</PublishAOT>
</PropertyGroup>
<ItemGroup>
<!-- Root the assemblies to avoid trimming. -->
<TrimmerRootAssembly Include="GodotSharp" />
<TrimmerRootAssembly Include="$(TargetName)" />
</ItemGroup>
</Project>
3)... to obtain a single executable file with the smallest size I used the following Project/Export/Options
...
Binary Format
Embed PCK = true
Dotnet
Include Scripts Content = true
Include Debug Symbols = FALSE
Embed Build Outputs = true
4)... VERY IMPORTANT, before make any Project/Export
, delete the .godot/mono
folder (if a previous exporting was done with Project/Export/Options/Dotnet/Include Debug Symbols
active then the old Dotnet Debug Symbols will be exported as well).
At the end of all work, the file size difference is incredible...
File Size:
AOT Build: 79.189.056 bytes
JIT Build: 140.992.096 bytes
PS: from my tests, seems that Speed and Memory Usage are almost the same for JIT and AOT compilation, at least on .NET 8, is possible that converting the GodotSharp Binding Libraries
in a Trimmable
version (to can activate AOT Full) will improve this stuff too.
Since you managed to make it work, can this issue be closed now?
Since you managed to make it work, can this issue be closed now?
I'm still working on it just now and I'll send all updates here.
Working to analyze what parts of the GodotSharp dotnet lib isn't trimmable I received the following detailed log:
ILC : Trim analysis warning IL2026: Godot.DebuggingUtils.GetCurrentStackInfo(Void*): Using member 'System.Diagnostics.StackFrame.GetMethod()' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. Metadata for the method might be incomplete or removed. [/home/fabio/Desktop/AOT_Test/AOT_Test.csproj]
ILC : Trim analysis warning IL2026: Godot.DebuggingUtils.GetStackFrameMethodDecl(StackFrame,String&): Using member 'System.Diagnostics.StackFrame.GetMethod()' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. Metadata for the method might be incomplete or removed. [/home/fabio/Desktop/AOT_Test/AOT_Test.csproj]
ILC : Trim analysis warning IL2075: Godot.DelegateUtils.TrySerializeSingleDelegate(Delegate,Byte[]&): 'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicFields' in call to 'System.Type.GetFields(BindingFlags)'. The return value of method 'System.Object.GetType()' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. [/home/fabio/Desktop/AOT_Test/AOT_Test.csproj]
ILC : Trim analysis warning IL2072: Godot.DelegateUtils.TryDeserializeSingleDelegate(Byte[],Delegate&): 'type' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicParameterlessConstructor' in call to 'System.Activator.CreateInstance(Type)'. The return value of method 'Godot.DelegateUtils.DeserializeType(BinaryReader)' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. [/home/fabio/Desktop/AOT_Test/AOT_Test.csproj]
ILC : Trim analysis warning IL2075: Godot.DelegateUtils.TryDeserializeSingleDelegate(Byte[],Delegate&): 'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicFields' in call to 'System.Type.GetField(String,BindingFlags)'. The return value of method 'Godot.DelegateUtils.DeserializeType(BinaryReader)' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. [/home/fabio/Desktop/AOT_Test/AOT_Test.csproj]
ILC : Trim analysis warning IL2075: Godot.DelegateUtils.TryDeserializeMethodInfo(BinaryReader,MethodInfo&): 'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods', 'DynamicallyAccessedMemberTypes.NonPublicMethods' in call to 'System.Type.GetMethod(String,BindingFlags,Binder,Type[],ParameterModifier[])'. The return value of method 'Godot.DelegateUtils.DeserializeType(BinaryReader)' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. [/home/fabio/Desktop/AOT_Test/AOT_Test.csproj]
ILC : Trim analysis warning IL2055: Godot.DelegateUtils.DeserializeType(BinaryReader): Call to 'System.Type.MakeGenericType(Type[])' can not be statically analyzed. It's not possible to guarantee the availability of requirements of the generic type. [/home/fabio/Desktop/AOT_Test/AOT_Test.csproj]
ILC : AOT analysis warning IL3050: Godot.DelegateUtils.DeserializeType(BinaryReader): Using member 'System.Type.MakeGenericType(Type[])' which has 'RequiresDynamicCodeAttribute' can break functionality when AOT compiling. The native code for this instantiation might not be available at runtime. [/home/fabio/Desktop/AOT_Test/AOT_Test.csproj]
ILC : Trim analysis warning IL2026: Godot.ReflectionUtils.FindTypeInLoadedAssemblies(String,String): Using member 'System.Reflection.Assembly.GetType(String)' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. Types might be removed. [/home/fabio/Desktop/AOT_Test/AOT_Test.csproj]
ILC : Trim analysis warning IL2072: Godot.Bridge.ScriptManagerBridge.CreateManagedForGodotObjectBinding(godot_string_name*,IntPtr): 'type' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicConstructors', 'DynamicallyAccessedMemberTypes.NonPublicConstructors' in call to 'System.Runtime.Serialization.FormatterServices.GetUninitializedObject(Type)'. The return value of method 'Godot.Bridge.ScriptManagerBridge.TypeGetProxyClass(String)' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. [/home/fabio/Desktop/AOT_Test/AOT_Test.csproj]
ILC : Trim analysis warning IL2075: Godot.Bridge.ScriptManagerBridge.CreateManagedForGodotObjectBinding(godot_string_name*,IntPtr): 'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicConstructors', 'DynamicallyAccessedMemberTypes.NonPublicConstructors' in call to 'System.Type.GetConstructor(BindingFlags,Binder,Type[],ParameterModifier[])'. The return value of method 'Godot.Bridge.ScriptManagerBridge.TypeGetProxyClass(String)' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. [/home/fabio/Desktop/AOT_Test/AOT_Test.csproj]
ILC : Trim analysis warning IL2075: Godot.Bridge.ScriptManagerBridge.CreateManagedForGodotObjectScriptInstance(IntPtr,IntPtr,godot_variant**,Int32): 'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicConstructors', 'DynamicallyAccessedMemberTypes.NonPublicConstructors' in call to 'System.Type.GetConstructors(BindingFlags)'. The return value of method 'Godot.Bridge.ScriptManagerBridge.ScriptTypeBiMap.GetScriptType(IntPtr)' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. [/home/fabio/Desktop/AOT_Test/AOT_Test.csproj]
ILC : Trim analysis warning IL2072: Godot.Bridge.ScriptManagerBridge.CreateManagedForGodotObjectScriptInstance(IntPtr,IntPtr,godot_variant**,Int32): 'type' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicConstructors', 'DynamicallyAccessedMemberTypes.NonPublicConstructors' in call to 'System.Runtime.Serialization.FormatterServices.GetUninitializedObject(Type)'. The return value of method 'Godot.Bridge.ScriptManagerBridge.ScriptTypeBiMap.GetScriptType(IntPtr)' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. [/home/fabio/Desktop/AOT_Test/AOT_Test.csproj]
ILC : Trim analysis warning IL2075: Godot.Bridge.ScriptManagerBridge.GetScriptNativeName(IntPtr,godot_string_name*): 'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicFields', 'DynamicallyAccessedMemberTypes.NonPublicFields' in call to 'System.Type.GetField(String,BindingFlags)'. The return value of method 'Godot.GodotObject.InternalGetClassNativeBase(Type)' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. [/home/fabio/Desktop/AOT_Test/AOT_Test.csproj]
ILC : Trim analysis warning IL2026: Godot.Bridge.ScriptManagerBridge.LookupScriptsInAssembly(Assembly): Using member 'System.Reflection.Assembly.GetTypes()' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. Types might be removed. [/home/fabio/Desktop/AOT_Test/AOT_Test.csproj]
ILC : Trim analysis warning IL2075: Godot.Bridge.ScriptManagerBridge.UpdateScriptClassInfo(IntPtr,godot_string*,godot_bool*,godot_bool*,godot_bool*,godot_string*,godot_array*,godot_dictionary*,godot_dictionary*,godot_ref*): 'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods', 'DynamicallyAccessedMemberTypes.NonPublicMethods' in call to 'System.Type.GetMethods(BindingFlags)'. The return value of method 'Godot.Bridge.ScriptManagerBridge.ScriptTypeBiMap.GetScriptType(IntPtr)' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. [/home/fabio/Desktop/AOT_Test/AOT_Test.csproj]
ILC : Trim analysis warning IL2075: Godot.Bridge.ScriptManagerBridge.UpdateScriptClassInfo(IntPtr,godot_string*,godot_bool*,godot_bool*,godot_bool*,godot_string*,godot_array*,godot_dictionary*,godot_dictionary*,godot_ref*): 'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods', 'DynamicallyAccessedMemberTypes.NonPublicMethods' in call to 'System.Type.GetMethods(BindingFlags)'. The return value of method 'System.Type.BaseType.get' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. [/home/fabio/Desktop/AOT_Test/AOT_Test.csproj]
ILC : Trim analysis warning IL2070: Godot.Bridge.ScriptManagerBridge.GetSignalListForType(Type): 'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods', 'DynamicallyAccessedMemberTypes.NonPublicMethods' in call to 'System.Type.GetMethod(String,BindingFlags)'. The parameter 'type' of method 'Godot.Bridge.ScriptManagerBridge.GetSignalListForType(Type)' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. [/home/fabio/Desktop/AOT_Test/AOT_Test.csproj]
ILC : Trim analysis warning IL2070: Godot.Bridge.ScriptManagerBridge.GetMethodListForType(Type): 'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods', 'DynamicallyAccessedMemberTypes.NonPublicMethods' in call to 'System.Type.GetMethod(String,BindingFlags)'. The parameter 'type' of method 'Godot.Bridge.ScriptManagerBridge.GetMethodListForType(Type)' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. [/home/fabio/Desktop/AOT_Test/AOT_Test.csproj]
ILC : Trim analysis warning IL2070: Godot.Bridge.ScriptManagerBridge.GetPropertyInfoListForType(Type,IntPtr,delegate*<IntPtr,godot_string*,Void*,Int32,Void>): 'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods', 'DynamicallyAccessedMemberTypes.NonPublicMethods' in call to 'System.Type.GetMethod(String,BindingFlags)'. The parameter 'type' of method 'Godot.Bridge.ScriptManagerBridge.GetPropertyInfoListForType(Type,IntPtr,delegate*<IntPtr,godot_string*,Void*,Int32,Void>)' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. [/home/fabio/Desktop/AOT_Test/AOT_Test.csproj]
ILC : Trim analysis warning IL2075: Godot.Bridge.ScriptManagerBridge.CallStatic(IntPtr,godot_string_name*,godot_variant**,Int32,godot_variant_call_error*,godot_variant*): 'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods', 'DynamicallyAccessedMemberTypes.NonPublicMethods' in call to 'System.Type.GetMethod(String,BindingFlags)'. The return value of method 'Godot.Bridge.ScriptManagerBridge.ScriptTypeBiMap.GetScriptType(IntPtr)' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. [/home/fabio/Desktop/AOT_Test/AOT_Test.csproj]
ILC : Trim analysis warning IL2070: Godot.Bridge.ScriptManagerBridge.GetPropertyDefaultValuesForType(Type,IntPtr,delegate*<IntPtr,Void*,Int32,Void>): 'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods', 'DynamicallyAccessedMemberTypes.NonPublicMethods' in call to 'System.Type.GetMethod(String,BindingFlags)'. The parameter 'type' of method 'Godot.Bridge.ScriptManagerBridge.GetPropertyDefaultValuesForType(Type,IntPtr,delegate*<IntPtr,Void*,Int32,Void>)' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. [/home/fabio/Desktop/AOT_Test/AOT_Test.csproj]
ILC : Trim analysis warning IL2026: Godot.Bridge.ScriptManagerBridge.TypeGetProxyClass(String): Using member 'System.Reflection.Assembly.GetType(String)' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. Types might be removed. [/home/fabio/Desktop/AOT_Test/AOT_Test.csproj]
ILC : Trim analysis warning IL2026: Godot.Bridge.ScriptManagerBridge.TypeGetProxyClass(String): Using member 'System.Reflection.Assembly.GetType(String)' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. Types might be removed. [/home/fabio/Desktop/AOT_Test/AOT_Test.csproj]
ILC : Trim analysis warning IL2026: Godot.Bridge.ScriptManagerBridge.<TypeGetProxyClass>g__GetTypeByGodotClassAttr|12_0(Assembly,String): Using member 'System.Reflection.Assembly.GetTypes()' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. Types might be removed. [/home/fabio/Desktop/AOT_Test/AOT_Test.csproj]
ILC : Trim analysis warning IL2067: Godot.DelegateUtils.RuntimeTypeConversionHelper.<ConvertToObjectOfType>g__ConvertToSystemArrayOfGodotObject|3_0(godot_array&,Type): 'type' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicConstructors' in call to 'System.Activator.CreateInstance(Type,Object[])'. The parameter 'type' of method 'Godot.DelegateUtils.RuntimeTypeConversionHelper.<ConvertToObjectOfType>g__ConvertToSystemArrayOfGodotObject|3_0(godot_array&,Type)' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. [/home/fabio/Desktop/AOT_Test/AOT_Test.csproj]
ILC : Trim analysis warning IL2059: Godot.NativeInterop.VariantUtils.GenericConversion`1..cctor(): Unrecognized value passed to the parameter 'type' of method 'System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(RuntimeTypeHandle)'. It's not possible to guarantee the availability of the target static constructor. [/home/fabio/Desktop/AOT_Test/AOT_Test.csproj]
If I'll try to solve all this issues, can someone explain to me how I can rebuild the GodotSharp lib?
Oh, you intend to solve the trimming warnings? In that case I should mention that, as you can see in the log, most of them are caused by the ScriptManagerBridge
which is part of the C# script implementation that will be removed when moving to GDExtension.
So it may not be worth working on this, since it may end up being fixed in the move to GDExtension. Keep in mind the move to GDExtension is a long-term project and will likely take a while.
Rooting the assemblies should work fine as a workaround even with the warnings. The only issue would be that the resulting binaries will be bigger since the trimmer won't be able to trim the rooted assemblies, but this may be acceptable for some users.
If you still want to work on this, I encourage you to join us in Rocket Chat so you can discuss with other .NET/C# contributors in the #dotnet channel.
Oh, you intend to solve the trimming warnings? In that case I should mention that, as you can see in the log, most of them are caused by the
ScriptManagerBridge
which is part of the C# script implementation that will be removed when moving to GDExtension.So it may not be worth working on this, since it may end up being fixed in the move to GDExtension. Keep in mind the move to GDExtension is a long-term project and will likely take a while.
While it required so many time?
Rooting the assemblies should work fine as a workaround even with the warnings. The only issue would be that the resulting binaries will be bigger since the trimmer won't be able to trim the rooted assemblies, but this may be acceptable for some users.
Yes I understand, but I'm continuing working about to obtain better results.
If you still want to work on this, I encourage you to join us in Rocket Chat so you can discuss with other .NET/C# contributors in the #dotnet channel.
Just done, thank you! :)
Godot version
4.2rc2
System information
Ubuntu 22.04
Issue description
Activating the Native AOT including
<PublishAot>true</PublishAot>
and changing the<TargetFramework>net8.0</TargetFramework>
to the .csproj file return failed build.This is the .csproj file:
Removing the
<PublishAot>true</PublishAot>
line returns to works fine.This is the MSBuild output:
I tested on .NET 8 - Linux Mint 22.1 (Ubuntu 22.04)
Steps to reproduce
Create an empty Godot 4 C# project, add an empty C# script and add
<PublishAot>true</PublishAot>
and change the<TargetFramework>net8.0</TargetFramework>
to the .csproj file, then try to export to desktop.Minimal reproduction project
AOT_Test.zip