Skip to content
This repository has been archived by the owner on Oct 6, 2023. It is now read-only.

Reference link.xml

Kalle Jillheden edited this page Jan 10, 2021 · 1 revision

To quote Unity docs on Bytecode Stripping:

Managed bytecode stripping removes unused code from managed assemblies (DLLs). The process works by defining root assemblies, then using static code analysis to determine what other managed code those root assemblies use. Any code that is not reachable is removed. /.../

For a given Unity player build, the root assemblies are those compiled by the Unity Editor from script code (for example, Assembly-CSharp.dll). Any assemblies compiled from script code will not be stripped, but other assemblies will. This includes:

  • Assemblies you add to a project
  • Unity Engine assemblies
  • .NET class library assemblies (e.g mscorlib.dll, System.dll)

Managed bytecode stripping is always enabled when the IL2CPP scripting backend is used. /.../

The link.xml file (described below) can be used to effectively disable bytecode stripping by preserving both types and full assemblies. For example, to prevent the System assembly from being stripped, the following link.xml file can be used:

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

This page includes a full reference list of how to use link.xml for all the different possible scenarios, that's not necessarily written in the Unity docs.

Table of contents

Where to place the link.xml

↑ Back to table of contents.

✔ Where Unity linker DOES looks for link.xml files

  • Assets/ folder
  • Any subdirectory of the Assets/ folder
  • Any subdirectory within an embedded package inside then Packages/ folder
  • Any embedded resource in assemblies that has the same as the assembly, but with the extension .xml

❌ Where Unity linker DOES NOT look for link.xml files

  • Project root
  • Any subdirectory except Assets/
  • Referenced packages added via UPM. I.e. all packages that are saved in Library/PackageCache/\*

Xml elements

The <linker> element

Element name linker
Child of -none, the linker element must be the root element-
Parent of assembly
Attributes -none-

The <assembly> element

↑ Back to table of contents.

Element name assembly
Child of linker
Parent of type
Attributes ignoreIfMissing, ignoreIfUnreferenced, preserve, windowsruntime
  • <assembly fullname>

    Name of assembly, or strong name of assembly. When using assembly definitions (.asmdef) the "Name" field in the inspector will be the assembly name and can therefore be used.

    To easily acquire a strong name from a type you can use this in PowerShell:

    # Acquire form a .dll file
    $dll = "C:/path/to/your/assembly.dll"
    [System.Reflection.AssemblyName]::GetAssemblyName($dll).FullName
    
    # Acquire from an already loaded type
    $type = [System.DateTime]
    $type.Assembly.GetName().FullName

    Supports wildcards (*). See the Wildcards section for more info.

  • <assembly preserve>

    Values: "all", "fields", "nothing"
    Default: "all" if element has no children, "nothing" otherwise.

    • all — Keep everything from the given type (or assembly, for IL2CPP only).
    • fields — Keep only the fields of the given type.
    • nothing — Keep only the given type, but none of its contents. Forces the assembly to be processed for roots but don’t explicitly preserve anything in particular. Useful when the assembly is not referenced.
  • <assembly ignoreIfMissing>

    Values: "true", "false"
    Default: "false"

    The Unity docs specifies that:

    By default, the UnityLinker aborts the build if an assembly referenced in a link.xml file cannot be found. If you need to declare preservations for an assembly that does not exist during all Player builds, use the ignoreIfMissing attribute on the <assembly> element in the link.xml file /.../

    However, in practice the UnityLinker has shown to not throw no matter if including or omitting this attribute.

  • <assembly ignoreIfUnreferenced>

    Values: "true", "false"
    Default: "false"

    In some cases, you might want to preserve entities in an assembly only when that assembly is referenced by another assembly. Use the ignoreIfUnreferenced attribute on the <assembly> element in the link.xml file to only preserve the entities in an assembly when at least one type is referenced in an assembly. /.../

    Note: It does not matter whether the code in the referencing assembly was itself stripped or not, the specified elements of the referenced assembly with this attribute are still preserved.

  • <assembly windowsruntime>

    Values: "true", "false"
    Default: "false"

    When defining preservations for a Windows Runtime Metadata (.winmd) assembly, you must add the windowsruntime="true" attribute to the element in the link.xml file:

Example using assembly name

<linker>
    <assembly fullname="MyAssemblyDefinition" preserve="all"/>
    <assembly fullname="mscorlib" preserve="all"/>
</linker>

Example using assembly strong name

<linker>
    <assembly fullname="MyAssemblyDefinition, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null" preserve="all"/>
    <assembly fullname="mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" preserve="all"/>
</linker>

The <type> element

↑ Back to table of contents.

Element name type
Child of assembly
Parent of event, field, method, property
Attributes feature, fullname
  • <type fullname>

    Name of target fullname, including namespace.

    Supports wildcards (*). See the Wildcards section for more info.

  • <type preserve>

    Values: "all", "fields", "nothing"
    Default: "all" if element has no children, "nothing" otherwise.

    • all — Keep everything from the given type (or assembly, for IL2CPP only).
    • fields — Keep only the fields of the given type.
    • nothing — Keep only the given type, but none of its contents.
  • <type feature>

    Values: "remoting", "sre", "com"
    Default: -none-

    During High level stripping, the UnityLinker excludes preservations for features that are not supported based on the settings for the current build:

    • remoting — Excluded when targeting the IL2CPP scripting backend.
    • sre — Excluded when targeting the IL2CPP scripting backend.
    • com — Excluded when targeting platforms that do not support COM.

The <event> element

↑ Back to table of contents.

Element name event
Child of type
Parent of -none-
Attributes feature, name, signature
  • <event signature>

    Can be used instead of the name attribute to specify target event.

    Signature follows the format {event type} {event name}

    • "event type" — full name of the event type. Note that C# keywords (such as int) can not be used, but instead the full name of the type must be used (such as System.Int32).
    • "event name" — name of the event member.
  • <event name>

    Name of target event, including namespace.

    Can be used instead of the signature attribute to specify target event.

  • <event feature>

    Values: "remoting", "sre", "com"
    Default: -none-

    During High level stripping, the UnityLinker excludes preservations for features that are not supported based on the settings for the current build:

    • remoting — Excluded when targeting the IL2CPP scripting backend.
    • sre — Excluded when targeting the IL2CPP scripting backend.
    • com — Excluded when targeting platforms that do not support COM.

Example

using System;

namespace MyNamespace {
    public class EventExample {
        public delegate void MyEventHandler();

        public event EventHandler MyEvent1;
        public event MyEventHandler MyEvent2;
        public event EventHandler<EventArgs> MyEvent3;
    }
}
<linker>
    <assembly fullname="MyNamespace">
        <type fullname="MyNamespace.EventExample">
            <event name="MyEvent1" />
            <event signature="MyNamespace.MyEventHandler MyEvent2" />
            <!-- The < and > characters must be escaped as &lt; and &gt; -->
            <event signature="System.EventHandler`1&lt;System.EventArgs&gt; MyEvent3" />
        </type>
    </assembly>
</linker>

The <field> element

↑ Back to table of contents.

Element name field
Child of type
Parent of -none-
Attributes feature, name, signature
  • <field signature>

    Can be used instead of the name attribute to specify target field.

    Signature follows the format {field type} {field name}

    • "field type" — full name of the field type. Note that C# keywords (such as int) can not be used, but instead the full name of the type must be used (such as System.Int32).
    • "field name" — name of the field member.
  • <field name>

    Name of target field, including namespace.

    Can be used instead of the signature attribute to specify target field.

  • <field feature>

    Values: "remoting", "sre", "com"
    Default: -none-

    During High level stripping, the UnityLinker excludes preservations for features that are not supported based on the settings for the current build:

    • remoting — Excluded when targeting the IL2CPP scripting backend.
    • sre — Excluded when targeting the IL2CPP scripting backend.
    • com — Excluded when targeting platforms that do not support COM.

Example

using System.Collections.Generic;

namespace MyNamespace {
    public class FieldExample {
        public string MyField1;
        public string[] MyField2;
        public List<string> MyField3;
    }
}
<linker>
    <assembly fullname="MyNamespace">
        <type fullname="MyNamespace.FieldExample">
            <field name="MyField1" />
            <field signature="System.String[] MyField2" />
            <!-- The < and > characters must be escaped as &lt; and &gt; -->
            <field signature="System.Collections.Generic.List`1&lt;System.String&gt; MyField3" />
        </type>
    </assembly>
</linker>

The <property> element

↑ Back to table of contents.

Element name property
Child of type
Parent of -none-
Attributes accessors, feature, name, signature
  • <property accessors>

    Values: "all", "get", "set"
    Default: "all"

    Marks which of the accessors should be skipped by the stripping process.

    • "set" — preserve the property setter
    • "get" — preserve the property getter
    • "all" — preserve both the property getter and setter, equivalent to having two property elements targeting the same property but one with accessors as "get" and one with "set".
  • <property signature>

    Can be used instead of the name attribute to specify target property.

    Signature follows the format {property type} {property name}

    • "property type" — full name of the property type. Note that C# keywords (such as int) can not be used, but instead the full name of the type must be used (such as System.Int32).
    • "property name" — name of the property member.
  • <property name>

    Name of target property, including namespace.

    Can be used instead of the signature attribute to specify target property.

  • <property feature>

    Values: "remoting", "sre", "com"
    Default: -none-

    During High level stripping, the UnityLinker excludes preservations for features that are not supported based on the settings for the current build:

    • remoting — Excluded when targeting the IL2CPP scripting backend.
    • sre — Excluded when targeting the IL2CPP scripting backend.
    • com — Excluded when targeting platforms that do not support COM.

Example

using System.Collections.Generic;

namespace MyNamespace {
    public class PropertyExample {
        public string MyProperty1 { get; }
        public string[] MyProperty2 { set; }
        public List<string> MyProperty3 { get; set; }
    }
}
<linker>
    <assembly fullname="MyNamespace">
        <type fullname="MyNamespace.PropertyExample">
            <property name="MyProperty1" />
            <property signature="System.String[] MyProperty2" accessors="set" />
            <!-- The < and > characters must be escaped as &lt; and &gt; -->
            <property signature="System.Collections.Generic.List`1&lt;System.String&gt; MyProperty3" accessors="get" />
        </type>
    </assembly>
</linker>

The <method> element

↑ Back to table of contents.

Element name method
Child of type
Parent of -none-
Attributes feature, name, signature
  • <method signature>

    Can be used instead of the name attribute to specify target method.

    Signature follows the format {method type} {method name}({method parameter types})

    • "method type" — full name of the method type. Note that C# keywords (such as int) can not be used, but instead the full name of the type must be used (such as System.Int32).
    • "method name" — name of the method member.
    • "method parameter types" — comma separated list (no spaces) of the parameter types. Note that C# keywords (such as int) can not be used, but instead the full name of the type must be used (such as System.Int32).

    Specifying signature instead of name is a great way to distinguish between overloads, especially constructors.

  • <method name>

    Name of target method, including namespace.

    Can be used instead of the signature attribute to specify target method.

  • <method feature>

    Values: "remoting", "sre", "com"
    Default: -none-

    During High level stripping, the UnityLinker excludes preservations for features that are not supported based on the settings for the current build:

    • remoting — Excluded when targeting the IL2CPP scripting backend.
    • sre — Excluded when targeting the IL2CPP scripting backend.
    • com — Excluded when targeting platforms that do not support COM.

Example

using System;
using System.Collections.Generic;
using System.Linq;

namespace MyNamespace {
    public class MethodExample {
        public void MyMethod1()
        {
            MyMethod3(new[] {
                DateTime.Now,
                DateTime.Today
            });
        }

        public bool MyMethod2(int a, int b) {
            return a > b;
        }

        public static List<bool> MyMethod3<T>(T[] values) {
            return values.Select(o => o == 2).ToList();
        }
    }
}
<linker>
    <assembly fullname="MyNamespace">
        <type fullname="MyNamespace.PropertyExample">
            <method name="MyMethod1">
            <method signature="System.Boolean MyMethod2(System.Int32,System.Int32)">
            <!-- The < and > characters must be escaped as &lt; and &gt; -->
            <method signature="System.Collections.Generic.List`1&ltSystem.Boolean;&gt; MyMethod3`1(System.DateTime[])">
        </type>
    </assembly>
</linker>

Tips and tricks

This section has been split up into multiple pages. See the sidebar for what you're searching for.

Clone this wiki locally