Handling platform specific settings for IL2CPP additional arguments
The IL2CPP (Intermediate Language To C++) scripting backendA framework that powers scripting in Unity. Unity supports three different scripting backends depending on target platform: Mono, .NET and IL2CPP. Universal Windows Platform, however, supports only two: .NET and IL2CPP. More info
See in Glossary is an alternative to the Mono backend. IL2CPP provides better support for applications across a wider range of platforms. The IL2CPP backend converts MSIL (Microsoft Intermediate Language) code (for example, C# code in scripts) into C++ code, then uses the C++ code to create a native binary file (for example, .exe, .apk, or .xap) for your chosen platform.
This type of compilation, in which Unity compiles code specifically for a target platform when it builds the native binary, is called ahead-of-time (AOT) compilation. The Mono backend compiles code at runtime, with a technique called just-in-time compilation (JIT).
On this page:
- Building a project using IL2CPP
- How IL2CPP works
- Optimising IL2CPP build times
- Enabling runtime checks using IL2CppSetOption
Some platforms don’t support AOT compilationAhead of Time (AOT) compilation is an iOS optimization method for optimizing the size of the built iOS player More info
See in Glossary, so the IL2CPP backend doesn’t work on every platform. Other platforms support AOT and IL2CPP, but don’t allow JIT compilation, and so can’t support the Mono backend. When a platform can support both backends, Mono is the default. For more information, see Scripting restrictions.
IL2CPP can improve performance across a variety of platforms, but the need to include machine code in built applications increases both the build time and the size of the final built application. For more information, see How IL2CPP works and the blog series An introduction to IL2CPP internals.
IL2CPP supports the debugging of managed code in the same way as the Mono scripting backend. For more information, see Debugging C# code in Unity.
Building a project using IL2CPP
To build a project with IL2CPP, you need to have the backend installed in your Unity installation. You can select IL2CPP as an optional module when you first install a version of Unity, or add IL2CPP support to an existing installation through the Unity Hub. For more information, see Installing the Unity Hub and Add modules to the Unity Editor.
IL2CPP also requires some systems native to the target platform to generate the C++ code. This means that to use IL2CPP on a specific platform, you need to build the application on that platform. For example, to use IL2CPP with MacOS as a build target, you need to build the application on a machine that uses MacOS. For more information about system requirements for desktop platforms, including IL2CPP requirements for individual platforms, see the Desktop section of System Requirements for Unity.
You can change the scripting backend Unity uses to build your application in one of two ways:
-
Through the Player SettingsSettings that let you set various player-specific options for the final game built by Unity. More info
See in Glossary menu in the Editor. Perform the following steps to change the scripting backend through the Player Settings menu:- Go to Edit > Project Settings.
- Click on the Player Settings button to open the Player settings for the current platform in the Inspector.
- Navigate to the Configuration section heading under the Other Settings sub-menu.
- Click on the Scripting Backend dropdown menu, then select IL2CPP.
You can also open the Player Settings menu from inside the Build Settings menu; go to File > Build Settings and click on the Player Settings button.
-
Through the Editor scripting API. Use the PlayerSettings.SetScriptingBackend property to change the scripting backend that Unity uses.
To start the build process, open the Build Settings window and click the Build button. Unity then converts your C# code and assemblies into C++ and finally produces a binary file for your target platform.
How IL2CPP works
When you start a build using IL2CPP, Unity automatically performs the following steps:
- The Roslyn C# compiler compiles your application’s C# code and any required package code to .NET DLLs (managed assemblies).
- Unity applies managed bytecode stripping. This step can significantly reduce the size of a built application.
- The IL2CPP backend converts all managed assemblies into standard C++ code.
- The C++ compiler compiles the generated C++ code and the runtime part of IL2CPP with a native platform compiler.
- Unity creates either an executable file or a DLL, depending on the platform you target.
Both IL2CPP and Mono provide a few useful options which you can control with attributes in your scriptsA piece of code that allows you to create your own Components, trigger game events, modify Component properties over time and respond to user input in any way you like. More info
See in Glossary. For more information, see Platform-dependent compilation.
IL2CPP enables Unity to pre-compile code for specific platforms. The binary file Unity produces at the end of this process already contains necessary machine code for the target platform, while Mono has to compile this machine code at runtime during execution. AOT compilation does increase build time, but it also improves compatibility with the target platform and can improve performance.
Both scripting backends require a new build for each platform you want to target. For example, to support both the Android and iOSApple’s mobile operating system. More info
See in Glossary platforms, you need to build your application twice and produce two binary files.
The assembly stripping stage helps reduce the final binary size. Unity removes any bytecode that the final built application doesn’t use.
Optimizing IL2CPP build times
Project build times when using IL2CPP can be significantly longer than when using Mono. However, you can do several things to reduce build time.
Exclude your project from anti-malware software scans
You can exclude your Unity project folder and target build folders from anti-malware software scans before you build your project.
Store your project and target build folder on a solid-state drive (SSD)
Solid-state drives (SSDs) have faster read/write speeds than traditional hard disk drives (HDD). Converting IL code to C++ and compiling it involves a large number of read/write operations, so a faster storage device speeds up this process.
Change the IL2CPP Code Generation option in the Build Settings
To change how IL2CPP generates code, open the Build Settings and configure the IL2CPP Code Generation option By default, the Faster runtime option is enabled, which produces more machine code that reduces the impact of IL2CPP at runtime. To reduce build times, you can set this option to Faster (smaller) builds. This method produces and includes less machine code in the binary executable and so can reduce performance at runtime, but also significantly reduces build times and binary size.
Enabling runtime checks using Il2CppSetOption
When you use the IL2CPP scripting backend, you can control how il2cpp.exe generates C++ code. You can use the Il2CppSetOption attribute to enable or disable the following runtime checks:
Property: | Description: | Default: |
---|---|---|
Null checks | If this option is enabled, the C++ code that IL2CPP generates contains null checks and throws managed NullReferenceException exceptions as necessary. If this option is disabled, IL2CPP doesn’t emit the null checks into the generated C++ code. For some projects, disabling this option might improve runtime performance.
When this setting is disabled, Unity doesn’t prevent attempts to access null values in the generated code, which might lead to incorrect behavior. Your application is likely to crash soon after it dereferences the null value. Unity recommends that you don’t disable this option. |
Enabled |
Array bounds checks | If this option is enabled, the C++ code that IL2CPP generates contains array bounds checks and throws managed IndexOutOfRangeException exceptions as necessary. If this option is disabled, IL2CPP doesn’t emit the array bounds checks into the generated C++ code.
For some projects, disabling this option might improve runtime performance. However, when this option is disabled, Unity doesn’t prevent attempts to access an array with invalid indices in the generated code, which might lead to incorrect behavior, including reading from or writing to arbitrary memory locations. In most cases, these memory accesses occur without any immediate side effects, and can corrupt the state of the application with no obvious warning signs. This can make debugging these errors extremely difficult. Unity recommends that you keep this option enabled. |
Enabled |
Divide by zero checks | If this option is enabled, C++ code generated by IL2CPP contains divide by zero checks for integer division and throw managed DivideByZeroException exceptions as necessary. If this option is disabled, IL2CPP doesn’t emit the divide by zero checks on integer division into the generated C++ code.
These checks have an impact on performance at runtime. You should only enable this option if you need to run divide by zero checks; otherwise, leave it disabled. |
Disabled |
To use the Il2CppSetOption attribute:
- In the directory where your Unity version is installed, navigate to the Datail2cpp directory on Windows, or the Contents/Frameworks/il2cpp directory on OS X.
- Find the Il2CppSetOptionAttribute.cs source file.
- Copy the source file into your project’s Assets directory.
The below example describes how to use the Il2CppSetOption attribute:
[Il2CppSetOption(Option.NullChecks, false)]
public static string MethodWithNullChecksDisabled()
{
var tmp = new object();
return tmp.ToString();
}
You can apply Il2CppSetOption attribute to types, methods, and properties. Unity uses the attribute from the most local scope.
[Il2CppSetOption(Option.NullChecks, false)]
public class TypeWithNullChecksDisabled
{
public static string AnyMethod()
{
// Unity doesn’t perform null checks in this method.
var tmp = new object();
return tmp.ToString();
}
[Il2CppSetOption(Option.NullChecks, true)]
public static string MethodWithNullChecksEnabled()
{
// Unity performs null checks in this method.
var tmp = new object();
return tmp.ToString();
}
}
public class SomeType
{
[Il2CppSetOption(Option.NullChecks, false)]
public string PropertyWithNullChecksDisabled
{
get
{
// Unity doesn’t perform null checks here.
var tmp = new object();
return tmp.ToString();
}
set
{
// Unity doesn’t perform null checks here.
value.ToString();
}
}
public string PropertyWithNullChecksDisabledOnGetterOnly
{
[Il2CppSetOption(Option.NullChecks, false)]
get
{
// Unity doesn’t perform null checks here.
var tmp = new object();
return tmp.ToString();
}
set
{
// Unity performs null checks here.
value.ToString();
}
}
}
• 2018–05–15 Page amended
Handling platform specific settings for IL2CPP additional arguments
IL2CPP (промежуточный язык для C++) серверная часть сценариев Фреймворк, поддерживающий сценарии в Unity. Unity поддерживает три различных бэкэнда для сценариев в зависимости от целевой платформы: Mono, .NET и IL2CPP. Однако универсальная платформа Windows поддерживает только два: .NET и IL2CPP. Дополнительная информация
См. в Словарь – это альтернатива серверной части Mono. IL2CPP обеспечивает лучшую поддержку приложений на более широком диапазоне платформ. Серверная часть IL2CPP преобразует код MSIL (Microsoft Intermediate Language) (например, код C# в сценариях) в код C++, а затем использует код C++ для создания собственного двоичного файла (например, .exe, .apk или .xap) для выбранная вами платформа.
Этот тип компиляции, при котором Unity компилирует код специально для целевой платформы при создании собственного двоичного файла, называется компиляцией с опережением (AOT). Бэкенд Mono компилирует код во время выполнения с помощью техники, называемой JIT-компиляцией.
На этой странице:
- Создание проекта с использованием IL2CPP
- Как работает IL2CPP
- Оптимизация времени сборки IL2CPP
- Включение проверок во время выполнения с помощью IL2CppSetOption
Некоторые платформы не поддерживают компиляцию AOTКомпиляция с опережением времени (AOT) — это метод оптимизации iOS для оптимизации размера встроенного проигрывателя iOS Подробнее
См. в Словарь, так что бэкенд IL2CPP работает не на каждой платформе. Другие платформы поддерживают AOT и IL2CPP, но не допускают JIT-компиляции и поэтому не могут поддерживать бэкэнд Mono. Когда платформа может поддерживать оба бэкенда, по умолчанию используется Mono. Дополнительную информацию см. в разделе Ограничения использования сценариев.
IL2CPP может повысить производительность на различных платформах, но необходимость включения машинного кода во встроенные приложения увеличивает как время сборки, так и размер конечного приложения. Дополнительную информацию см. в разделе Как работает IL2CPP и в серии блогов Введение во внутренние устройства IL2CPP. .
IL2CPP поддерживает отладку управляемого кода так же, как и серверная часть сценариев Mono. Дополнительную информацию см. в разделе Отладка кода C# в Unity.
Сборка проекта с использованием IL2CPP
Чтобы создать проект с помощью IL2CPP, вам необходимо установить серверную часть в вашей установке Unity. Вы можете выбрать IL2CPP в качестве дополнительного модуля при первой установке версии Unity или добавить поддержку IL2CPP в существующую установку через Unity Hub. Дополнительные сведения см. в разделах Установка Unity Hub и Добавить модули в редактор Unity.
Вы можете изменить серверную часть сценариев, которую Unity использует для создания вашего приложения, одним из двух способов:
-
Через Настройки игрокаНастройки, которые позволяют вам установить различные параметры для конкретного игрока для окончательной игры, созданной Unity. . Подробнее
См. в меню Словарь в Редакторе. Выполните следующие шаги, чтобы изменить серверную часть сценариев через меню Настройки проигрывателя:- Выберите Редактировать > Настройки проекта.
- Нажмите кнопку Настройки проигрывателя, чтобы открыть настройки проигрывателя для текущей платформы в Инспектор.
- Перейдите к заголовку раздела Конфигурация в подменю Другие настройки.
- Нажмите раскрывающееся меню Scripting Backend, затем выберите IL2CPP.
Вы также можете открыть меню Настройки проигрывателя из меню Настройки сборки; перейдите в раздел Файл > Настройки сборки и нажмите кнопку Настройки проигрывателя.
-
Через API сценариев редактора. Используйте свойство PlayerSettings.SetScriptingBackend, чтобы изменить серверную часть сценариев, которую использует Unity.
Как работает IL2CPP
Когда вы запускаете сборку с использованием IL2CPP, Unity автоматически выполняет следующие шаги:
- Компилятор Roslyn C# компилирует код C# вашего приложения и любой необходимый код пакета в .NET DLL (управляемые сборки).
- Unity применяет управляемое удаление байт-кода. Этот шаг может значительно уменьшить размер встроенного приложения.
- Бэкенд IL2CPP преобразует все управляемые сборки в стандартный код C++.
- Компилятор C++ компилирует сгенерированный код C++ и исполняемую часть IL2CPP с помощью собственного компилятора платформы.
- Unity создает либо исполняемый файл, либо DLL, в зависимости от целевой платформы.
Как IL2CPP, так и Mono предоставляют несколько полезных параметров, которыми можно управлять с помощью атрибутов в ваших скриптахфрагмент кода, который позволяет вы можете создавать свои собственные Компоненты, запускать игровые события, изменять свойства Компонентов с течением времени и реагировать на ввод данных пользователем любым удобным для вас способом. Подробнее
См. в Словарь. Дополнительные сведения см. в разделе Компиляция в зависимости от платформы.
IL2CPP позволяет Unity предварительно компилировать код для определенных платформ. Двоичный файл, который Unity создает в конце этого процесса, уже содержит необходимый машинный код для целевой платформы, в то время как Mono должен компилировать этот машинный код во время выполнения во время выполнения. Компиляция AOT увеличивает время сборки, но также улучшает совместимость с целевой платформой и может повысить производительность.
Для обоих бэкэндов сценариев требуется новая сборка для каждой целевой платформы. Например, для поддержки как Android, так и iOSмобильной операционной системы Apple. Подробнее
На платформах Словарь вам нужно дважды собрать приложение и создать два двоичных файла. файлы.
Этап разборки сборки помогает уменьшить окончательный размер двоичного файла. Unity удаляет любой байт-код, который не используется в готовом приложении.
Оптимизация времени сборки IL2CPP
Время сборки проекта при использовании IL2CPP может быть значительно больше, чем при использовании Mono. Однако вы можете сделать несколько вещей, чтобы сократить время сборки.
Исключить ваш проект из сканирования антивирусным ПО
Вы можете исключить папку проекта Unity и целевые папки сборки из сканирования программным обеспечением для защиты от вредоносных программ перед сборкой проекта.
Сохраните проект и целевую папку сборки на твердотельном накопителе (SSD)
Твердотельные накопители (SSD) имеют более высокую скорость чтения/записи, чем традиционные жесткие диски (HDD). Преобразование кода IL в C++ и его компиляция требуют большого количества операций чтения/записи, поэтому более быстрое запоминающее устройство ускоряет этот процесс.
Включение проверок во время выполнения с помощью Il2CppSetOption
При использовании серверной части сценариев IL2CPP можно управлять тем, как il2cpp.exe генерирует код C++. Вы можете использовать атрибут Il2CppSetOption, чтобы включить или отключить следующие проверки во время выполнения:
Свойства: | Описание: | По умолчанию: |
---|---|---|
Null checks | Если этот параметр включен, код C++, генерируемый IL2CPP, содержит проверки нулевых значений и при необходимости создает управляемые исключения NullReferenceException. Если этот параметр отключен, IL2CPP не выдает нулевые проверки в сгенерированный код C++. Для некоторых проектов отключение этого параметра может улучшить производительность во время выполнения.
Если этот параметр отключен, Unity не предотвращает попытки доступа к нулевым значениям в сгенерированном коде, что может привести к некорректному поведению. Ваше приложение, скорее всего, рухнет вскоре после того, как оно разыменует нулевое значение. Unity рекомендует не отключать эту опцию. |
Enabled |
Array bounds checks | Если этот параметр включен, код C++, создаваемый IL2CPP, содержит проверки границ массива и при необходимости создает управляемые исключения IndexOutOfRangeException. Если эта опция отключена, IL2CPP не выдает проверки границ массива в сгенерированный код C++.
Для некоторых проектов отключение этого параметра может повысить производительность во время выполнения. Однако, когда этот параметр отключен, Unity не предотвращает попытки доступа к массиву с недопустимыми индексами в сгенерированном коде, что может привести к некорректному поведению, включая чтение или запись в произвольные области памяти. В большинстве случаев эти обращения к памяти происходят без каких-либо немедленных побочных эффектов и могут повредить состояние приложения без каких-либо явных предупреждающих признаков. Это может сильно затруднить отладку этих ошибок. Unity рекомендует оставить этот параметр включенным. |
Enabled |
Divide by zero checks | Если этот параметр включен, код C++, сгенерированный IL2CPP, содержит проверки деления на ноль для целочисленного деления и при необходимости создает управляемые исключения DivideByZeroException. Если эта опция отключена, IL2CPP не выдает проверки деления на ноль при целочисленном делении в сгенерированный код C++.
Эти проверки влияют на производительность во время выполнения. Вы должны включать эту опцию только в том случае, если вам нужно выполнить проверку деления на ноль; в противном случае оставьте его отключенным. |
Disabled |
Чтобы использовать атрибут Il2CppSetOption:
- В каталоге, где установлена ваша версия Unity, перейдите в каталог Datail2cpp в Windows или в каталог Contents/Frameworks/il2cpp в OS X.
- Найдите исходный файл Il2CppSetOptionAttribute.cs.
- Скопируйте исходный файл в папку Assets вашего проекта.
В приведенном ниже примере показано, как использовать атрибут Il2CppSetOption:
[Il2CppSetOption(Option.NullChecks, false)]
public static string MethodWithNullChecksDisabled()
{
var tmp = new object();
return tmp.ToString();
}
Вы можете применить атрибут Il2CppSetOption к типам, методам и свойствам. Unity использует атрибут из самой локальной области.
[Il2CppSetOption(Option.NullChecks, false)]
public class TypeWithNullChecksDisabled
{
public static string AnyMethod()
{
// Unity doesn’t perform null checks in this method.
var tmp = new object();
return tmp.ToString();
}
[Il2CppSetOption(Option.NullChecks, true)]
public static string MethodWithNullChecksEnabled()
{
// Unity performs null checks in this method.
var tmp = new object();
return tmp.ToString();
}
}
public class SomeType
{
[Il2CppSetOption(Option.NullChecks, false)]
public string PropertyWithNullChecksDisabled
{
get
{
// Unity doesn’t perform null checks here.
var tmp = new object();
return tmp.ToString();
}
set
{
// Unity doesn’t perform null checks here.
value.ToString();
}
}
public string PropertyWithNullChecksDisabledOnGetterOnly
{
[Il2CppSetOption(Option.NullChecks, false)]
get
{
// Unity doesn’t perform null checks here.
var tmp = new object();
return tmp.ToString();
}
set
{
// Unity performs null checks here.
value.ToString();
}
}
}
Unity продолжают совершенствовать технологию IL2CPP, а мы публикуем перевод статьи о том, как она работает.
Около года назад мы писали о будущем скриптинга в Unity. Новая технология скриптинга IL2CPP должна была обеспечить движок высокопроизводительной портативной виртуальной машиной. В январе мы выпустили нашу первую платформу на 64-битной iOS, использующую IL2CPP. С выходом Unity 5 появилась еще одна платформа – WebGL. При поддержке огромного сообщества пользователей мы выпустили множество патчей и обновлений для IL2CPP, постепенно оптимизируя компилятор и повышая быстродействие среды.
А пока мы продолжаем совершенствовать технологию IL2CPP, было бы неплохо рассказать о том, как она работает. Мы планируем написать серию статей, посвященных таким темам:
1. Основы – набор инструментов и аргументы командной строки (эта статья).
2. Экскурсия по генерируемому коду.
3. Советы по отладке генерируемого кода.
4. Вызовы методов: обычные методы, виртуальные методы и другие.
5. Реализация общего обмена.
6. Обёртки P/Invoke для типов и методов.
7. Интеграция сборщика мусора.
8. Тестирование и применение фреймворков.
В этих статьях мы обсудим некоторые особенности реализации IL2CPP. Надеюсь, эта информация вам пригодится.
Что такое IL2CPP?
Технология IL2CPP состоит из двух частей:
• компилятор Ahead-of-time (AOT);
• исполняемая библиотека для поддержки виртуальной машины.
AOT-компилятор переводит промежуточный язык (IL) из .NET-компиляторов в исходный код C++. Исполняемая библиотека предоставляет сервисы и абстракции (такие как сборщик мусора), межплатформенный доступ к потокам и файлам, а также способы реализации внутренних вызовов (неуправляемый код, напрямую изменяющий управляемые структуры данных).
AOT-компилятор
AOT-компилятор IL2CPP называется il2cpp.exe. В Windows его можно найти в директории EditorDatail2cpp, а в OS X – в директории Contents/Frameworks/il2cpp/build в месте установки Unity. Утилита il2cpp.exe полностью написана на языке C# и скомпилирована с помощью .NET и компиляторов Mono.
Эта утилита принимает управляемые сборки, скомпилированные Mono-компилятором, поставляемым с Unity, и генерирует код C++, который мы передаем в компилятор C++ для конкретной платформы.
Инструментарий IL2CPP можно схематически представить так:
Исполняемая библиотека
Вторая часть технологии IL2CPP – это исполняемая библиотека для поддержки виртуальной машины. Мы написали эту библиотеку почти полностью на C++ (в ней есть немного платформенного кода, но пусть это останется между нами) и назвали ее libil2cpp. Она поставляется в виде статической библиотеки, связанной с исполняемым файлом плеера, а ее простота и портативность являются одними из ключевых преимуществ технологии IL2CPP.
Вы можете получить более четкое представление об организации кода libil2cpp, глядя на файлы заголовков, поставляемых с Unity (их можно найти в директории EditorDataPlaybackEngineswebglsupportBuildToolsLibrarieslibil2cppinclude в Windows, или в директории Contents/Frameworks/il2cpp/libil2cpp – в OS X). Например, интерфейс между кодом C++, генерируемым il2cpp.exe, и средой libil2cpp находится в файле заголовка codegen/il2cpp-codegen.h.
Один из ключевых элементов среды – сборщик мусора. В комплект Unity 5 входит libgc, сборщик мусора Boehm-Demers-Weiser. Однако libil2cpp поддерживает и другие сборщики. Например, мы рассматриваем возможность интеграции с Microsoft GC – сборщиком с открытым исходным кодом в комплекте CoreCLR. В одной из следующих статей мы расскажем о нём подробнее.
Как выполняется il2cpp.exe?
Давайте рассмотрим на примере. Для этого я создам новый пустой проект в Unity 5.0.1 на Windows. Чтобы у нас был хотя бы один пользовательский скрипт, я добавлю к главной камере простой компонент MonoBehaviour:
При сборке для платформы WebGL я могу использовать Process Explorer, чтобы увидеть команду для запуска il2cpp.exe:
"C:Program FilesUnityEditorDataMonoBleedingEdgebinmono.exe" "C:Program FilesUnityEditorDatail2cpp/il2cpp.exe" --copy-level=None --enable-generic-sharing --enable-unity-event-support --output-format=Compact --extra-types.file="C:Program FilesUnityEditorDatail2cppil2cpp_default_extra_types.txt" "C:UsersJosh PetersonDocumentsIL2CPP Blog ExampleTempStagingAreaDataManagedAssembly-CSharp.dll" "C:UsersJosh PetersonDocumentsIL2CPP Blog ExampleTempStagingAreaDataManagedUnityEngine.UI.dll" "C:UsersJosh PetersonDocumentsIL2CPP Blog ExampleTempStagingAreaDatail2cppOutput"
Это достаточно длинная строка, поэтому давайте разберем ее по частям. Сперва Unity запускает этот исполняемый файл:
«C:Program FilesUnityEditorDataMonoBleedingEdgebinmono.exe»
Следующий аргумент – сама утилита il2cpp.exe.
«C:Program FilesUnityEditorDatail2cpp/il2cpp.exe»
Остальные аргументы передаются il2cpp.exe, а не mono.exe. Давайте разберем и их. Во-первых, Unity передает 5 флагов il2cpp.exe:
• -copy-level=None
Указывает, что il2cpp.exe не следует выполнять специальные копии файлов генерируемого кода C++.
• -enable-generic-sharing
Уменьшает размер кода и бинарного файла. Со временем мы опубликуем процесс выполнения универсальных методов в IL2CPP.
• -enable-unity-event-support
Обеспечивает корректную генерацию кода для событий Unity, вызываемых при помощи рефлексии.
• -output-format=Compact
Генерирует код C++ в формате с меньшим количеством символов для имен типов и методов. Учитывая, что имена на промежуточном языке не сохраняются, такой код сложнее отлаживать, но зато он быстрее компилируется, поскольку компилятору C++ нужно разобрать меньше кода.
• -extra-types.file=»C:Program FilesUnityEditorDatail2cppil2cpp_default_extra_types.txt»
Использует стандартный пустой файл для дополнительных типов. Его можно добавить в проект Unity, чтобы il2cpp.exe знал, какие универсальные или индексируемые типы создаются во время выполнения, но не указаны в коде IL.
Стоит отметить, что этот набор аргументов командной строки для il2cpp.exe всё еще нестабилен и, скорее всего, изменится в последующих версиях.
Итак, в командной строке указаны 2 файла и 1 директория:
• «C:UsersJosh PetersonDocumentsIL2CPP Blog ExampleTempStagingAreaDataManagedAssembly-CSharp.dll»
• «C:UsersJosh PetersonDocumentsIL2CPP Blog ExampleTempStagingAreaDataManagedUnityEngine.UI.dll»
• «C:UsersJosh PetersonDocumentsIL2CPP Blog ExampleTempStagingAreaDatail2cppOutput»
Утилита il2cpp.exe принимает список всех сборок IL, подлежащих конвертации. В нашем случае сюда входит мой простой скрипт MonoBehaviour, Assembly-CSharp.dll и UnityEngine.UI.dll. Обратите внимание, что здесь явно отсутствует несколько сборок. Очевидно, что мой скрипт ссылается на UnityEngine.dll, а значит нужен хотя бы mscorlib.dll, и, возможно, другие сборки. Но где они? Дело в том, что разрешение сборок происходит внутри il2cpp.exe. Их можно упомянуть в командной строке, но это необязательно. Получается, Unity нужно всего лишь указать корневые сборки (на которые не ссылаются другие сборки).
Последний аргумент командной строки il2cpp.exe – каталог, в котором создаются файлы C++. Если вам интересно, вы можете сами ознакомиться со сгенерированными файлами, но мы еще поговорим о них подробнее в следующей статье. Прежде чем открыть каталог, вам стоит выбрать опцию Development Player в настройках сборки WebGL. Это удалит аргумент -output-format=Compact и улучшит отображение имен типов и методов в коде C++.
Попробуйте поиграть с настройками Player Settings WebGL или iOS. Вы увидите различные параметры командной строки, передаваемые il2cpp.exe и отвечающие за различные этапы генерации кода. Например, задав параметру Enable Exceptions в WebGL Player Settings значение Full, вы добавите в командную строку аргументы -emit-null-checks, -enable-stacktrace и -enable-array-bounds-check.
Чего не делает IL2CPP?
Хотелось бы обратить внимание на одну сложность, которую мы решили обойти стороной и таким образом избежали многих проблем. Мы не пытались переписать стандартную библиотеку C# под IL2CPP. При создании проекта Unity с использованием IL2CPP весь код стандартных библиотек C# (mscorlib.dll, System.dll и т. д.) является точной копией кода Mono-скриптов.
Мы используем код стандартных библиотек C#, потому что он уже успел хорошо зарекомендовать себя во многих проектах. Таким образом, если где-то возникает ошибка, мы можем быть уверены, что проблема в AOT-компиляторе или исполняемой библиотеке.
Разработка, тестирование и выпуск IL2CPP
С момента первого официального релиза IL2CPP версии 4.6.1p5 в январе мы выпустили 6 полноценных обновлений и 7 патчей (для Unity 4.6 и 5.0), в которых исправили более ста ошибок.
Чтобы обеспечить непрерывную оптимизацию, мы разрабатываем обновления на базе одной версии кода. Перед каждым релизом мы передаем все изменения в конкретную релизную ветку, проводим тестирование и проверяем, все ли ошибки были успешно исправлены. Наши команды QA и Sustained Engineering прикладывают максимум усилий, чтобы разработка велась в таком темпе, и ошибки исправлялись каждую неделю.
Наше сообщество оказало нам бесценную помощь, предоставив множество полезных сообщений об ошибках. Мы очень благодарны пользователям за все отзывы, которые помогают непрерывно улучшать IL2CPP.
Для разработчиков IL2CPP тестирование стоит на первом месте. Мы часто берем за основу технику разработки через тестирование и крайне редко отправляем запросы на включение, если код не был полностью протестирован. Эта стратегия хорошо работает для таких технологий, как IL2CPP, где есть четкие входы и выходы. Это означает, что подавляющее большинство ошибок, с которыми мы сталкиваемся, являются скорее частными случаями, чем неожиданным поведением системы (например, при использовании 64-битного IntPtr в качестве 32-битного индекса массива может произойти вылет с ошибкой компилятора С++). Таким образом, мы можем быстро определять и исправлять любые баги.
При поддержке нашего сообщества мы всё время делаем IL2CPP стабильнее и производительнее.
Продолжение следует
Боюсь, я слишком часто упоминаю о следующих статьях. Просто хочется рассказать очень много, и это не уместить в одном посте. В следующий раз мы покопаемся в коде, генерируемом il2cpp.exe, и поговорим о работе компилятора C++.
Мы не планируем прекращать поддержку и развитие IL2CPP, но мы подумали, что было бы неплохо сделать шаг в сторону и рассказать немного о том, как работает IL2CPP. В течение следующих нескольких месяцев мы планируем написать о следующих темах (возможно. и о других) в серии постов об IL2CPP:
Основы — набор инструментов и аргументы командной строки (этот пост).
- Экскурсия по генерируемому коду.
- Советы по отладке генерируемого кода.
- Вызовы методов (обычные методы, виртуальные методы, и т.д.).
- Реализация общего обмена.
- Обертки P/вызова для типов и методов.
- Интеграция сборщика мусора.
- Тестирование и применение фреймворков.
Мы собираемся обсудить некоторые детали о реализации IL2CPP, что, несомненно, изменится в будущем. Надеюсь, мы все еще можем предоставить некоторую полезную и интересную информацию.
Что такое IL2CPP?
Технология, которую мы называем IL2CPP, состоит из двух отдельных частей:
- Ahead-of-time (AOT) компилятор
- Исполняемая библиотека для поддержки виртуальной машины
AOT компилятор переводит промежуточный язык (IL) из .NET компиляторов в C++ код. Исполняемая библиотека предоставляет инструменты, такие как сборщик мусора, независимый от платформы доступ к потокам и файлам, реализации внутренних вызовов (нативный код, который изменяет управляемые структуры данных напрямую).
AOT компилятор
AOT компилятор IL2CPP называется il2cpp.exe. В Windows вы можете найти его в директории EditorDatail2cpp. На OSX – в директории Contents/Frameworks/il2cpp/build в месте установки Unity. Утилита Il2cpp.exe полностью написана на C#. Мы скомпилировали ее с помощью .NET и Mono компиляторов во время разработки IL2CPP.
Утилита Il2cpp.exe принимает управляемые сборки, собранные с компилятором Mono, который поставляется с Unity, и генерирует C++ код, который мы передаем в C++ компилятор конкретной платформы.
Вы можете думать об инструментах IL2CPP так:
Исполняемая библиотека
Другая часть технологии IL2CPP — это исполняемая библиотека для поддержки виртуальной машины. Мы написали эту библиотеку почти полностью на C++ (он содержит немного платформенного кода, но пусть это останется между нами). Мы назвали ее libil2cpp, она поставляется в статической библиотеке связанной с исполняемым файлом плеера. Одно из ключевых преимуществ технологии IL2CPP — это простая и портативная исполняемая библиотека.
Вы можете найти некоторые подсказки о том, как код libil2cpp организован глядя на файлы заголовков для libil2cpp, которые поставляются с Unity (вы найдете их в директории EditorDataPlaybackEngineswebglsupportBuildToolsLibrarieslibil2cppinclude на Windows, или в Contents/Frameworks/il2cpp/libil2cpp на OSX). Например, интерфейс между генерацией C++ кода il2cpp.exe и libil2cpp находится в файле заголовка codegen/il2cpp-codegen.h.
Один из ключевых элементов — сборщик мусора. Мы поставляем Unity 5 с libgc, сборщиком мусора Boehm-Demers-Weiser. Тем не менее, libil2cpp была разработана, чтобы позволить нам использовать другие сборщики мусора. Например, мы исследуем интеграцию Microsoft GC, который стал с открытым кодом в рамках CoreCLR. Мы расскажем больше об этом позже в нашей статье об интеграции сборщика мусора.
Как выполняется il2cpp.exe?
Давайте рассмотрим на примере. Я буду использовать Unity 5.0.1 на Windows, и я начну с нового проекта. Так что у нас есть один пользовательский скрипт, я добавлю этот простой компонент MonoBehaviour к главной камере в сцене:
[csharp]using UnityEngine;
public class HelloWorld : MonoBehaviour {
void Start () {
Debug.Log(«Hello, IL2CPP!»);
}
}[/csharp]
Когда я соберу проект для WebGL, я могу использовать Process Explorer, чтобы увидеть команду Unity, используемую для запуска il2cpp.exe:
"C:Program FilesUnityEditorDataMonoBleedingEdgebinmono.exe" "C:Program FilesUnityEditorDatail2cpp/il2cpp.exe" --copy-level=None --enable-generic-sharing --enable-unity-event-support --output-format=Compact --extra-types.file="C:Program FilesUnityEditorDatail2cppil2cpp_default_extra_types.txt" "C:UsersJosh PetersonDocumentsIL2CPP Blog ExampleTempStagingAreaDataManagedAssembly-CSharp.dll" "C:UsersJosh PetersonDocumentsIL2CPP Blog ExampleTempStagingAreaDataManagedUnityEngine.UI.dll" "C:UsersJosh PetersonDocumentsIL2CPP Blog ExampleTempStagingAreaDatail2cppOutput"
Это строка довольно длинная и страшная, так что давайте разберем ее. Во-первых, Unity запускает этот исполняемый файл:
"C:Program FilesUnityEditorDataMonoBleedingEdgebinmono.exe"
Следующий аргумент — сама утилита il2cpp.exe.
"C:Program FilesUnityEditorDatail2cpp/il2cpp.exe"
Остальные аргументы передаются il2cpp.exe, а не mono.exe. Давайте посмотрим на них. Во-первых, Unity передает пять флагов il2cpp.exe:
- —copy-level=None
- Указывает, что il2cpp.exe не следует выполнять специальные копии файлов генерируемого C++ кода.
- —enable-generic-sharing
- Функция уменьшения размера кода и бинарника. IL2CPP поделятся реализацией генерированных методов, когда это возможно.
- —enable-unity-event-support
- Специальная поддержка кода для событий Unity, доступ к которым осуществляется с помощью рефлексии.
- —output-format=Compact
- Создание C++ кода в формате, который требует меньше символов для имен типов и методов. Этот код трудно отлаживать, поскольку имена в коде IL не сохраняются, но часто компилируется быстрее, так как будет меньше кода для разбора компилятором C++.
- —extra-types.file=»C:Program FilesUnityEditorDatail2cppil2cpp_default_extra_types.txt»
- Использует значение по умолчанию (или пустой) дополнительный файл типов. Этот файл может быть добавлен в проект Unity, чтобы знать, какие il2cpp.exe типы будут созданы во время выполнения, но не присутствуют в коде IL.
Важно отметить, что эти аргументы могут быть и будут изменены в более поздних версиях. Ещё не то время, когда у нас есть стабильный и поддерживаемый набор аргументов для il2cpp.exe.
В итоге у нас есть два файла и одна директория:
- «C:UsersJosh PetersonDocumentsIL2CPP Blog ExampleTempStagingAreaDataManagedAssembly-CSharp.dll»
- «C:UsersJosh PetersonDocumentsIL2CPP Blog ExampleTempStagingAreaDataManagedUnityEngine.UI.dll»
- «C:UsersJosh PetersonDocumentsIL2CPP Blog ExampleTempStagingAreaDatail2cppOutput»
Утилита il2cpp.exe принимает список всех сборок IL, которые следует конвертировать. В нашем случае это сборка, содержащая мой простой скрипт MonoBehaviour, Assembly-CSharp.dll и UnityEngine.UI.dll. Обратите внимание, что здесь есть несколько явно недостающих сборок. Очевидно, что мой скрипт ссылается на UnityEngine.dll, и, по крайней мере необходима mscorlib.dll, и, возможно, другие сборки. Где они? На самом деле, il2cpp.exe определяет эти сборки внутри. Они могут быть упомянуты в командной строке, но это необязательно. Unity явно нужно указать только главные сборки (те, на которые не ссылаются другие сборки).
Последний аргумент в il2cpp.exe — каталог, где должны быть созданы файлы C++. Если вам интересно, посмотрите на сгенерированные файлы в этом каталоге, они будут предметом следующей статьи в этой серии. Прежде чем это сделать, вы, возможно, захотите выбрать опцию «Development Player» в настройках сборки WebGL. Это удалит аргумент –output-format=Compact и даст вам лучшие имена типов и методов в созданном C++ коде.
Попробуйте изменить различные параметры в Player Settings WebGL или iOS. Вы увидите различные аргументы, передаваемые il2cpp.exe включающие различные этапы генерации кода. Например, изменение опции «Enable Exceptions» в Player Settings WebGL на «Full» добавляет аргументы –emit-null-checks, –enable-stacktrace, и –enable-array-bounds-check к вызову il2cpp.exe.
Чего не делает IL2CPP?
Я хотел бы указать на одну из проблем, которые мы не учли в IL2CPP. Мы не пытались переписать стандартную библиотеку C# в IL2CPP. При создании проекта Unity, который использует IL2CPP, весь код стандартных библиотек C# mscorlib.dll, System.dll и т.д. является точно таким же кодом, какой используется для написания скриптов с Mono.
Мы полагаемся на код стандартных библиотек C#, который уже известен пользователям и хорошо проверен в проектах Unity. Поэтому, когда мы исследуем ошибки, связанные с IL2CPP, мы можем быть достаточно уверены, что это ошибка в компиляторе AOT или в исполняемой библиотеки, и нигде больше.
Как мы разрабатываем, тестируем и выпускаем IL2CPP
С момента первоначального публичного релиза IL2CPP в версии 4.6.1p5 в январе, мы выпустили 6 полных релизов и 7 патчей (в разных версиях Unity 4.6 и 5.0). Мы исправили более 100 ошибок, упомянутых в примечаниях к выпуску.
Для того чтобы сделать это процесс совершенствования непрерывным, мы разрабатываем только одну версию кода IL2CPP. Перед каждым выпуском мы портируем изменения IL2CPP для конкретной ветки версий, запускаем наши тесты и проверяем, все ли исправления корректно работают в этой версии. Наши команды QA и Sustained Engineering проделали невероятную работу, чтобы сделать возможным выпуск обновлений так быстро. Это означает, что наши пользователи будут ждать не более одной недели с момента последних исправлений для IL2CPP.
Наше сообщество пользователей, оказалось бесценным, представив множество полезных сообщений об ошибках. Мы ценим все отзывы от наших пользователей, помогающие непрерывно улучшать IL2CPP, и мы с нетерпением ждем больше.
Команда разработчиков работает над IL2CPP имея настрой на сильный тест. Мы часто используем методы Test Driven Design, и редко отправляем запросы на слияние без хороших тестов. Эта стратегия хорошо работает для технологий, таких как IL2CPP, где у нас есть четкие входы и выходы. Это означает, что подавляющее большинство ошибок, которые мы видим, не неожиданное поведение, а неожиданные случаи (например, можно использовать 64-битный IntPtr как 32-битный индекс массива, в результате чего вылет с ошибкой компилятора С++, и в реальном коде на самом деле так делают!). Это различие позволяет нам быстро исправлять ошибки.
С помощью нашего сообщества мы работаем над тем, чтобы IL2CPP работал стабильно и быстро, насколько возможно. Кстати, если это интересно вам, у нас есть вакансия (просто говорю).
Дальше — больше
Боюсь, что я провел слишком много времени здесь, говоря о будущих записях в блоге. Нам многое хочется рассказать, и все это просто не уместятся в одном посте. В следующий раз мы будем копаться в коде, созданном il2cpp.exe, чтобы узнать, как ваш проект на самом деле выглядит для компилятора C++.
Содержание
- Введение в IL2CPP
- IL2CPP Overview
- Building a project using IL2CPP
- How IL2CPP works
- Optimizing IL2CPP build times
- Enabling runtime checks using IL2CppSetOptions
- Universal Windows Platform: IL2CPP scripting back end
- Windows Player: IL2CPP Scripting Backend
- Universal Windows Platform: Plugins on IL2CPP Scripting Backend
- Managed plugins
- Native plugins
- Precompiled native plugins
- C++ source code native plugins
- P/Invoke limitations
- See also
Введение в IL2CPP
Unity продолжают совершенствовать технологию IL2CPP, а мы публикуем перевод статьи о том, как она работает.
Около года назад мы писали о будущем скриптинга в Unity. Новая технология скриптинга IL2CPP должна была обеспечить движок высокопроизводительной портативной виртуальной машиной. В январе мы выпустили нашу первую платформу на 64-битной iOS, использующую IL2CPP. С выходом Unity 5 появилась еще одна платформа – WebGL. При поддержке огромного сообщества пользователей мы выпустили множество патчей и обновлений для IL2CPP, постепенно оптимизируя компилятор и повышая быстродействие среды.
А пока мы продолжаем совершенствовать технологию IL2CPP, было бы неплохо рассказать о том, как она работает. Мы планируем написать серию статей, посвященных таким темам:
1. Основы – набор инструментов и аргументы командной строки (эта статья).
2. Экскурсия по генерируемому коду.
3. Советы по отладке генерируемого кода.
4. Вызовы методов: обычные методы, виртуальные методы и другие.
5. Реализация общего обмена.
6. Обёртки P/Invoke для типов и методов.
7. Интеграция сборщика мусора.
8. Тестирование и применение фреймворков.
В этих статьях мы обсудим некоторые особенности реализации IL2CPP. Надеюсь, эта информация вам пригодится.
Технология IL2CPP состоит из двух частей:
• компилятор Ahead-of-time (AOT);
• исполняемая библиотека для поддержки виртуальной машины.
Эта утилита принимает управляемые сборки, скомпилированные Mono-компилятором, поставляемым с Unity, и генерирует код C++, который мы передаем в компилятор C++ для конкретной платформы.
Инструментарий IL2CPP можно схематически представить так:
Вторая часть технологии IL2CPP – это исполняемая библиотека для поддержки виртуальной машины. Мы написали эту библиотеку почти полностью на C++ (в ней есть немного платформенного кода, но пусть это останется между нами) и назвали ее libil2cpp. Она поставляется в виде статической библиотеки, связанной с исполняемым файлом плеера, а ее простота и портативность являются одними из ключевых преимуществ технологии IL2CPP.
Вы можете получить более четкое представление об организации кода libil2cpp, глядя на файлы заголовков, поставляемых с Unity (их можно найти в директории EditorDataPlaybackEngineswebglsupportBuildToolsLibrarieslibil2cppinclude в Windows, или в директории Contents/Frameworks/il2cpp/libil2cpp – в OS X). Например, интерфейс между кодом C++, генерируемым il2cpp.exe, и средой libil2cpp находится в файле заголовка codegen/il2cpp-codegen.h.
Один из ключевых элементов среды – сборщик мусора. В комплект Unity 5 входит libgc, сборщик мусора Boehm-Demers-Weiser. Однако libil2cpp поддерживает и другие сборщики. Например, мы рассматриваем возможность интеграции с Microsoft GC – сборщиком с открытым исходным кодом в комплекте CoreCLR. В одной из следующих статей мы расскажем о нём подробнее.
Как выполняется il2cpp.exe?
Давайте рассмотрим на примере. Для этого я создам новый пустой проект в Unity 5.0.1 на Windows. Чтобы у нас был хотя бы один пользовательский скрипт, я добавлю к главной камере простой компонент MonoBehaviour:
При сборке для платформы WebGL я могу использовать Process Explorer, чтобы увидеть команду для запуска il2cpp.exe:
Это достаточно длинная строка, поэтому давайте разберем ее по частям. Сперва Unity запускает этот исполняемый файл:
Следующий аргумент – сама утилита il2cpp.exe.
Остальные аргументы передаются il2cpp.exe, а не mono.exe. Давайте разберем и их. Во-первых, Unity передает 5 флагов il2cpp.exe:
Стоит отметить, что этот набор аргументов командной строки для il2cpp.exe всё еще нестабилен и, скорее всего, изменится в последующих версиях.
Итак, в командной строке указаны 2 файла и 1 директория:
• «C:UsersJosh PetersonDocumentsIL2CPP Blog ExampleTempStagingAreaDataManagedAssembly-CSharp.dll»
• «C:UsersJosh PetersonDocumentsIL2CPP Blog ExampleTempStagingAreaDataManagedUnityEngine.UI.dll»
• «C:UsersJosh PetersonDocumentsIL2CPP Blog ExampleTempStagingAreaDatail2cppOutput»
Утилита il2cpp.exe принимает список всех сборок IL, подлежащих конвертации. В нашем случае сюда входит мой простой скрипт MonoBehaviour, Assembly-CSharp.dll и UnityEngine.UI.dll. Обратите внимание, что здесь явно отсутствует несколько сборок. Очевидно, что мой скрипт ссылается на UnityEngine.dll, а значит нужен хотя бы mscorlib.dll, и, возможно, другие сборки. Но где они? Дело в том, что разрешение сборок происходит внутри il2cpp.exe. Их можно упомянуть в командной строке, но это необязательно. Получается, Unity нужно всего лишь указать корневые сборки (на которые не ссылаются другие сборки).
Чего не делает IL2CPP?
Хотелось бы обратить внимание на одну сложность, которую мы решили обойти стороной и таким образом избежали многих проблем. Мы не пытались переписать стандартную библиотеку C# под IL2CPP. При создании проекта Unity с использованием IL2CPP весь код стандартных библиотек C# (mscorlib.dll, System.dll и т. д.) является точной копией кода Mono-скриптов.
Мы используем код стандартных библиотек C#, потому что он уже успел хорошо зарекомендовать себя во многих проектах. Таким образом, если где-то возникает ошибка, мы можем быть уверены, что проблема в AOT-компиляторе или исполняемой библиотеке.
Разработка, тестирование и выпуск IL2CPP
С момента первого официального релиза IL2CPP версии 4.6.1p5 в январе мы выпустили 6 полноценных обновлений и 7 патчей (для Unity 4.6 и 5.0), в которых исправили более ста ошибок.
Чтобы обеспечить непрерывную оптимизацию, мы разрабатываем обновления на базе одной версии кода. Перед каждым релизом мы передаем все изменения в конкретную релизную ветку, проводим тестирование и проверяем, все ли ошибки были успешно исправлены. Наши команды QA и Sustained Engineering прикладывают максимум усилий, чтобы разработка велась в таком темпе, и ошибки исправлялись каждую неделю.
Наше сообщество оказало нам бесценную помощь, предоставив множество полезных сообщений об ошибках. Мы очень благодарны пользователям за все отзывы, которые помогают непрерывно улучшать IL2CPP.
Для разработчиков IL2CPP тестирование стоит на первом месте. Мы часто берем за основу технику разработки через тестирование и крайне редко отправляем запросы на включение, если код не был полностью протестирован. Эта стратегия хорошо работает для таких технологий, как IL2CPP, где есть четкие входы и выходы. Это означает, что подавляющее большинство ошибок, с которыми мы сталкиваемся, являются скорее частными случаями, чем неожиданным поведением системы (например, при использовании 64-битного IntPtr в качестве 32-битного индекса массива может произойти вылет с ошибкой компилятора С++). Таким образом, мы можем быстро определять и исправлять любые баги.
При поддержке нашего сообщества мы всё время делаем IL2CPP стабильнее и производительнее.
Источник
IL2CPP Overview
This type of compilation, in which Unity compiles code specifically for a target platform when it builds the native binary, is called ahead-of-time (AOT) compilation. The Mono backend compiles code at runtime, with a technique called just-in-time compilation (JIT). For more information, see Mono overview.
IL2CPP can improve performance across a variety of platforms, but the need to include machine code in built applications increases both the build time and the size of the final built application. For more information, see How IL2CPP works and the blog series An introduction to IL2CPP internals.
IL2CPP supports the debugging of managed code in the same way as the Mono scripting backend. For more information, see Debugging C# code in Unity.
Building a project using IL2CPP
To build a project with IL2CPP, you need to have the backend installed in your Unity installation. You can select IL2CPP as an optional module when you first install a version of Unity, or add IL2CPP support to an existing installation through the Unity Hub. For more information, see Installing the Unity Hub and Adding modules to the Unity Editor.
You can change the scripting backend Unity uses to build your application in one of two ways:
Through the Player Settings Settings that let you set various player-specific options for the final game built by Unity. More info
See in Glossary menu in the Editor. Perform the following steps to change the scripting backend through the Player Settings menu:
You can also open the Player Settings menu from inside the Build Settings menu; go to File > Build Settings and click on the Player Settings button.
Through the Editor scripting API. Use the PlayerSettings.SetScriptingBackend property to change the scripting backend that Unity uses.
The Configuration section of the Player settings
How IL2CPP works
When you start a build using IL2CPP, Unity automatically performs the following steps:
IL2CPP enables Unity to pre-compile code for specific platforms. The binary file Unity produces at the end of this process already contains necessary machine code for the target platform, while Mono has to compile this machine code at runtime during execution. AOT compilation does increase build time, but it also improves compatibility with the target platform and can improve performance.
Both scripting backends require a new build for each platform you want to target. For example, to support both the Android and iOS Apple’s mobile operating system. More info
See in Glossary platforms, you need to build your application twice and produce two binary files.
The assembly stripping stage helps reduce the final binary size. Unity removes any bytecode that the final built application doesn’t use.
Optimizing IL2CPP build times
Project build times when using IL2CPP can be significantly longer than when using Mono. However, you can do several things to reduce build time.
Exclude your project from anti-malware software scans
You can exclude your Unity project folder and target build folders from anti-malware software scans before you build your project.
Store your project and target build folder on a solid-state drive (SSD)
Solid-state drives (SSDs) have faster read/write speeds than traditional hard disk drives (HDD). Converting IL code to C++ and compiling it involves a large number of read/write operations, so a faster storage device speeds up this process.
Enabling runtime checks using IL2CppSetOptions
When you use the IL2CPP scripting backend, you can control how il2cpp.exe generates C++ code. You can use the Il2CppSetOptions attribute to enable or disable the following runtime checks:
Property: | Description: | Default: |
---|---|---|
Null checks | If this option is enabled, the C++ code that IL2CPP generates contains null checks and throws managed NullReferenceException exceptions as necessary. If this option is disabled, IL2CPP doesn’t emit the null checks into the generated C++ code. For some projects, disabling this option might improve runtime performance.
When this setting is disabled, Unity doesn’t prevent attempts to access null values in the generated code, which might lead to incorrect behavior. Your application is likely to crash soon after it dereferences the null value. Unity recommends that you don’t disable this option. |
Enabled |
Array bounds checks | DIf this option is enabled, the C++ code that IL2CPP generates contains array bounds checks and throws managed IndexOutOfRangeException exceptions as necessary. If this option is disabled, IL2CPP doesn’t emit the array bounds checks into the generated C++ code.
For some projects, disabling this option might improve runtime performance. However, when this option is disabled, Unity doesn’t prevent attempts to access an array with invalid indices in the generated code, which might lead to incorrect behavior, including reading from or writing to arbitrary memory locations. In most cases, these memory accesses occur without any immediate side effects, and can corrupt the state of the application with no obvious warning signs. This can make debugging these errors extremely difficult. Unity recommends that you keep this option enabled. |
Enabled |
Divide by zero checks | If this option is enabled, C++ code generated by IL2CPP contains divide by zero checks for integer division and throw managed DivideByZeroException exceptions as necessary. If this option is disabled, IL2CPP doesn’t emit the divide by zero checks on integer division into the generated C++ code.
These checks have an impact on performance at runtime. You should only enable this option if you need to run divide by zero checks; otherwise, leave it disabled. |
Disabled |
To use the Il2CppSetOptions attribute:
The below example describes how to use the Il2CppSetOption attribute:
You can apply Il2CppSetOptions attribute to types, methods, and properties. Unity uses the attribute from the most local scope.
Источник
Universal Windows Platform: IL2CPP scripting back end
• 2017–05–16 Page amended with no editorial review
Did you find this page useful? Please give it a rating:
Thanks for rating this page!
What kind of problem would you like to report?
Is something described here not working as you expect it to? It might be a Known Issue. Please check with the Issue Tracker at issuetracker.unity3d.com.
Thanks for letting us know! This page has been marked for review based on your feedback.
If you have time, you can provide more information to help us fix the problem faster.
You’ve told us this page needs code samples. If you’d like to help us further, you could provide a code sample, or tell us about what kind of code sample you’d like to see:
You’ve told us there are code samples on this page which don’t work. If you know how to fix it, or have something better we could use instead, please let us know:
You’ve told us there is information missing from this page. Please tell us more about what’s missing:
You’ve told us there is incorrect information on this page. If you know what we should change to make it correct, please tell us:
You’ve told us this page has unclear or confusing information. Please tell us more about what you found unclear or confusing, or let us know how we could make it clearer:
You’ve told us there is a spelling or grammar error on this page. Please tell us what’s wrong:
You’ve told us this page has a problem. Please tell us more about what’s wrong:
Thanks for helping to make the Unity documentation better!
Источник
Windows Player: IL2CPP Scripting Backend
When you build a Project using IL2CPP, Unity converts IL code from scripts A piece of code that allows you to create your own Components, trigger game events, modify Component properties over time and respond to user input in any way you like. More info
See in Glossary and assemblies to C++ before creating a native binary. See IL2CPP A Unity-developed scripting back-end which you can use as an alternative to Mono when building Projects for some platforms. More info
See in Glossary for more information.
• 2018–03–13 Page published with editorial review
New feature in 2018.1 NewIn20181
Did you find this page useful? Please give it a rating:
Thanks for rating this page!
What kind of problem would you like to report?
Is something described here not working as you expect it to? It might be a Known Issue. Please check with the Issue Tracker at issuetracker.unity3d.com.
Thanks for letting us know! This page has been marked for review based on your feedback.
If you have time, you can provide more information to help us fix the problem faster.
You’ve told us this page needs code samples. If you’d like to help us further, you could provide a code sample, or tell us about what kind of code sample you’d like to see:
You’ve told us there are code samples on this page which don’t work. If you know how to fix it, or have something better we could use instead, please let us know:
You’ve told us there is information missing from this page. Please tell us more about what’s missing:
You’ve told us there is incorrect information on this page. If you know what we should change to make it correct, please tell us:
You’ve told us this page has unclear or confusing information. Please tell us more about what you found unclear or confusing, or let us know how we could make it clearer:
You’ve told us there is a spelling or grammar error on this page. Please tell us what’s wrong:
You’ve told us this page has a problem. Please tell us more about what’s wrong:
Thanks for helping to make the Unity documentation better!
Источник
Universal Windows Platform: Plugins on IL2CPP Scripting Backend
The plugin model for Universal Windows Platform An IAP feature that supports Microsoft’s In App Purchase simulator, which allows you to test IAP purchase flows on devices before publishing your application. More info
See in Glossary is similar to other Unity platforms (such as Windows standalone).
Managed plugins
Native plugins
IL2CPP scripting backend supports using native plugins through P/Invoke mechanism. It means that you can call into native plugins directly from your C# code by specifying the native function prototype and then calling it. For example:
The implementation of such function inside MyPlugin.dll would look like this:
Native plugins can be authored in two ways: precompiled DLL or C++ source code.
Precompiled native plugins
P/Invoking into precompiled native plugins works by loading the DLL at runtime, finding the function entry point and then calling it. These DLLs must be compiled against appropriate Windows SDK for the target CPU architecture. The DLLs must also be configured in Plugin Inspector A Unity window that displays information about the currently selected GameObject, asset or project settings, allowing you to inspect and edit the values. More info
See in Glossary when added to Unity project.
C++ source code native plugins
It is possible to add C++ (.cpp) code files directly into Unity project, which will act as a plugin in Plugin Inspector. If configured to be compatible with Universal Windows Platform and IL2CPP scriping backend, these C++ files will be compiled together with C++ code that gets generated from managed assemblies:
Since the functions are linked together with generated C++ code, there is no separate DLL to P/Invoke into. Due to this, it’s possible to use “__Internal” keyword in place of DLL name, which will make it C++ Linker responsibility to resolve the functions, rather than loading them at runtime:
Since the call is resolved by the linker, making an error in function declaration on managed side will produce a linker error, rather an error at runtime. This also means that no dynamic loading needs to take place at runtime, and function is called directly. This significantly decreases the overhead of a P/Invoke call.
P/Invoke limitations
On Universal Windows Platform you cannot P/Invoke into specific system libraries by specifying the dll name (like “kernelbase.dll”) when using IL2CPP scripting backend. Attempting to P/Invoke into any DLL that exists outside of the project will result in DllNotFoundException at runtime.
However, it’s still possible to P/Invoke into these system functions by specifying “**Internal” keyword instead of the DLL name, which results in linker resolving the functions at build time.
See also
Источник
Building a project using IL2CPP
IL2CPP (Intermediate Language To C++) is a Unity-developed scripting backendA framework that powers scripting in Unity. Unity supports three different scripting backends depending on target platform: Mono, .NET and IL2CPP. Universal Windows Platform, however, supports only two: .NET and IL2CPP. More info
See in Glossary which you can use as an alternative to Mono when building projects for various platforms. When building a project using IL2CPP, Unity converts IL code from scriptsA piece of code that allows you to create your own Components, trigger game events, modify Component properties over time and respond to user input in any way you like. More info
See in Glossary and assemblies to C++, before creating a native binary file (.exe, apk, .xap, for example) for your chosen platform. Some of the uses for IL2CPP include increasing the performance, security, and platform compatibility of your Unity projects.
For more information about using IL2CPP, refer to the The Unity IL2CPP blog series and the following Unity Manual pages.
- Building a project using IL2CPP
- How IL2CPP works
- Optimising IL2CPP build times
See the Scripting Restrictions page for details about which platforms support IL2CPP.
IL2CPP supports debugging of managed code in the same way as the Mono scripting backend.
• 2018–05–15 Page amended with limited editorial review
Did you find this page useful? Please give it a rating:
Building a project using IL2CPP
Введение
Сериал будет разделен на следующие части:
1. Обзор (эта статья)
2. Анализ кода C ++
3. Отладка кода C ++.
4. Вызов метода (общий метод, виртуальный метод и т. Д.)
5. Общий доступ
6. P / invoke инкапсуляция типов и методов
7. Сборка мусора
8. Структура тестирования и использование
Что такое IL2CPP
IL2CPP — это новый бэкэнд-метод сценариев, предложенный Unity начиная с версии 4.6.1p5. Он обеспечивает Unity более эффективной и портативной виртуальной машиной. IL2CPP разделен на две независимые части:
- Компилятор AOT (статическая компиляция)
- Библиотека времени исполнения
Компилятор AOT преобразует IL (промежуточный язык, выводимый компилятором .Net) в исходный код C ++, а библиотека времени выполнения предоставляет, например,Сборка мусора, сбор потоков / файлов (независимо и независимо от платформы), внутренние вызовы напрямую изменяют собственный код управляемой структуры данныхСервис и абстракция.
Компилятор AOT
Так называемый редактор AOT — этоil2cpp.exe
В Windows вы можете найти его в каталоге Editor Data il2cpp,
В OSX вы можете найти его в Contents / Frameworks / il2cpp / build, который является установочным каталогом Unity.
il2cpp.exe — это управляемая исполняемая программа, написанная на C #. Она принимает управляемую сборку, созданную компилятором Mono в Unity, и генерирует код C ++ на указанной платформе.
Цепочка инструментов IL2CPP показана ниже:
il2cpp-toolchain
Библиотека времени исполнения
Другая часть технологии IL2CPP — это библиотека времени выполнения (libil2cpp), которая существует для поддержки работы виртуальной машины IL2CPP. Библиотека времени выполнения почти полностью написана кодом C ++ и связана с конечной исполняемой программой как статическая библиотека. (Стоит отметить, что технология IL2CPP значительно выигрывает от использования libil2cpp, более легкой библиотеки времени выполнения)
Вы можете понять состав кода libil2cpp, посмотрев на его заголовочный файл (каталог в системе Windows — Editor Data PlaybackEngines webglsupport BuildTools Libraries libil2cpp include, а каталог в системе OSX — Contents / Frameworks / il2cpp / libil2cpp) Например, вы можете увидеть интерфейс il2cpp.exe для генерации кода C ++ и интерфейс библиотеки времени выполнения в файле codegen / il2cpp-codegen.h.
Еще одна ключевая функция библиотеки времени выполнения — обеспечить сборку мусора, которая будет подробно обсуждаться в следующих статьях.
Как работает компилятор AOT
Давайте посмотрим на пример (этот пример работает в версии Unity 5.0.1 в системе Windows)
Запустите новый проект и добавьте в основную камеру следующий скрипт:
-
public class HelloWorld : MonoBehaviour
-
Debug.Log(«Hello, IL2CPP!»)
В настоящее время мы публикуем программу на платформе WebGL и используем ее.Process ExplorerИнструмент, чтобы узнать, какая командная строка использовалась Unity для вызова il2cpp.exe:
«C:Program FilesUnityEditorDataMonoBleedingEdgebinmono.exe»
«C:Program FilesUnityEditorDatail2cpp/il2cpp.exe»
—enable-unity-event-support
—extra-types.file=«C:Program FilesUnityEditorDatail2cppil2cpp_default_extra_types.txt»
«C:UsersJosh PetersonDocumentsIL2CPP Blog ExampleTempStagingAreaDataManagedAssembly-CSharp.dll»
«C:UsersJosh PetersonDocumentsIL2CPP Blog ExampleTempStagingAreaDataManagedUnityEngine.UI.dll»
«C:UsersJosh PetersonDocumentsIL2CPP Blog ExampleTempStagingAreaDatail2cppOutput»
Эта командная строка выглядит сложной и пугающей, не волнуйтесь, давайте разберем ее шаг за шагом,
"C:Program FilesUnityEditorDataMonoBleedingEdgebinmono.exe"
Сначала Unity запускает mono.exe
«C:Program FilesUnityEditorDatail2cpp/il2cpp.exe
Затем запустите il2cpp.exe
Остальная часть командной строки передается в il2cpp.exe вместо параметров, передаваемых в mono.exe. Сначала в il2cpp.exe передаются 5 идентификаторов:
–copy-level=None
Скажите il2cpp.exe не копировать сгенерированный код C ++.
–enable-generic-sharing
IL2CPP будет совместно использовать дженерики, чтобы уменьшить окончательный размер пакета.
–enable-unity-event-support
Поддерживайте события Unity, полученные посредством отражения, чтобы гарантировать правильную генерацию кода.
–output-format=Compact
В сгенерированном коде C ++ используйте меньшее количество символов для именования классов и методов, что затруднит отладку кода, потому что название кода IL изменится (примечание автора: оно должно быть похоже на путаницу кода), но Он может быть скомпилирован компилятором быстрее, потому что количество символов, которые компилятор должен проанализировать, уменьшается.
–extra-types.file=”C:Program FilesUnityEditorDatail2cppil2cpp_default_extra_types.txt”
Используйте файл дополнительного типа по умолчанию. Этот файл будет добавлен в ваш проект Unity и сообщит il2cpp.exe, какие универсальные типы или типы массивов не отображаются в коде IL, но будут созданы во время выполнения.
Стоит отметить, что эти командные строки могут измениться в последующих версиях Unity. Наконец, давайте посмотрим на оставшиеся три командные строки.
“C:UsersJosh PetersonDocumentsIL2CPP Blog ExampleTempStagingAreaDataManagedAssembly-CSharp.dll”
“C:UsersJosh PetersonDocumentsIL2CPP Blog ExampleTempStagingAreaDataManagedUnityEngine.UI.dll”
il2cpp.exe принимает все сборки IL, которые должны быть преобразованы, в этом примере он должен содержать моиСкрипт MonoBehaviour、 Assembly-CSharp.dll так же как GUI assembly с участием UnityEngine.UI.dllОчевидно, что в приведенной выше командной строке чего-то не хватает. Мой сценарий ссылается на UnityEngine.dll и mscorlib.dll, но они не включены в указанную выше командную строку. Так где же они? Фактически il2cpp.exe обрабатывает эти сборки внутренне, поэтому они не нужны в приведенной выше командной строке, Unity требуется только явно.Корневая сборка (сборка, на которую не ссылается никакая сборка)Упоминается в командной строке.
“C:UsersJosh PetersonDocumentsIL2CPP Blog ExampleTempStagingAreaDatail2cppOutput”
Последний параметр указывает выходной каталог il2cpp.exe, то есть расположение вывода сгенерированного кода il2cpp.exe. Если вас это интересует, вы можете взглянуть на файлы C ++ в сгенерированном каталоге, и мы также будем следовать этому разделу Подробно это объясняется в статье. Кроме того, если вы хотите просмотреть код в сгенерированном каталоге, рекомендуется выбрать, когда пакет будет выпущен.Development PlayerMode, таким образом он будет удален–output-format=CompactКомандная строка делает ваш код более читабельным.
PS: Вы можете увидеть разницу в командной строке, передаваемой Unity il2cpp.exe, изменив настройки в настройках проигрывателя, например,
Enable ExceptionsУстановить какFull, Тогда командная строка добавит–emit-null-checks、–enable-stacktrace 、 –enable-array-bounds-checkТри предмета.
Что не делал IL2CPP
Официально Unity не переписывает стандартную библиотеку C #, поэтому, когда вы публикуете проект Unity, даже если вы выбираете IL2CPP для генерации кода, все вmscorlib.dll、System.dllКод в стандартной библиотеке будет сгенерирован с использованием Mono2X.
Автор: StalkerME
Ссылка: https://www.jianshu.com/p/7cfcb7b0cfe7
Источник: Краткая книга
Авторские права на короткую книгу принадлежат автору. Для любой формы перепечатки, пожалуйста, свяжитесь с автором для авторизации и укажите источник.