IL2CPP Internals:

Il2CPP Reverse:

Tutorial:

Adventures:

Honkai Impact:

How is il2cpp.exe executed?

Let’s take a look at an example. I’ll be using Unity 5.0.1 on Windows, and I’ll start with a new, empty project. So that we have at least one user script to convert, I’ll add this simple MonoBehaviour component to the Main Camera game object:

                
                using UnityEngine;
public class HelloWorld : MonoBehaviour 
{
void Start () 
{
Debug.Log("Hello, IL2CPP!");
}
}

When build for the WebGL platform, Can use Process Explorer to see the command line Unity used to run il2cpp.exe:

                "C:\Program Files\Unity\Editor\Data\MonoBleedingEdge\bin\mono.exe" 
"C:\Program Files\Unity\Editor\Data\il2cpp/il2cpp.exe" --copy-level=None --enable-generic-sharing --enable-unity-event-support --output-format=Compact --extra-types.file="C:\Program Files\Unity\Editor\Data\il2cpp\il2cpp_default_extra_types.txt" 
"C:\Users\Josh Peterson\Documents\IL2CPP Blog Example\Temp\StagingArea\Data\Managed\Assembly-CSharp.dll" 
"C:\Users\Josh Peterson\Documents\IL2CPP Blog Example\Temp\StagingArea\Data\Managed\UnityEngine.UI.dll" 
"C:\Users\Josh Peterson\Documents\IL2CPP Blog Example\Temp\StagingArea\Data\il2cppOutput"
                    
                    

That command line is pretty long and horrible, so let’s unpack it. First, Unity is running this executable:

                "C:\Program Files\Unity\Editor\Data\MonoBleedingEdge\bin\mono.exe"
            

The next argument on the command line is the il2cpp.exe utility itself.

                "C:\Program Files\Unity\Editor\Data\il2cpp/il2cpp.exe"
            

The remaining command line arguments are passed to il2cpp.exe, not mono.exe. Let’s look at them. First, Unity passes five flags to il2cpp.exe:

  • --copy-level=None
    • Specify that il2cpp.exe should not perform an special file copies of the generated C++ code.
  • --enable-generic-sharing
    • This is a code and binary size reduction feature. IL2CPP will share the implementation of generic methods when it can.
  • --enable-unity-event-support
    • Special support to ensure that code for Unity events, which are accessed via reflection, is correctly generated.
  • --output-format=Compact
    • Generate C++ code in a format that requires fewer characters for type and method names. This code is difficult to debug, since the names in the IL code are not preserved, but it often compiles faster, since there is less code for the C++ compiler to parse.
  • --extra-types.file="C:\Program Files\Unity\Editor\Data\il2cpp\il2cpp_default_extra_types.txt"
    • Use the default (and empty) extra types file. This file can be added in a Unity project to let il2cpp.exe know which generic or array types will be created at runtime, but are not present in the IL code.

It is important to note that these command line arguments can and will be changed in later releases. We’re not at a point yet where we have a stable and supported set of command line arguments for il2cpp.exe.

Finally, we have a list of two files and one directory on the command line:

  • "C:\Users\Josh Peterson\Documents\IL2CPP Blog
    Example\Temp\StagingArea\Data\Managed\Assembly-CSharp.dll"
  • "C:\Users\Josh Peterson\Documents\IL2CPP Blog
    Example\Temp\StagingArea\Data\Managed\UnityEngine.UI.dll"
  • "C:\Users\Josh Peterson\Documents\IL2CPP Blog
    Example\Temp\StagingArea\Data\il2cppOutput"

The il2cpp.exe utility accepts a list of all of the IL assemblies it should convert. In this case they are the assembly containing my simple MonoBehaviour, Assembly-CSharp.dll, and the GUI assembly, UnityEngine.UI.dll. Note that there are a few conspicuously missing assembles here. Clearly, my script references UnityEngine.dll, and that references at least mscorlib.dll, and maybe other assemblies. Where are they? Actually, il2cpp.exe resolves those assemblies internally. They can be mentioned on the command line, but they are not necessary. Unity only needs to mention the root assemblies (those which are not referenced by any other assembly) explicitly.

The last argument on the il2cpp.exe command line is the directory where the output C++ files should be created. If you are curious, have a look at the generated files in that directory, they will be the subject of the next post in this series. Before you do though, you might want to choose the “Development Player” option in the WebGL build settings. That will remove the --output-format=Compact command line argument and give you better type and method names in the generated C++ code.

Try changing various options in the WebGL or iOS Player Settings. You should be able to see different command line options passed to il2cpp.exe to enable different code generation steps. For example, changing the “Enable Exceptions” setting in the WebGL Player Settings to a value of “Full” adds the --emit-null-checks, --enable-stacktrace, and --enable-array-bounds-check arguments to the il2cpp.exe command line.