Unity iOS linker error: Unable to insert branch island. No insertion point available.

I’ve got a linker error while building our big Unity-based game for iOS:

ld: Unable to insert branch island. No insertion point available. for architecture armv7
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Error occurred in XCode. I’ve researched same issues and found out that it’s because of too large Assembly-CSharp.dll file that is located in “YOUR_XCODE_PROJECT/Data/Managed/Assembly-CSharp.dll”. On our project the limit was empirically determined to be 1.8 MB. I’ve found out that it’s not only because of the assembly size. I’ve created test Unity project with small amount of very big classes. I linked fine for 10 MB Assembly-CSharp.dll and failed for 15MB DLL. Tested on Unity 3.5.7 and 4.3.4, Xcode 4.6.3 and 5.1. So I assume that case also depends on the number of classes (or methods or generics or everything). I want to find out the source of the issue, possibly it’s XCode issue.
There is a kind of workaround - put part of your code into Assets/Plugins folder. Code from Assets/Plugins is built into Assembly-CSharp-firstpass.dll. That workaround could be helpful but not good enough. First of all it allows you only 2 times increase of your code size. Also it doesn’t allow code from Plugins to refer any code from the outside (only other code from Plugins). So it could be suitable for external frameworks that doesn’t depend on your custom code. But Plugins folder has another strict limitation on it’s structure - all the editor scripts that are contained in Plugins should lay in Plugins/Editor and nowhere else. So if external framework has it’s Editor scripts you should move them to Plugins/Editor thereby break the consistency of that framework and make it impossible to store it in separate repository.

1586522–94967–$unity4_proj_unable_to_insert_branch_island.zip (75.4 KB)

Found some usefull information.
First of all, the file “YOUR_XCODE_PROJECT/Data/Managed/Assembly-CSharp.dll” is compressed and even if it’s 1.5 MB, there still can be “Unable to insert branch island” error. The actual size of object file that causes the error could be seen in: ~/Library/Developer/Xcode/DerivedData/Unity-iPhone-XXXXXXXXXXXXXXX/Build/Intermediates/Unity-iPhone.build/Debug-iphoneos/Unity-iPhone.build/Objects-normal/armv7/Assembly-CSharp.dll.o
where XXXXXXXXXXXXXXX - is an XCode-generated hash for your project (for example “brlidjvfeiuonvcahlicvtmanfxh”)
The actual limit is applied to this .dll.o file and it’s about 44 MB.
Here is of items that consumes space in Assembly-CSharp.dll.o

  1. Namespace, class and method names. Each method of each class is presented in this file, and all the class names are full - including full namespace. In my case for 44 MB .o file the size of this block was 8.8 MB. You can of course reduce the names of your classes and namespaces, but it won’t give you much, it’s better to look at the next points.
  2. Statically allocated and initialized data. Entries like:
class MyClass
{
  static int[] _myData = new int[1000] { 23, 231, 168, ... };
}

consumes space in .dll.o file. You can put huge amounts of data into data files instead of source files. In my case there wasn’t any huge amounts of statically initialized data but I’ve created an empty project that was causing “Unable to insert branch island” only because of statically initialized data.
3. Generic types that are parameterized with structs. That was a clue in my case. There was a file ZEnum in our project that was used for enum functionality extension, for example ZEnum.count returned the number of elements in MyEnum. And it was used all over the project with about 30 different enum types used as generic-parameters. Refactoring of ZEnum without generics resulted into reducing of .dll.o file from 44 MB to 18 MB. The size of class and method names section reduced from 8.8 MB to 5.5 MB.

So there’s still no final workaround for the issue, but we know how to make code less space-consuming.

Hi avorobyov,
I just wanted to say thank you for your research; It all makes much sense.
This seems to be an obscure issue, and I have seen some threads with Unity devs also involved.
I have not seen those threads conclude as concisely as you have, kudos!

I have been struggling with the same issues, and this clears up a lot on potential solutions I can try.
Much obliged!

Any more headway on this issue? We just ran into it and are having a hard time figuring out what could be making the dlls so large. We cannot afford to move code to the plugins folder because of the requirement to use SendMessage().

Are there any other solutions to this problem or any more advice on how to avoid it in the future.
Thanks

What’s wrong with SendMessage() and Plugins?

avorobyov, what did you use to look at the contents of your .o file? How did you know that your method/class/namespace names are taking up 8.8MB out of 44MB?

I moved a lot of code into our Plugins folder and now my dlls are well under the 44mb limit but I’m still getting the same linker error. I’m using XCode 5.1.1, how about everyone else?

I’ve used text editor to look at the contents of .o file. Tried to find appropriate .o parser but found nothing. Anyway it’s not hard to find methods mentioning in .o files. In my case method names were duplicated for all the ZEnum classes.
Method/class/namespace names occupies separate section in the .o file - just look at the contents of it and you’ll see what I’m talking about. Name section is located in the end of the .o file. I’ve just found the place where binary data ends and names start and measured it.

Size limit applies not to the dll file, but to dll.o file as dll may compress it’s contents, but linker works with uncompressed data.
I suppose either you have a lot of types (thousands, move them into separate DLL) or a lot of struct genetics (refactor them) or a lot of statically allocated data (move them into files).

Oh, sorry for the misunderstanding. I was in fact referring to the .o files:
http://screencast.com/t/XlmyngOdUi8

Hey jctz, we’re on Xcode 6.1. We get the error when Assembly-CSharp.dll.o is at 31.7 mb. We do not when it is at 31.2 mb.

You can workaround this limitation by moving your code into separate managed assemblies, creating smaller .o object files. You are not just limited by the ones Unity creates when it compiles the script code (Assembly-CSharp.dll, Assembly-CSharp-firstpass.dll, …)

You can use MonoDevelop for this: File → New Solution → C# → Library.
If your code references types from UnityEngine.dll (MonoBehaviours, GameObject, etc), then remember to add the reference to the UnityEngine.dll assembly in the Project.

Is the limit for a single .o file or the combined size of all .o files? As I am having this issue despite the Assembly-CSharp.dll.o and Assembly-CSharp-firstpass.dll.o files been around 20mb each.

just the same problem here, but every thing is ok when unity is 4.5.4 and the Assembly-CSharp.dll.o is 36MB, after i upgrade unity 4.6.2p2 and dont do anything else, the Assembly-CSharp.dll.o is 44MB now, and link error happen, please help me, is that the BUG of Unity 4.6.2p2 ?

Is your code exactly the same? Did you modify the stripping settings? Also, try with the latest version 4.6.4p4.

Actually is the same project, just open by different version unity, and the stripping settings is the same, i ll try 4.6.4p4 later, thanks for ur reply :slight_smile:

Had the same problem over the last couple of days - solved it by unchecking Script Debugging in the build settings

1 Like

Cool, and what if I do need to have script debugging enabled?

this bug has fixed in 4.6.4f1

installed 4.6.5f1 and still have this problem when debug is enable