AoT workaround to generate code is ignored when it is placed in a package and references a built assembly

I’d like to make a package that will be run on an AOT platform with the IL2CPP scripting backend.

Part of the code is compiled, and I have added appropriated code to work around the following AOT issue (ExecutionEngineException: Attempting to call method ‘XXXX’ for which no ahead of time (AOT) code was generated.), but when I move the code from the Assets folder to the package, the error appears again.


Here is a simplified code that illustrates the issue:

---- Sample.cs

using System;
using System.Reflection;
using UnityEngine;

public class SourceValue<T> { public T value; }
public class TargetValue<T> { public T value; }

public class Dummy
{
  public static TargetValue<T> GenericMethod<T>(SourceValue<T> source)
  {
    return new TargetValue<T> { value = source.value };
  }
}

---- AOTSolver.cs

///The code that will prevent the ExecutionEngineException
class AOTSolver
{
 static void ForceRegistrationOfMethod()
 {
   SourceValue<float> source = new SourceValue<float>();
   Dummy.GenericMethod<float>(source);
 }
}

And I create a scene containing a Sample component.


  1. If both those scripts are in the Assets folder (no package), the UWP build (il2cpp) behaves correctly.
  1. If both those scripts are in a package with the following structure, everything is also fine.
  • package.json

  • Runtime/Sample.cs

  • Runtime/AOTSolver.cs

  • Runtime/mylib.Runtime.asmdef

  1. Now, I want the file Sample.cs to be built in the assembly Sample.dll, so my package look like this:
  • package.json
  • Runtime/Sample.dll
  • Runtime/AOTSolver.cs
  • Runtime/mylib.Runtime.asmdef

The error appears again.

Is my package badly structured ? I tried changing the properties of the asmdef and the dll.meta, without success.

Note: if I move the file AOTSolver.cs back in the Assets folder (living the rest of the files in the package), the code works again, but this is a solution I’d like to avoid.

  • Assets/AOTSolver.cs

  • package.json

  • Runtime/Sample.dll

  • Runtime/mylib.Runtime.asmdef

Note: tested on Unity 2019.4 and 2020.2

[Edited for formatting]

When ForceRegistrationOfMethod is in the assets assembly it ends up compiled into Assembly-CSharp.dll which is not stripped by managed code stripping. When you move it to a package it may or may not be stripped away depending on a variety of factors. In your case I’m guessing it is stripped away.

Try adding[Preserve] on ForceRegistrationOfMethod. This will ensure that ForceRegistrationOfMethod survives managed code stripping as long as some code path that is used references the package.