Skip to content

Latest commit

 

History

History
121 lines (102 loc) · 8.36 KB

README.md

File metadata and controls

121 lines (102 loc) · 8.36 KB

MonoGameNativeAOTTest

This project is a sample project using NativeAOT with MonoGame on Windows-x64. I will make a note here because I had a hard time outputting the actual Native executable file. However, with the execution speed of modern PCs, the normal JIT should be sufficient.

Executable files developed in C# can be output with fairly high accuracy through reverse engineering, so there is a concern about theft from reverse engineering. However, unless the software becomes a big hit, the possibility is low. Rather, it is embarrassing to have your own immature program seen. That's why I embarked on a journey to find out how to use NativeAOT with MonoGame.

I found some web pages showing usage examples, but with the current MonoGame 3.8.1.303, I had trouble outputting the Native file when using "dotnet publish".

I was able to solve the problem by finding this web page. MonoGame/MonoGame#8005

The key to the solution was:

  • Building with .NET 7.0
  • Using the DesktopGL template

Since MonoGame is compatible with .NET 6.0, I had assumed that I should not build with version 7.0.

To add/modify options in the .csproj file, follow the example below.

<PropertyGroup>
  <TargetFramework>net7.0</TargetFramework>
  <PublishAot>true</PublishAot>
</PropertyGroup>

<ItemGroup>
  <PackageReference Include="MonoGame.Framework.DesktopGL" Version="3.8.1.303" />
  <PackageReference Include="MonoGame.Content.Builder.Task" Version="3.8.1.303" />
</ItemGroup>
<ItemGroup>
  <PackageReference Include="Microsoft.DotNet.ILCompiler" Version="8.0.0-*" />
  <KnownILCompilerPack Update="Microsoft.DotNet.ILCompiler" TargetFramework="net7.0" ILCompilerPackNamePattern="runtime.win-x64.Microsoft.DotNet.ILCompiler" ILCompilerPackVersion="8.0.0-preview.2.23128.3" ILCompilerRuntimeIdentifiers="win-x64" />
</ItemGroup>
<ItemGroup>
  <RdXmlFile Include="rd.xml" />
</ItemGroup>

I needed to specify the version of the Microsoft.DotNet.ILCompiler package as Version="8.0.0-*". Since .NET 8.0 is still in preview, I had assumed that it would be better not to use it.

In addition, the contents of nuget.config are as follows:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
 <packageSources>
    <!--To inherit the global NuGet package sources remove the <clear/> line below -->
    <clear />
    <add key="dotnet-public" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public/nuget/v3/index.json" />
    <add key="dotnet-experimental" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-experimental/nuget/v3/index.json" />
    <add key="nuget" value="https://api.nuget.org/v3/index.json" />
 </packageSources>
</configuration>

In addition, prepare a file called rd.xml for reflection support. It seems that you need to append it appropriately depending on the content of your own program, but I haven't fully understood the details yet.

<Directives xmlns="http://schemas.microsoft.com/netfx/2013/01/metadata">
    <Application>
        <Assembly Name="mscorlib" />
        <Assembly Name="MonoGame.Framework">
            <Type Name="Microsoft.Xna.Framework.Content.ListReader`1[[System.Char,mscorlib]]" Dynamic="Required All" />
            <Type Name="Microsoft.Xna.Framework.Content.ByteReader" Dynamic="Required All"/>
            <Type Name="Microsoft.Xna.Framework.Content.SByteReader" Dynamic="Required All"/>
            <Type Name="Microsoft.Xna.Framework.Content.DateTimeReader" Dynamic="Required All"/>
            <Type Name="Microsoft.Xna.Framework.Content.DecimalReader" Dynamic="Required All"/>
            <Type Name="Microsoft.Xna.Framework.Content.BoundingSphereReader" Dynamic="Required All"/>
            <Type Name="Microsoft.Xna.Framework.Content.BoundingFrustumReader" Dynamic="Required All"/>
            <Type Name="Microsoft.Xna.Framework.Content.RayReader" Dynamic="Required All"/>
            <Type Name="Microsoft.Xna.Framework.Content.ListReader`1[[System.Char,System.Private.CoreLib]]" Dynamic="Required All"/>
            <Type Name="Microsoft.Xna.Framework.Content.ListReader`1[[Microsoft.Xna.Framework.Rectangle,MonoGame.Framework]]" Dynamic="Required All"/>
            <Type Name="Microsoft.Xna.Framework.Content.ArrayReader`1[[Microsoft.Xna.Framework.Rectangle,MonoGame.Framework]]" Dynamic="Required All"/>
            <Type Name="Microsoft.Xna.Framework.Content.ListReader`1[[Microsoft.Xna.Framework.Vector3,MonoGame.Framework]]" Dynamic="Required All"/>
            <Type Name="Microsoft.Xna.Framework.Content.ListReader`1[[Microsoft.Xna.Framework.Content.StringReader,MonoGame.Framework]]" Dynamic="Required All"/>
            <Type Name="Microsoft.Xna.Framework.Content.ListReader`1[[System.Int32,System.Private.CoreLib]]" Dynamic="Required All"/>
            <Type Name="Microsoft.Xna.Framework.Content.SpriteFontReader" Dynamic="Required All"/>
            <Type Name="Microsoft.Xna.Framework.Content.Texture2DReader" Dynamic="Required All"/>
            <Type Name="Microsoft.Xna.Framework.Content.CharReader" Dynamic="Required All"/>
            <Type Name="Microsoft.Xna.Framework.Content.RectangleReader" Dynamic="Required All"/>
            <Type Name="Microsoft.Xna.Framework.Content.StringReader" Dynamic="Required All"/>
            <Type Name="Microsoft.Xna.Framework.Content.Vector2Reader" Dynamic="Required All"/>
            <Type Name="Microsoft.Xna.Framework.Content.Vector3Reader" Dynamic="Required All"/>
            <Type Name="Microsoft.Xna.Framework.Content.Vector4Reader" Dynamic="Required All"/>
            <Type Name="Microsoft.Xna.Framework.Content.CurveReader" Dynamic="Required All"/>
            <Type Name="Microsoft.Xna.Framework.Content.IndexBufferReader" Dynamic="Required All"/>
            <Type Name="Microsoft.Xna.Framework.Content.BoundingBoxReader" Dynamic="Required All"/>
            <Type Name="Microsoft.Xna.Framework.Content.MatrixReader" Dynamic="Required All"/>
            <Type Name="Microsoft.Xna.Framework.Content.BasicEffectReader" Dynamic="Required All"/>
            <Type Name="Microsoft.Xna.Framework.Content.VertexBufferReader" Dynamic="Required All"/>
            <Type Name="Microsoft.Xna.Framework.Content.AlphaTestEffectReader" Dynamic="Required All"/>
            <Type Name="Microsoft.Xna.Framework.Content.EnumReader`1[[Microsoft.Xna.Framework.Graphics.SpriteEffects,MonoGame.Framework]]" Dynamic="Required All"/>
            <Type Name="Microsoft.Xna.Framework.Content.ArrayReader`1[[System.Single,System.Private.CoreLib]]" Dynamic="Required All"/>
            <Type Name="Microsoft.Xna.Framework.Content.ArrayReader`1[[Microsoft.Xna.Framework.Vector2,MonoGame.Framework]]" Dynamic="Required All"/>
            <Type Name="Microsoft.Xna.Framework.Content.ListReader`1[[Microsoft.Xna.Framework.Vector2,MonoGame.Framework]]" Dynamic="Required All"/>
            <Type Name="Microsoft.Xna.Framework.Content.ArrayReader`1[[Microsoft.Xna.Framework.Matrix,MonoGame.Framework]]" Dynamic="Required All"/>
            <Type Name="Microsoft.Xna.Framework.Content.EnumReader`1[[Microsoft.Xna.Framework.Graphics.Blend,MonoGame.Framework]]" Dynamic="Required All"/>
            <Type Name="Microsoft.Xna.Framework.Content.NullableReader`1[[Microsoft.Xna.Framework.Rectangle,MonoGame.Framework]]" Dynamic="Required All"/>
            <Type Name="Microsoft.Xna.Framework.Content.EffectMaterialReader" Dynamic="Required All"/>
            <Type Name="Microsoft.Xna.Framework.Content.ExternalReferenceReader" Dynamic="Required All"/>
            <Type Name="Microsoft.Xna.Framework.Content.SoundEffectReader" Dynamic="Required All"/>
            <Type Name="Microsoft.Xna.Framework.Content.SongReader" Dynamic="Required All"/>
            <Type Name="Microsoft.Xna.Framework.Content.ModelReader" Dynamic="Required All"/>
            <Type Name="Microsoft.Xna.Framework.Content.Int32Reader" Dynamic="Required All"/>
            <Type Name="Microsoft.Xna.Framework.Content.EffectReader" Dynamic="Required All"/>
            <Type Name="Microsoft.Xna.Framework.Content.SingleReader" Dynamic="Required All"/>
        </Assembly>
    </Application>
</Directives>

With the above settings, if you execute dotnet publish from the command line, Native files will be output to the .\Publish folder.

dotnet publish ./YourProject.csproj --self-contained -r win-x64 -c Release -o .\Publish

I hope this article will be useful for other people who may have faced similar difficulties.

By Pirota Pirozou