Please help for IL2CPP problem

I tried to switch my project with IL2CPP, but it alway failed, is there a specific reason for this?
At the beginning, it outputs below

stdout;
Fatal error in Mono CIL Linker
System.Exception: Error processing method: ‘System.Boolean I18N.Common.ByteEncoding::IsAlwaysNormalized(System.Text.NormalizationForm)’ in assembly: ‘I18N.dll’ —> Mono.Cecil.ResolutionException: Failed to resolve System.Void System.Threading.Monitor::Enter(System.Object,System.Boolean&)
at Mono.Linker.Steps.MarkStep.MarkMethod (Mono.Cecil.MethodReference reference) [0x00000] in :0

So I tried to copy I18N.dll from (Unity.app/Contents/Frameworks/Mono/lib/mono/unity) to Assets folder, after this I tried again

stdout;
IL2CPP error for method ‘System.Void ClassX::Initialize()’ in assembly ‘/Users/XXX/Temp/StagingArea/Data/Managed/Assembly-CSharp.dll’
Additional information: Build a development build for more information. Operation is not valid due to the current state of the object
stderr:
Unhandled Exception: System.InvalidOperationException: Operation is not valid due to the current state of the object
at System.Linq.Enumerable.Single[TypeReference] (IEnumerable1 source, System.Func2 predicate, Fallback fallback) [0x00000] in :0
at System.Linq.Enumerable.Single[TypeReference] (IEnumerable1 source, System.Func2 predicate) [0x00000] in :0
at Unity.IL2CPP.StackAnalysis.StackAnalysis.ComputeType (Unity.IL2CPP.StackAnalysis.Entry entry) [0x00000] in :0
at Unity.IL2CPP.StackAnalysis.StackAnalysis+c__AnonStorey35.<>

I don’t believe that you need to copy the I18N.dll into the Assets folder. I suspect that the second error occurs because the one copied there is not the same version as the one that we should find. The build process should find the correct version itself.

I’m a bit puzzled by the first error though, as System.Threading.Monitor::Enter is certainly there. Which version of Unity are you using? Also, in the iOS Player Settings, what are the values of the “Api Compatibility Level” and “Stripping Level” settings? Thanks.

I am using Unity 4.6.2
Api Compatibility Level: .Net 2.0 Subset
Stripping Level: Strip Byte Code

It works well on Mono(2.x) Scripting Backend, hope we can find a way to make it works.

Maybe try using the API Compatibility level of .Net 2.0 instead of .Net 2.0 Subset. We have a few bug related to stripping with IL2CPP that have manifested only with .Net 2.0 Subset. We’re working on fixes, but this might help you to work around the problem now.

Still same on Unity 4.6.3 with .Net 2.0 configure
stdout;
Fatal error in Mono CIL Linker
System.Exception: Error processing method: ‘System.Boolean I18N.Common.ByteEncoding::IsAlwaysNormalized(System.Text.NormalizationForm)’ in assembly: ‘I18N.dll’ —> Mono.Cecil.ResolutionException: Failed to resolve System.Void System.Threading.Monitor::Enter(System.Object,System.Boolean&)
at Mono.Linker.Steps.MarkStep.MarkMethod (Mono.Cecil.MethodReference reference) [0x00000] in :0
at Mono.Linker.Steps.MarkStep.MarkInstruction (Mono.Cecil.Cil.Instruction instruction) [0x00000] in :0
at Mono.Linker.Steps.MarkStep.MarkMethodBody (Mono.Cecil.Cil.MethodBody body) [0x00000] in :0
at Mono.Linker.Steps.MarkStep.ProcessMethod (Mono.Cecil.MethodDefinition method) [0x00000] in :0
at Mono.Linker.Steps.MarkStep.ProcessQueue () [0x00000] in :0
— End of inner exception stack trace —
at Mono.Linker.Steps.MarkStep.ProcessQueue () [0x00000] in :0
at Mono.Linker.Steps.MarkStep.Process () [0x00000] in :0
at Mono.Linker.Steps.MarkStep.Process (Mono.Linker.LinkContext context) [0x00000] in :0
at Mono.Linker.Pipeline.Process (Mono.Linker.LinkContext context) [0x00000] in :0
at Mono.Linker.Driver.Run () [0x00000] in :0
at Mono.Linker.Driver.RunDriver (Mono.Linker.Driver driver) [0x00000] in :0
stderr:

UnityEngine.Debug:LogError(Object)
UnityEditorInternal.Runner:RunManagedProgram(String, String, String, CompilerOutputParserBase)
UnityEditorInternal.AssemblyStripper:RunAssemblyLinker(IEnumerable1, String&, String&, String, String) UnityEditorInternal.AssemblyStripper:StripAssembliesTo(String, String, String&, String&, String, String, IEnumerable1)
UnityEditorInternal.AssemblyStripper:Strip(String, String, String&, String&, String, String, IEnumerable1) UnityEditorInternal.AssemblyStripper:Strip(String[ ], String[ ], String, String, String&, String&, String, String, IEnumerable1)
UnityEditorInternal.IL2CPPBuilder:RunAssemblyStripper(IEnumerable, String, String[ ], String[ ], String)
UnityEditorInternal.IL2CPPBuilder:StripAssemblies(String[ ], String)
UnityEditorInternal.IL2CPPBuilder:Run()
UnityEditorInternal.IL2CPPUtils:RunIl2Cpp(String, String, IIl2CppPlatformProvider, Action`1, RuntimeClassRegistry)
UnityEditor.HostView:OnGUI()

Since that did not work, can you please submit a bug and include the project that causes this issue? We would like to have a look at it here. Thanks!

I will try to make a minimum version of my project can reproduce the issue.

I have a similar problem with the Linker.

  • Unity 4.6.6p3
  • IL2CPP
  • .NET 2.0 Subset
  • Universal architecture

It works with the full .NET 2.0, but then I get this error.

@CoalCzar

This usually indicates that some assembly in your project was compiled against the .NET 2.0 profile. If it was script code cause this, the script would fail to compile. Does this project build correctly if everything is the same and the scripting backend used is Mono?

I’ll have a look at the other error you referenced as well.

I can build successfully with the .NET 2.0 subset when using the Mono scripting backend, though for a different reason, I have to change the stripping level from Disabled to Strip Byte Code.

@CoalCzar

Thanks for letting me know. I think that this is beginning to make some sense. This project builds with the Mono scripting backend and stripping disabled, but not with the Mono scripting backend and the “Strip Byte Code” setting. The problem with “Strip Byte Code” (and IL2CPP, which always does the equivalent of byte code stripping) is that the stripping process requires all of the types used in all assembly to be located. Hence, this problem happens, as some assembly in the project really requires the .NET 2.0 profile.

With the Mono scripting backend and stripping disabled, everything works, even at runtime, because the code in the assembly which requires System.ComponentModel.AddingNewEventHandler to exist is never executed, so the fact that System.ComponentModel.AddingNewEventHandler does not exist in the .NET 2.0 Subset profile does not matter.

I think that we have a few options to correct this issue:

  • The best option is probably to allow the IL2CPP scripting backend to work with stripping disabled. We will discuss that possibility and determine what we can/should do in cases like this. If we decide to allow stripping to be disabled, it won’t be available for a few patch releases, at the earliest (and maybe not at all).
  • In the 4.6.7p1 and 5.1.1p3 patch releases, we will have a new option in the link.xml file to preserve everything in a given assembly, effectively disabling stripping for that assembly. Once this is available, you could manually disable stripping for all assemblies in the project. This is a tedious process for sure, but I think it will work in this case.
  • You could determine which assembly requires the .NET 2.0 profile and remove it or replace with one built against the .NET 2.0 Subset profile (if possible). This is probably the best option, as there is likely a runtime option lurking in this project - if the code which requires the .NET 2.0 profile is ever executed. However, determining which assembly is the culprit may not be easy.

Thanks for your response, though I’m not sure I was clear enough earlier. I can’t actually build with Mono scripting backend and stripping disabled, though I’m not sure it’s related to this specific error. I have to build with some level of stripping (I used to use Strip Byte Code) in order to build. (If that it was you were referencing, I apologize for misreading your post).

I’d like to build to the .NET 2.0 Subset, but I gave up for now because fixing that other bug was easier to fix by simply replacing XML with JSON.

@CoalCzar

Thanks for clarifying, I was unclear before. I think that I understand now though.

I tried to switch my project with IL2CPP, but it alway failed, is there a specific reason for this?
At the beginning, it outputs below

Failed running /Applications/Unity/Unity.app/Contents/Frameworks/Tools/UnusedByteCodeStripper2/UnusedBytecodeStripper2.exe -out “/Users/zhaoye/xlj_main/trunk/main/Temp/StagingArea/Data/Managed” -l none -c link -x “/Applications/Unity/Unity.app/Contents/Frameworks/Tools/UnusedByteCodeStripper/native_link.xml” -f “/Applications/Unity/Unity.app/Contents/Frameworks/il2cpp/LinkerDescriptors” -x “/Users/zhaoye/xlj_main/trunk/main/Temp/StagingArea/Data/Managed/…/platform_native_link.xml” -x “/Users/zhaoye/xlj_main/trunk/main/Temp/StagingArea/Data/methods_pointedto_by_uievents.xml” -d “/Users/zhaoye/xlj_main/trunk/main/Temp/StagingArea/Data/Managed” -a “/Users/zhaoye/xlj_main/trunk/main/Temp/StagingArea/Data/Managed/Assembly-CSharp.dll” -a “/Users/zhaoye/xlj_main/trunk/main/Temp/StagingArea/Data/Managed/Assembly-UnityScript.dll” -a “/Users/zhaoye/xlj_main/trunk/main/Temp/StagingArea/Data/Managed/UnityEngine.UI.dll” -a “/Users/zhaoye/xlj_main/trunk/main/Temp/StagingArea/Data/Managed/CommonLib.dll” -a “/Users/zhaoye/xlj_main/trunk/main/Temp/StagingArea/Data/Managed/Config2.dll” -a “/Users/zhaoye/xlj_main/trunk/main/Temp/StagingArea/Data/Managed/LumenWorks.Framework.IO.dll” -a “/Users/zhaoye/xlj_main/trunk/main/Temp/StagingArea/Data/Managed/Microsoft.QualityTools.Testing.Fakes.dll” -a “/Users/zhaoye/xlj_main/trunk/main/Temp/StagingArea/Data/Managed/ProtoCmd.dll” -a “/Users/zhaoye/xlj_main/trunk/main/Temp/StagingArea/Data/Managed/MatrixWrapper.dll”

stdout:
Fatal error in Mono CIL Linker
System.Exception: Error processing method: ‘System.Void GUIWrapper::GetExternalStorageDirectory()’ in assembly: ‘MatrixWrapper.dll’ —> Mono.Cecil.ResolutionException: Failed to resolve UnityEngine.AndroidJavaClass
at Mono.Linker.Steps.MarkStep.MarkType (Mono.Cecil.TypeReference reference) [0x00000] in :0
at Mono.Linker.Steps.MarkStep.MarkMethodBody (Mono.Cecil.Cil.MethodBody body) [0x00000] in :0
at Mono.Linker.Steps.MarkStep.ProcessMethod (Mono.Cecil.MethodDefinition method) [0x00000] in :0
at Mono.Linker.Steps.MarkStep.ProcessQueue () [0x00000] in :0
— End of inner exception stack trace —
at Mono.Linker.Steps.MarkStep.ProcessQueue () [0x00000] in :0
at Mono.Linker.Steps.MarkStep.Process () [0x00000] in :0
at Mono.Linker.Steps.MarkStep.Process (Mono.Linker.LinkContext context) [0x00000] in :0
at Mono.Linker.Pipeline.Process (Mono.Linker.LinkContext context) [0x00000] in :0
at Mono.Linker.Driver.Run () [0x00000] in :0
at Mono.Linker.Driver.RunDriver (Mono.Linker.Driver driver) [0x00000] in :0
stderr:

UnityEngine.Debug:LogError(Object)
UnityEditorInternal.Runner:RunManagedProgram(String, String, String, CompilerOutputParserBase) (at /Users/builduser/buildslave/unity/build/Editor/Mono/BuildPipeline/Il2Cpp/IL2CPPUtils.cs:66)
UnityEditorInternal.AssemblyStripper:RunAssemblyLinker(IEnumerable1, String&, String&, String, String) (at /Users/builduser/buildslave/unity/build/Editor/Mono/BuildPipeline/Il2Cpp/IL2CPPUtils.cs:192) UnityEditorInternal.AssemblyStripper:StripAssembliesTo(String, String, String&, String&, String, String, IEnumerable1) (at /Users/builduser/buildslave/unity/build/Editor/Mono/BuildPipeline/Il2Cpp/IL2CPPUtils.cs:185)
UnityEditorInternal.AssemblyStripper:Strip(String, String, String&, String&, String, String, IEnumerable1) (at /Users/builduser/buildslave/unity/build/Editor/Mono/BuildPipeline/Il2Cpp/IL2CPPUtils.cs:136) UnityEditorInternal.AssemblyStripper:Strip(String[ ], String[ ], String, String, String&, String&, String, String, IEnumerable1) (at /Users/builduser/buildslave/unity/build/Editor/Mono/BuildPipeline/Il2Cpp/IL2CPPUtils.cs:121)
UnityEditorInternal.IL2CPPBuilder:RunAssemblyStripper(IEnumerable, String, String[ ], String[ ], String) (at /Users/builduser/buildslave/unity/build/Editor/Mono/BuildPipeline/Il2Cpp/IL2CPPUtils.cs:445)
UnityEditorInternal.IL2CPPBuilder:StripAssemblies(String[ ], String) (at /Users/builduser/buildslave/unity/build/Editor/Mono/BuildPipeline/Il2Cpp/IL2CPPUtils.cs:433)
UnityEditorInternal.IL2CPPBuilder:Run() (at /Users/builduser/buildslave/unity/build/Editor/Mono/BuildPipeline/Il2Cpp/IL2CPPUtils.cs:273)
UnityEditorInternal.IL2CPPUtils:RunIl2Cpp(String, String, IIl2CppPlatformProvider, Action`1, RuntimeClassRegistry) (at /Users/builduser/buildslave/unity/build/Editor/Mono/BuildPipeline/Il2Cpp/IL2CPPUtils.cs:211)
UnityEditor.HostView:OnGUI()

@zzpzzp

This error indicates a problem with assembly stripping. It looks like the assembly MatrixWrapper.dll has a method named GUIWrapper::GetExternalStorageDirectory, and that method references UnityEngine.AndroidJavaClass, but UnityEngine.AndroidJavaClass cannot be found.

This may be indicative of a problem in assembly references, although I’m not sure. You could disable stripping for the MatrixWrapper.dll assembly by adding a link.xml file which looks like this:

You can find more details about link.xml here: http://docs.unity3d.com/Manual/iphone-playerSizeOptimization.html

Thank you for your advice, I carefully find the reason to give you feedback under