Unity managed code stripping

If the project is large and the amount of code is large, it will not only increase the size of the package and increase the compilation time, but also cause various compilation errors. for example:

ARM64 branch out of range (154869072 max is +/-128MB)

Unity provides a solution called managed code stripping to remove unused or inaccessible code. Managed code stripping removes code from managed assemblies, including assemblies built from C# scripts in projects, assemblies that are part of packages and plug-ins, and assemblies in the .NET Framework.

Unity uses a tool called the Unity linker (Unity linker) to perform static analysis on the code in the project assembly. Static analysis identifies any class, part of a class, function or part of a function that cannot be accessed during execution. This analysis only includes code that exists at build time, since there is no runtime generated code when Unity performs static analysis. The degree of stripping can be controlled using managed stripping levels.

To configure managed code stripping:

Go to Edit > Project Settings > Player.
In Additional Settings, find the Optimization section.
insert image description here

Set the Managed Stripping Level property to the desired value.
The attribute function
Disabled does not remove any code. If using mono, this is the default setting
Minimal only searches for unused code in UnityEngine and .net class libraries. No user-written code will be removed. This setting is the least likely to cause any unexpected runtime behavior if using IL2CPP, which is the default.

Managed Stripping Level level setting

Low Unity searches some user-written assemblies, as well as all UnityEngine and .net libraries for unused code. This setting applies a set of rules that remove some unused code but minimize the possibility of unintended consequences, such as behavior changes for runtime code that uses reflection.
Medium Unity partially searches all assemblies for unreachable code. This setting applies a set of rules that strip more types of code patterns to reduce build size. While Unity doesn't remove all potentially inaccessible code, this setting does increase the risk of undesirable or unexpected behavior changes.
High Unity does an extensive search of all assemblies to find unreachable code. In this setup, Unity prioritizes size reduction over code stability and removes as much code as possible. This search may take longer than at lower stripping levels. Thoroughly test your app, using the [Preserve] attribute and link.xml file carefully, to ensure that the Unity linker does not strip critical code.
Use managed code stripping with care to prevent necessary code from being stripped. We can use Preserve or Link.xml to protect the code.

Preserve:
Preserve can be used to prevent the Unity linker from stripping specific parts of the code. This is helpful if your application generates runtime code that does not exist when Unity performs static analysis; for example, through reflection. Preserves either provide general guidance to the Unity linker as to which code patterns it should not strip, or provide instructions not to strip specific, defined sections of code.

For example:

class Foo
{
    [Preserve]
    public void PreservedMethod(){}
}

Link.xml:
You can also include an .xml file named link.xml in your project to keep a list of a specific assembly or part of an assembly. The xml file must exist in the Assets folder or a subdirectory of the Assets folder in the project, and the markup must be included in the file. The Unity linker considers any assembly, type or member saved in the link.xml file as a root type.

For example:

<!--No "preserve" attribute and no members specified means preserve all members-->
<type fullname="AssemblyName.MethodName"/>

<!--Preserve all fields on a type-->
<type fullname="AssemblyName.MethodName" preserve="fields"/>

<!--Preserve all fields on a type-->
<type fullname="AssemblyName.MethodName" preserve="methods"/>

<!--Preserve the type only-->
<type fullname="AssemblyName.MethodName" preserve="nothing"/>

<!--Preserving only specific members of a type-->
<type fullname="AssemblyName.MethodName">
    
  <!--Fields-->
  <field signature="System.Int32 FieldName" />

  <!--Preserve a field by name rather than signature-->
  <field name="FieldName" />
  
  <!--Methods-->
  <method signature="System.Void MethodName()" />

  <!--Preserve a method with parameters-->
  <method signature="System.Void MethodName(System.Int32,System.String)" />

  <!--Preserve a method by name rather than signature-->
  <method name="MethodName" />

  <!--Properties-->

  <!--Preserve a property, it's backing field (if present), 
      getter, and setter methods-->
  <property signature="System.Int32 PropertyName" />

  <property signature="System.Int32 PropertyName" accessors="all" />

  <!--Preserve a property, it's backing field (if present), and getter method-->
  <property signature="System.Int32 PropertyName" accessors="get" />

  <!--Preserve a property, it's backing field (if present), and setter method-->
  <property signature="System.Int32 PropertyName" accessors="set" />

  <!--Preserve a property by name rather than signature-->
  <property name="PropertyName" />

  <!--Events-->

  <!--Preserve an event, it's backing field (if present), add, and remove methods-->
  <event signature="System.EventHandler EventName" />

  <!--Preserve an event by name rather than signature-->
  <event name="EventName" />

</type>
For details, please refer to the official Unity documentation:

https://docs.unity.cn/cn/current/Manual/ManagedCodeStripping.html
If you have done managed code stripping, but ARM64 branch out of range is still reported on IOS, then you can open the Xcode project and make the following settings:

Set the optimization level to -Os
and set the optimization level of both the main project and the UnityFramework project to -Os

insert image description here

Reposted from: https://www.jianshu.com/p/23ee1a176a90

Guess you like

Origin blog.csdn.net/u011484013/article/details/125396066