IL2CPP ビルド時間の最適化
イベントシステム

IL2CPP を使ったマネージバイトコードストリップ

マネージバイトコードストリップは、マネージアセンブリ (DLL) から使用しないコードを削除します。その処理は、まずルートアセンブリを定義し、それから、静的コード解析を使用してそれらのルートアセンブリが使用するマネージコードを定義します。アクセスできないコードはすべて削除されます。バイトコードストリップがコードを難解にすることは なく、また、使用するコードを変更することも ありません

Unity プレーヤービルドの場合、ルートアセンブリは、スクリプトコード (例えば、Assembly-CSharp.dll) から Unity エディターによってコンパイルされたものです。 スクリプトコードからコンパイルされたアセンブリは削除されませんが、その他のアセンブリ (以下を含む) は削除されます。

  • ユーザーがプロジェクトに加えたアセンブリ
  • Unity エンジンアセンブリ
  • .NET クラスライブラリアセンブリ (例えば mscorlib.dll、System.dll)

マネージバイトコードストリップは、 IL2CPP スクリプティングバックエンドが使用されている場合は常に使用可能です。この場合、Stripping Level オプションは Strip Engine Code という名前の Boolean オプションに替わります。このオプションを有効にすると、 ネイティブの Unity エンジンコードで使用されないモジュールとクラスは削除されます。逆に無効にすると、ネイティブの Unity エンジンコードのモジュールとクラスのすべてが保持されます。

link.xml ファイル (後述) を使用すると、型とフルアセンブリを保持することによって効果的にバイトコードのストリップを無効にすることができます。例えば、System アセンブリがストリップされるのを防ぐため、以下のような link.xml ファイルを使用します。

<linker>
       <assembly fullname="System" preserve="all"/>
</linker>

ヒント

リフレクションを使用するときのストリッピングへの対応

ストリッピングは静的なコード分析に強く依存していて、特に、リフレクションのように動的な機能が使用される場合、効率的に行えないことがあります。そのような場合、どのクラスを対象外とするかの情報をヒントとして渡す必要があります。Unity ではプロジェクト単位のカスタム化されたストリッピングブラックリストが可能です。ブラックリストの使用はいたって簡単です。link.xml ファイルを作成して Assets フォルダー (または、Assets のサブディレクトリ) に置くだけです。link.xml の記載例は以下のとおりです。リストアップされたクラスはストリップされることはありません。

<linker>
       <assembly fullname="System.Web.Services">
               <type fullname="System.Web.Services.Protocols.SoapTypeStubInfo" preserve="all"/>
       </assembly>

       <assembly fullname="System">
               <type fullname="System.Net.Configuration.WebRequestModuleHandler" preserve="all"/>
               <type fullname="System.Net.HttpRequestCreator" preserve="all"/>
               <type fullname="System.Net.FileWebRequestCreator" preserve="all"/>
       </assembly>

       <assembly fullname="mscorlib">
               <type fullname="System.AppDomain" preserve="fields"/>
               <type fullname="System.InvalidOperationException" preserve="fields">
                       <method signature="System.Void .ctor()"/>
               </type>
               <type fullname="System.Object" preserve="nothing">
                      <method name="Finalize"/>
               </type>
       </assembly>
</linker>

プロジェクトは複数の link.xml ファイルを持つことができます。各 link.xml ファイルでは、多数のオプションを指定することができます。 assembly 要素はマネージアセンブリを示し、ネストされたディレクティブを記述します。

type 要素は、特定の型の処理方法を示すのに使用されます。type 要素は assembly の子要素でなければなりません。fullname 属性には、1 つ以上の文字に該当するワイルドカード ‘*’ を使用できます。

preserve 属性は以下の 3 つ値のうち 1 つを取ります。

  • all: 指定した型のすべてを保持します (IL2CPP だけに関しては、指定したアセンブリのすべてを保持します)。
  • fields: 指定した型のフィールドだけを保持します。
  • nothing: 指定した型だけを保持し、そのコンテンツは保持しません。

method 要素は、指定したメソッドを保持するために使用します。method 要素は type 要素の子でなければなりません。method は name (名前) または signature (署名) で指定します。

link.xml ファイルに加え、ソースコード内で C# の [Preserve] 属性を使って、リンカーがそのコードをストリップするのを避けることができます。この属性は link.xml ファイルに対応するエントリーとは少し違う挙動をします。

  • Assembly: アセンブリのすべての型を保持します (各型に [Preserve] 属性があるような挙動)。
  • Type: 型とデフォルトコンストラクターを保持します。
  • Method: メソッドの宣言型、返り値の型、すべての引数の型を保持します。
  • Property, Field, Event: プロパティー、フィールド、イベントの宣言型と返り値の型を保持します。

ストリップされたアセンブリは、プロジェクトの Temp ディレクトリ下の任意のディレクトリに出力されます (正確な場所はターゲットプラットフォームによって異なります)。オリジナルのストリップされていないアセンブリは、ストリップされたアセンブリと同じ場所にある not-stripped ディレクトリで利用可能です。ILSpy のようなツールを使って、ストリップされた、または、されなかったアセンブリを検証し、コードのどの部分が削除されたかを判断することができます。


  • 2017–09–01 限られた 編集レビュー で修正されたページ

  • 2017–05–26 - Unity 5.6 で Unity ユーザーマニュアルのドキュメントのみを更新

  • 2017–09–01 - Unity 2017.1 で C# [Preserve] 属性の使用に関するヒントを追加

IL2CPP ビルド時間の最適化
イベントシステム