il2cpp_IL2CPP内部介绍

il2cpp_IL2CPP内部介绍_第1张图片

il2cpp

Almost a year ago now, we started to talk about the future of scripting in Unity. The new IL2CPP scripting backend promised to bring a highly-performant, highly-portable virtual machine to Unity. In January, we shipped our first platform using IL2CPP, iOS 64-bit. The Unity 5 release brought another platform, WebGL. Thanks to the input from our tremendous community of users, we have shipped many patch release updates for IL2CPP, steadily improving its compiler and runtime.

大约一年前的现在,我们开始谈论Unity中脚本的未来 。 新的IL2CPP脚本后端承诺将为Unity带来高性能,高度可移植的虚拟机。 1月,我们使用IL2CPP( iOS 64位)发布了第一个平台。 Unity 5版本带来了另一个平台WebGL 。 感谢广大用户的反馈,我们为IL2CPP发行了许多补丁程序更新 ,从而稳步改善了其编译器和运行时。

We have no plans to stop improving IL2CPP, but we thought it might be a good idea to take a step back and tell you a little bit about how IL2CPP works from the inside out. Over the next few months, we’re planning to write about the following topics (and maybe others) in this IL2CPP Internals series of posts:

我们没有停止改善IL2CPP的计划,但是我们认为最好退一步,向您介绍一下IL2CPP从内而外的工作原理。 在接下来的几个月中,我们计划在此IL2CPP Internals系列文章中撰写以下主题(可能还有其他主题):

  1. A tour of generated code

    生成代码之旅

  2. Debugging tips for generated code

    生成代码的调试技巧

  3. Method calls (normal methods, virtual methods, etc.)

    方法调用 (普通方法,虚拟方法等)

  4. Generic sharing implementation

    通用共享实施

  5. P/invoke wrappers for types and methods

    P /调用包装器的类型和方法

  6. Garbage collection integration

    垃圾收集整合

  7. Testing frameworks and usage

    测试框架和用法

In order to make this series of posts possible, we’re going to discuss some details about the IL2CPP implementation that will surely change in the future. Hopefully we can still provide some useful and interesting information.

为了使这一系列文章成为可能,我们将讨论有关IL2CPP实现的一些细节,这些细节将来肯定会改变。 希望我们仍然可以提供一些有用和有趣的信息。

What is IL2CPP?

什么是IL2CPP?

The technology that we refer to as IL2CPP has two distinct parts.

我们称为IL2CPP的技术有两个不同的部分。

    The AOT compiler translates Intermediate Language (IL), the low-level output from .NET compilers, to C++ source code. The runtime library provides services and abstractions like a garbage collector, platform-independent access to threads and files, and implementations of internal calls (native code which modifies managed data structures directly).

    AOT编译器将.NET编译器的低级输出中间语言(IL)转换为C ++源代码。 运行时库提供服务和抽象,例如垃圾收集器,对线程和文件的平台独立访问以及内部调用的实现(直接修改托管数据结构的本机代码)。

    The AOT compiler

    AOT编译器

    The IL2CPP AOT compiler is named il2cpp.exe. On Windows you can find it in the Editor\Data\il2cpp directory. On OSX it is in the Contents/Frameworks/il2cpp/build directory in the Unity installation. The il2cpp.exe utility is a managed executable, written entirely in C#. We compile it with both .NET and Mono compilers during our development of IL2CPP.

    IL2CPP AOT编译器名为il2cpp.exe。 在Windows上,您可以在Editor \ Data \ il2cpp目录中找到它。 在OSX上,它位于Unity安装的Contents / Frameworks / il2cpp / build目录中。 il2cpp.exe实用程序是一个托管可执行文件,完全用C#编写。 在我们开发IL2CPP时,我们使用.NET和Mono编译器对其进行编译。

    The il2cpp.exe utility accepts managed assemblies compiled with the Mono compiler that ships with Unity and generates C++ code which we pass on to a platform-specific C++ compiler.

    il2cpp.exe实用程序接受使用Unity附带的Mono编译器编译的托管程序集,并生成C ++代码,然后将其传递给特定于平台的C ++编译器。

    You can think about the IL2CPP toolchain like this:

    您可以这样考虑一下IL2CPP工具链:

    il2cpp_IL2CPP内部介绍_第2张图片

    The runtime library

    运行时库

    The other part of the IL2CPP technology is a runtime library to support the virtual machine. We have implemented this library using almost entirely C++ code (it has a little bit of platform-specific assembly code, but let’s keep that between the two of us). We call the runtime library libil2cpp, and it is shipped as a static library linked into the player executable. One of the key benefits of the IL2CPP technology is this simple and portable runtime library.

    IL2CPP技术的另一部分是运行时库,用于支持虚拟机。 我们几乎完全使用C ++代码实现了该库(它有一些特定于平台的汇编代码,但让我们将其保留在我们两个人之间)。 我们将运行时库称为libil2cpp,它作为链接到播放器可执行文件的静态库提供。 IL2CPP技术的主要优势之一就是这个简单且可移植的运行时库。

    You can find some clues about how the libil2cpp code is organized by looking at the header files for libil2cpp we ship with Unity (you’ll find them in the  Editor\Data\PlaybackEngines\webglsupport\BuildTools\Libraries\libil2cpp\include directory on Windows, or the Contents/Frameworks/il2cpp/libil2cpp directory on OSX). For example, the interface between the C++ code generated by il2cpp.exe and the libil2cpp runtime is located in the codegen/il2cpp-codegen.h header file.

    通过查看我们随Unity一起提供的libil2cpp的头文件,您可以找到有关libil2cpp代码组织方式的一些线索(您可以在Windows的Editor \ Data \ PlaybackEngines \ webglsupport \ BuildTools \ Libraries \ libil2cpp \ include目录中找到它们) ,或OSX上的Contents / Frameworks / il2cpp / libil2cpp目录)。 例如,il2cpp.exe生成的C ++代码与libil2cpp运行时之间的接口位于codegen / il2cpp-codegen.h头文件中。

    One key part of the runtime is the garbage collector. We’re shipping Unity 5 with libgc, the Boehm-Demers-Weiser garbage collector. However, libil2cpp has been designed to allow us to use other garbage collectors. For example, we are researching an integration of the Microsoft GC which was open-sourced as part of the CoreCLR. We’ll have more to say about this in our post about garbage collector integration later in the series.

    运行时的关键部分是垃圾收集器。 我们将使用Boehm-Demers-Weiser垃圾收集器libgc交付 Unity 5。 但是,libil2cpp旨在允许我们使用其他垃圾收集器。 例如,我们正在研究Microsoft GC的集成,该集成是CoreCLR的一部分开源。 在本系列后面的有关垃圾收集器集成的文章中,我们将对此进行更多说明。

    How is il2cpp.exe executed?

    il2cpp.exe如何执行?

    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:

    让我们看一个例子。 我将在Windows上使用Unity 5.0.1,并从一个新的空项目开始。 为了至少有一个要转换的用户脚本,我将这个简单的MonoBehaviour组件添加到Main Camera游戏对象中:

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

    1

    2
    3
    4
    5
    6
    7
    using UnityEngine;
    public class HelloWorld : MonoBehaviour {
    void Start () {
    Debug.Log("Hello, IL2CPP!");
    }
    }

    1

    2
    3
    4
    5
    6
    7
    using UnityEngine ;
    public class HelloWorld : MonoBehaviour {
    void Start ( ) {
    Debug . Log ( "Hello, IL2CPP!" ) ;
    }
    }

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

    当我为WebGL平台构建时,可以使用Process Explorer查看用于运行il2cpp.exe的命令行Unity:

    "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" "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"

    1

    "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"

    1

    "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:

    该命令行很长而且很可怕,所以让我们打开它的包装。 首先,Unity运行此可执行文件:

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

    1

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

    1

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

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

    命令行上的下一个参数是il2cpp.exe实用程序本身。

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

    1

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

    1

    "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:

    其余命令行参数将传递给il2cpp.exe,而不是mono.exe。 让我们看看它们。 首先,Unity将五个标志传递给il2cpp.exe:

    • –copy-level=None

      –copy-level =无

      • –enable-generic-sharing

        –启用通用共享

        • –enable-unity-event-support

          –enable-unity-event-support

          • –output-format=Compact

            –output-format =紧凑

            • –extra-types.file=”C:\Program Files\Unity\Editor\Data\il2cpp\il2cpp_default_extra_types.txt”

              –extra-types.file =” C:\ Program Files \ Unity \ Editor \ Data \ il2cpp \ il2cpp_default_extra_types.txt”

              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.

              重要的是要注意,这些命令行参数可以并且将在以后的版本中更改。 我们还没有为il2cpp.exe提供一套稳定且受支持的命令行参数。

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

              最后,在命令行上有两个文件和一个目录的列表:

                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.

                il2cpp.exe实用程序接受应转换的所有IL程序集的列表。 在这种情况下,它们是包含我简单的MonoBehaviour的程序集Assembly-CSharp.dll和GUI程序集UnityEngine.UI.dll。 请注意,这里有一些明显缺少的程序集。 显然,我的脚本引用了UnityEngine.dll,并且至少引用了mscorlib.dll,也许还引用了其他程序集。 他们在哪? 实际上,il2cpp.exe在内部解析这些程序集。 可以在命令行上提及它们,但不是必需的。 Unity只需要明确提及根程序集(其他程序集未引用的根程序集)。

                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.

                il2cpp.exe命令行上的最后一个参数是应在其中创建输出C ++文件的目录。 如果您感到好奇,请查看该目录中生成的文件,它们将是本系列下一篇文章的主题。 但是,在进行此操作之前,您可能需要在WebGL构建设置中选择“开发播放器”选项。 这将删除–output-format = Compact命令行参数,并在生成的C ++代码中为您提供更好的类型和方法名称。

                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.

                尝试更改WebGL或iOS Player设置中的各种选项。 您应该能够看到传递给il2cpp.exe的不同命令行选项,以启用不同的代码生成步骤。 例如,将WebGL Player设置中的“ Enable Exceptions”设置更改为“ Full”值,将–emit-null-checks,–enable-stacktrace和–enable-array-bounds-check参数添加到il2cpp。 exe命令行。

                What does IL2CPP not do?

                IL2CPP不做什么?

                I’d like to point out one of the challenges that we did not take on with IL2CPP, and we could not be happier that we ignored it. We did not attempt to re-write the C# standard library with IL2CPP. When you build a Unity project which uses the IL2CPP scripting backend, all of the C# standard library code in mscorlib.dll, System.dll, etc. is the exact same code used for the Mono scripting backend.

                我想指出我们在IL2CPP上没有遇到的挑战之一,并且我们对忽略它感到高兴。 我们没有尝试用IL2CPP重写C#标准库。 当您构建使用IL2CPP脚本后端的Unity项目时,mscorlib.dll,System.dll等中的所有C#标准库代码与用于Mono脚本后端的代码完全相同。

                We rely on C# standard library code that is already well-known by users and well-tested in Unity projects. So when we investigate a bug related to IL2CPP, we can be fairly confident that the bug is in either the AOT compiler or the runtime library, and nowhere else.

                我们依赖于C#标准库代码,该代码已经为用户所熟知,并在Unity项目中经过了良好的测试。 因此,当我们调查与IL2CPP有关的错误时,我们可以完全确定该错误在AOT编译器或运行时库中,而没有其他地方。

                How we develop, test, and ship IL2CPP

                我们如何开发,测试和运送IL2CPP

                Since the initial public release of IL2CPP at version 4.6.1p5 in January, we’ve shipped 6 full releases and 7 patch releases (across versions 4.6 and 5.0 of Unity). We have corrected more than 100 bugs mentioned in the release notes.

                自从一月份的IL2CPP首次公开发行4.6.1p5版本以来,我们已经发布了6个完整版本和7个补丁版本(Unity 4.6和5.0版本)。 我们已经纠正了发行说明中提到的100多个错误。

                In order to make this continuous improvement happen, we develop against only one version of the IL2CPP code internally, which sits on the bleeding edge of the trunk branch in Unity used to ship alpha and beta releases. Just before each release, we port the IL2CPP changes to the specific release branch, run our tests, and verify all of the bugs we fixed are corrected in that version. Our QA and Sustained Engineering teams have done incredible work to make delivery at this rate possible. This means that our users are never more than about one week away from the latest fixes for IL2CPP bugs.

                为了使这种持续改进得以实现,我们仅在内部针对IL2CPP代码的一个版本进行开发,该版本位于Unity中用于发布alpha和beta版本的主干分支的前沿。 就在每个发行版之前,我们将IL2CPP更改移植到特定的发行分支,运行我们的测试,并验证在该版本中纠正的所有错误。 我们的质量保证和持续工程团队做了出色的工作,以这种速度交付产品。 这意味着我们的用户离IL2CPP错误的最新修补程序只有不到一周的时间。

                Our user community has proven invaluable by submitting many high quality bug reports. We appreciate all the feedback from our users to help continually improve IL2CPP, and we look forward to more of it.

                通过提交许多高质量的错误报告,我们的用户社区被证明是无价的。 我们非常感谢用户提供的所有反馈意见,以帮助他们不断改善IL2CPP,我们期待着更多的反馈。

                The development team working on IL2CPP has a strong test-first mentality. We often employee Test Driven Design practices, and seldom merge a pull request without good tests. This strategy works well for a technology like IL2CPP, where we have clear inputs and outputs. It means that the vast majority of the bugs we see are not unexpected behavior, but rather unexpected cases (e.g. it is possible to use an 64-bit IntPtr as a 32-bit array index, causing clang to fail with a C++ compiler error, and real code actually does this!). That difference allows us to fix bugs quickly with a high degree of confidence.

                IL2CPP的开发团队具有强烈的测试优先心态。 我们经常采用“测试驱动设计”实践,并且很少合并没有良好测试的拉取请求。 这种策略对于像IL2CPP这样的技术非常有效,在该技术中我们有明确的输入和输出。 这意味着我们看到的绝大多数错误不是意外行为,而是意外情况(例如,可以将64位IntPtr用作32位数组索引,从而导致Clang失败并出现C ++编译器错误,而实际的代码实际上就是这样做的!)。 这种差异使我们能够高度自信地快速修复错误。

                With the help of our community, we’re working hard to make IL2CPP as stable and fast as possible. By the way, if any of this excites you, we’re hiring (just sayin’).

                在我们社区的帮助下,我们正在努力使IL2CPP尽可能稳定和快速。 顺便说一句,如果其中任何一个使您兴奋, 我们正在招聘 (只是说)。

                More to come

                还有更多

                I fear that I’ve spent too much time here teasing future blog posts. We have a lot to say, and it simply won’t all fit in one post. Next time, we’ll dig into the code generated by il2cpp.exe to see how your project actually looks to the C++ compiler.

                我担心我在这里花了太多时间来逗弄未来的博客文章。 我们有很多话要说,而且根本不可能全部适合一篇文章。 下次,我们将深入研究il2cpp.exe生成的代码,以查看您的项目对C ++编译器的实际外观。

                翻译自: https://blogs.unity3d.com/2015/05/06/an-introduction-to-ilcpp-internals/

                il2cpp

                你可能感兴趣的:(c++,python,java,大数据,linux)