是
Unity 官方博客译文(看完这篇博文非常的兴奋,第一时间想到的是翻译后介绍给大家,文章是以IL2CPP内部开发人员的角度来讲述。大约在一年以前,我们写了一篇博客讨论Unity中脚本将来会是个什么样子,在那篇博客中我们提到了崭新的IL2CPP后端,并许诺其会为Unity带来更高效和更适合于各个平台的虚拟机。在2015年的一月份,我们正式发布了第一个使用IL2CPP的平台:iOS 64-bit。而随着Unity 5的发布,又带给大家另一个使用IL2CPP的平台:WebGL。感谢我们社区中用户的大量宝贵的反馈,我们在接下来的时间里根据这些反馈得以更新IL2CPP,发布补丁版本,从而持续的改进IL2CPP的编译器和运行时库。我们没有停止改进IL2CPP的打算,但是在目前这个时间点上,我们觉得可以回过头来抽出点时间告诉大家一些IL2CPP的内部工作机制。在接下来的几个月的时间里,我们打算对以下话题(或者还有其他未列出的话题)进行讨论,来做一个IL2CPP深入讲解系列。目前准备讨论的话题有:1.基础 - 工具链和命令行参数(本篇博文)2.IL2CPP生成代码介绍3.IL2CPP生成代码调试小窍门4.方法调用介绍(一般方法调用和虚方法调用等)5. 通用代码共享的实现6.P/invoke(Platform Invocation Service)对于类型(types)和方法(methods)的封装7.垃圾回收器的集成8.测试框架(Testing frameworks)及其使用为了能让这个系列的讨论成为可能,我们会涉及到一些将来肯定会进行改动的IL2CPP的实现细节。但这也没有关系,通过这些讨论,我们希望能给大家提供一些有用和有趣的信息。什么是IL2CPP?从技术层面上来说,我们说的IL2CPP包含了两部分: 一个进行 预先编译(译注:ahead-of-time,又叫AOT,以下一律使用AOT缩写)的编译器 一个支持虚拟机的运行时库AOT编译器将由.NET 输出的中间语言(IL)代码生成为C++代码。运行时库则提供诸如垃圾回收,与平台无关的线程,IO以及内部调用(C++原生代码直接访问托管代码结构)这样的服务和抽象层。AOT编译器IL2CPP AOT编译器实际的执行文件是il2cpp.exe。在Windows平台你可以在Unity安装路径的Editor\Data\il2cpp目录下找到。对于OSX平台,它位于Unity安装路径的Contents/Frameworks/il2cpp/build目录内。 il2cpp.exe这个工具是一个托管代码可执行文件,其完全由C#写成。在开发IL2CPP的过程中,我们同时使用.NET和Mono编译器对其进行编译。il2cpp 接受来自Unity自带的或者由Mono编译器产生的托管程序集,将这些程序集转换成C++代码。这些转换出的C++代码最终由部署目标平台上的C++编译器进行编译。你可以参照下图理解IL2CPP工具链的作用:运行时库IL2CPP的另外一个部分就是对虚拟机提供支持的运行时库。我们基本上是用C++代码来实现整个运行时库的(好吧,其实里面还是有一些和平台相关的代码使用了程序集,这个只要你知我知便好,不要告诉别人 )。我们把运行时库称之为libli2cpp,它是作为一个静态库被连接到最终的游戏可执行文件中。这么做的一个主要的好处是可以使得整个IL2CPP技术是简单并且是可移植的。你能通过查看随Unity一起发布的libil2cpp头文件来窥探其代码组织方式(Windows平台,头文件在Editor\Data\PlaybackEngines\webglsupport\BuildTools\Libraries\libil2cpp\include目录中。OSX平台,头文件在Contents/Frameworks/il2cpp/libil2cpp目录中)。举个例子,由il2cpp产生的C++代码和libil2cpp之间的接口API,存在于codegen/il2cpp-codegen.h这个文件中。运行时的另外一个重要的部分,就是垃圾收集器。在Unity 5中,我们使用libgc垃圾收集器。它是一个典型的贝姆垃圾收集器(Boehm-Demers-Weiser garbage collector)。(译注:相对使用保守垃圾回收策略)。然而我们的libil2cpp被设计成可以方便使用其他垃圾回收器。因此我们现在也在研究集成微软开源的垃圾回收器(Microsoft GC)。对于垃圾回收器这一点,我们会在后续的一篇中专门的讨论,这里就不多说了。il2cpp是如何执行的?让我们从一个简单的例子入手。这里使用Unity的版本是5.0.1,在Windows环境并且建立一个全新的空项目。然后创建一个带MonoBehaviour的脚本文件,将其作为组件加入到Main Camera上。代码也是非常的简单,输出Hello World:| 1234567 | using UnityEngine;public class HelloWorld : MonoBehaviour { void Start () { Debug.Log("Hello, IL2CPP!"); }} |
- –copy-level=None
- 指明il2cpp.exe不对生成的C++文件进行copy操作
- –enable-generic-sharing
- 告诉IL2CPP如果可以,对通用方法进行共享。这个可以减少代码并降低最后二进制文件的尺寸
- –enable-unity-event-support
- 确保和Unity events相关的,通过反射机制来运作的代码,能够正确生成。
- –output-format=Compact
- 在生成C++代码时为里面的类型和方法使用更短的名字。这会使得C++代码难以阅读,因为原来在IL中的名字被更短的取代了。但好处是可以让C++编译器运行的更快。
- –extra-types.file=”C:\Program Files\Unity\Editor\Data\il2cpp\il2cpp_default_extra_types.txt”
- 使用默认的(也是空的)额外类型文件。il2cpp.exe会将在这个文件中出现的基本类型或者数组类型看作是在运行时生成的而不是一开始出现在IL代码中来对待。
- “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”
评论