Unity LLVM Out Of Memory

Unity LLVM Out Of Memory
Photo by Denny Müller / Unsplash

Good news!

Unity just launched an update to the DevOps dashboard that now has two distinct toggle buttons to enable development builds and/or script debugging, yay! So no more POST requests are needed.

Updated DevOps toggles

Old Post

TL;DR - Solution

In recent versions of Unity due to some limitations of Android NDK it can eventually happen that any Android build breaks. The reason seems to be that the script size is too big after/during LLVM compilation.

Unfortunately, the real fix will land in Unity 2022.2. If you're currently starting a new project, using a tech version of Unity may suit you, but if you're in production or close to production, updating to a tech version is not a good idea.

Good thing: the error seems only to happen in development build with Script Debugging turned on.

So the workaround is to create development builds without Script Debugging or use Mono backend if you want to debug something on the device.

And yes, having Script Debugging turned off depends on your situation if you need to debug on the device or not.

For me, I run all-important builds on Unity Cloud Build. For those builds, I'm not interested in debugging them (except reading some logs), so I can happily turn off script debugging to fix the error.

If I need to debug, I switch the scripting backend back to Mono and deploy to the device directly.

Turn off Script Debugging in the Editor

Build & Run Dialog

Open the "Build & Run" dialog and then turn off script debugging.

Turn off Script Debugging via Code

Because I use Unity Cloud Build for our game Bug-A-Ball, I can not use the Editor dialog, so I tried turning it off via code like this:

#if UNITY_ANDROID
using UnityEditor;
using UnityEditor.Build;
using UnityEditor.Build.Reporting;
using UnityEngine;

namespace BoundfoxStudios.BugABall.Editor.Build.Android
{
  // We currently need to turn this off due to an issue with Android NDK.
  // That will be fixed with 2022.2... :)
  public class AndroidTurnOffScriptDebugging : IPreprocessBuildWithReport
  {
    public int callbackOrder => 0;
    public void OnPreprocessBuild(BuildReport report)
    {
      if (report.summary.platform != BuildTarget.Android)
      {
        return;
      }

      Debug.Log("Android: Turning off script debugging");
      EditorUserBuildSettings.allowDebugging = false;
    }
  }
}
#endif

However, this will not work. UCB is not respecting that settings.

Instead of you have to ...

Turn off Script Debugging via a POST request

At first, go into your UCB config and turn off development mode. The reason for that is that if you enable development mode, UCB will automatically turn on development mode and script debugging without actually allowing turn off the latter. That will come at some point in time according to the Unity support, but is currently not possible.

So, after you've turned off development mode (which practically means that app will now be build in production mode), you issue the following request:

curl --request PUT 'https://build-api.cloud.unity3d.com/api/v1/orgs/{ORG_ID}}/projects/{PROJECT_ID/buildtargets/{TARGET_NAME}' \
--header 'authorization: Basic {API_KEY}' \
--header 'Content-Type: application/json' \
--data-raw '{
   "settings": {
       "advanced": {
           "unity": {
               "playerExporter": {
                   "buildOptions": [
                       "Development"
                   ]
               }
           }
       }
   }
}'

That will turn on development build but not script debugging.

Unfortunately, you will not see "Development mode" ticked in UCB UI. In the log files there is also no information about the type of build.

To get some information, just add this editor script:

public class BuildTypeLogger : IPreprocessBuildWithReport
{
  public int callbackOrder { get; }
  public void OnPreprocessBuild(BuildReport report)
  {
    var isDevelopmentBuild = buildSummary.options.HasFlag(BuildOptions.Development).ToString();
    Debug.Log($"Build type logger: {report.summary.platform}, isDevelopment={isDevelopmentBuild}");
  }
}

Voilà. You know have a development build with script debugging turned off.