Cannot build 3D sample scene on M1 using IL2CPP

I’m trying to confirm if there’s a problem on my end, or if what I’m trying to do is not possible – it seems like others are able to use the IL2CPP scripting backend on M1 macs without issue. All Unity versions spanning 2021 to 2023 show the same issue for me.

Environment is 2020 MacBook Pro, with Xcode 14.3 (14E222b), Ventura 13.2.1 (22D68), and Unity 2022.2.13f installed via UnityHub.

I’m much more comfortable in Linux despite using a Mac for several years now, but AFAICT I can build C++ sources without issue and all the usual tools are on my PATH.

/Applications/Xcode.app/Contents/Developer```

Every time I attempt a build in the editor, the embedded il2cpp call fails (per editor log):

Starting: /Applications/Unity/Hub/Editor/2022.2.13f1-arm64/Unity.app/Contents/bee_backend --dont-print-to-structured-log --ipc --dagfile=“Library/Bee/Playerdbbd0d9a.dag” --profile=“Library/Bee/backend1.traceevents” Player
WorkingDir: /Users/anthonyr/wkspaces/arm64-macos-il2cpp
[ ] Require frontend run. Library/Bee/Playerdbbd0d9a.dag couldn’t be loaded
Starting: /Applications/Unity/Hub/Editor/2022.2.13f1-arm64/Unity.app/Contents/Tools/netcorerun/netcorerun “/Applications/Unity/Hub/Editor/2022.2.13f1-arm64/Unity.app/Contents/PlaybackEngines/MacStandaloneSupport/MacStandalonePlayerBuildProgram.exe” “/Applications/Unity/Hub/Editor/2022.2.13f1-arm64/Unity.app/Contents/PlaybackEngines/MacStandaloneSupport/Bee:/Applications/Unity/Hub/Editor/2022.2.13f1-arm64/Unity.app/Contents/Tools/BuildPipeline” “Library/Bee/Playerdbbd0d9a.dag.json” “Library/Bee/Playerdbbd0d9a-inputdata.json” “Library/Bee/buildprogram0.traceevents”
WorkingDir: /Users/anthonyr/wkspaces/arm64-macos-il2cpp
ExitCode: 4 Duration: 0s108ms
ExitCode: 1 Duration: 0s830ms
Internal build system error. BuildProgram exited with code 1.
error: Could not set up a toolchain for Architecture x64. Make sure you have the right build tools installed for il2cpp builds. Details:
C++ code builder is unable to build C++ code. Mac builds are not supported on this platform.


The same failure occurs when generating an Xcode project (and building it with xcodebuild -project GameAssembly.xcodeproj):

/bin/sh -c /Users/anthonyr/wkspaces/arm64-macos-il2cpp/Builds/build/GameAssembly.build/Release/GameAssembly.build/Script-251A4AC2ACF5885CBBC71E62.sh
/Users/anthonyr/wkspaces/arm64-macos-il2cpp/Builds/Il2CppOutputProject/IL2CPP/build/deploy/il2cpp --compile-cpp --platform=MacOSX --architecture=x64 --outputpath=GameAssembly.dylib --libil2cpp-static --baselib-directory=/Applications/Unity/Hub/Editor/2022.2.13f1-arm64/Unity.app/Contents/PlaybackEngines/MacStandaloneSupport --incremental-g-c-time-slice=3 --configuration=Release --dotnetprofile=unityaot-macos --profiler-report --profiler-output-file=/Users/anthonyr/wkspaces/arm64-macos-il2cpp/Library/Bee/artifacts/il2cpp_conv_6972.traceevents --print-command-line --data-folder=/Users/anthonyr/wkspaces/arm64-macos-il2cpp/Library/Bee/artifacts/MacStandalonePlayerBuildProgram/il2cppOutput/data --generatedcppdir=Il2CppOutputProject/Source/il2cppOutput --architecture=x64 --outputpath=/Users/anthonyr/wkspaces/arm64-macos-il2cpp/Builds/build/GameAssembly.build/Release/x64/GameAssembly.dylib --cachedirectory=/Users/anthonyr/wkspaces/arm64-macos-il2cpp/Builds/build/GameAssembly.build/Release/artifacts/x64 --configuration=Release
Starting: /Users/anthonyr/wkspaces/arm64-macos-il2cpp/Builds/Il2CppOutputProject/IL2CPP/build/deploy/bee_backend/mac-arm64/bee_backend --profile=“/Users/anthonyr/wkspaces/arm64-macos-il2cpp/Builds/build/GameAssembly.build/Release/artifacts/x64/buildstate/backend_profiler0.traceevents” --beedriver-listener --dagfile=“/Users/anthonyr/wkspaces/arm64-macos-il2cpp/Builds/build/GameAssembly.build/Release/artifacts/x64/buildstate/bee.dag” --continue-on-failure FinalProgram
WorkingDir: /Users/anthonyr/wkspaces/arm64-macos-il2cpp/Builds/build/GameAssembly.build/Release/artifacts/x64/buildstate
ExitCode: 4 Duration: 0s182ms
ExitCode: 1 Duration: 0s0ms
Build failed with 0 successful nodes and 0 failed ones
Error: Internal build system error. BuildProgram exited with code 1.
Unity.IL2CPP.Bee.BuildLogic.ToolchainNotFoundException: C++ code builder is unable to build C++ code. Mac builds are not supported on this platform.


If I intercept bee_backend and add --spammy-verbose, I see this:

[D] /Users/anthonyr/wkspaces/arm64-macos-il2cpp/Builds/build/GameAssembly.build/Release/artifacts/arm64/buildstate/bee.dag: mmap failed


Which could be normal if the exit 4 thing is expected, I'm not sure.

It seems like I'm missing or doing something dumb on my end, but I've tried debug builds with different switches, release builds, Intel 64-bit only builds, Apple-silicon only builds, mixed architecture, and literally nothing works with IL2CPP for me yet. The project above was a vanilla sample project generated by Unity (the one change being Mono-to-IL2CPP).

Mono builds are working for me, so it's not necessarily a blocker, but I'm trying to understand what's going wrong, since everything I read suggests installing Xcode makes it "Just Work". I'm able to dig much further, but I'm looking for some indication of where the problem lies.

I’ve also tried both flavors of the latest Tech Stream editors – both Intel 64 and native Apple silicon – is building via IL2CPP only supported on Intel-based Macs? Should this be working out-of-the-box or am I doing something unsupported?

Hrrrm, OK – fresh Mac installation with native Intel processor fails in the same way – what am I missing here? Are IL2CPP builds supported on Mac hosts? With Xcode 14.3? Other than xcode-select, I’m not sure what else il2cpp is looking for (I would dtrace it to find out but I can’t remove SIP protections currently).

Same behavior on both the Intel-native and Apple-native machines, using Xcode 14.2. I was able to confirm C++ code does in fact build in both cases, because Main.cpp is compiled by the generated Xcode project using the expected clang binary without issue – only il2cpp fails – is anyone able to confirm successful il2xpp builds on any combination of Mac host and Editor version?

I can’t build iOS projects either, so it must be something dumb with my setup or the fact I’m running the latest everything. I’m leaning toward a bug in IL2CPP itself right now, because I’m able to compile C++ without issue, eg. Main.cpp in the generated Xcode project itself, and IL2CPP is the only thing failing.

I’m already working around the fact macOS doesn’t support OpenXR (likely a more elegant way to do this with the OpenXR-bundled utility package I recently found), and there’s not a simple way to disable it for that standalone platform only, so for now, I’m forcing macOS to use Mono :frowning: I also had an update in macOS and Xcode today, and I was hoping that would do the trick, but no dice.

using System.Collections.Generic;

using UnityEngine;
using UnityEngine.XR.Management;

using UnityEditor;

[InitializeOnLoad]
public class BuildMethods
{
    static readonly public BuildMethods Instance = new BuildMethods();

    static BuildMethods() => BuildPlayerWindow.RegisterBuildPlayerHandler(Instance.BuildPlayer);

    void BuildPlayer(BuildPlayerOptions options)
    {
        if (options.target != BuildTarget.StandaloneOSX)
        {
            BuildPlayerWindow.DefaultBuildMethods.BuildPlayer(options);
            return;
        }
        var loaders = new List<XRLoader>(XRGeneralSettings.Instance.Manager.activeLoaders);
        var backend = PlayerSettings.GetScriptingBackend(options.targetGroup);
        try
        {
            XRGeneralSettings.Instance.Manager.TrySetLoaders(new List<XRLoader>());
            PlayerSettings.SetScriptingBackend(options.targetGroup, ScriptingImplementation.Mono2x);
            BuildPlayerWindow.DefaultBuildMethods.BuildPlayer(options);
        }
        finally
        {
            XRGeneralSettings.Instance.Manager.TrySetLoaders(loaders);
            PlayerSettings.SetScriptingBackend(options.targetGroup, backend);
        }
    }
}

sudo /Applications/ProcessMonitor.app/Contents/MacOS/ProcessMonitor | jq -r '([.process.path]+.process.arguments | join(" "))'

I used the above to trace all the commands that were called by il2cpp (or its children), and the below is what it called. I’m not familiar enough with mono to know how to do it just yet, but I’m trying to use the bundled mono installation to run il2cpp with --debug flags or something. I’m also looking into monodis disassembly output to get clues about what else il2cpp is actually trying (and failing) to do.

/usr/bin/uname uname -s

/Users/anthonyr/wkspaces/PROJECT/Builds/Il2CppOutputProject/IL2CPP/build/deploy/bee_backend/mac-arm64/bee_backend --profile=/Users/anthonyr/wkspaces/PROJECT/Builds/build/GameAssembly.build/Release/artifacts/arm64/buildstate/backend_profiler0.traceevents --beedriver-listener --dagfile=/Users/anthonyr/wkspaces/PROJECT/Builds/build/GameAssembly.build/Release/artifacts/arm64/buildstate/bee.dag --continue-on-failure FinalProgram

/usr/bin/xcode-select -p

/usr/bin/plutil -convert json -o - -- /Applications/Xcode-14.1.app/Contents/version.plist

/bin/mkdir -p /Users/anthonyr/wkspaces/PROJECT/Builds/build/Release

Normally I’d use strace for this on Linux, but SIP on macOS is preventing me from using anything too low-level – does anybody (Unity?) know how to convince il2cpp to give up more details (–verbose doesn’t show extra AFAICT)? I’m going to start getting into some low-level gdb-type tools soon and force il2cpp to reveal what file/dir/etc it wants.

You can see from the output that I also tried Xcode 14.1 to no avail.

Lastly, I was similarly unable to build for Android with ilc2pp using the NDK until I did the below, so something tells me there is a similar arm64/x64 mismatch going on here.

ln -s darwin-x86_64 /Applications/Unity/Hub/Editor/2022.2.15f1/PlaybackEngines/AndroidPlayer/NDK/toolchains/llvm/prebuilt/linux-x86_64

ughhh FML… I’m a monster lol

So I used lldb to set breakpoints on the stat call

breakpoint libsystem_kernel.dylib`stat

then printed the $x0 register holding the first arg

memory read -f s -c 1 $x0

so I could see what il2cpp was trying to do. After seeing it make several stat checks on /proc, I remembered I’d used /etc/synthetic.conf to create a fake /proc containing well-known files to trick various Linux tools into thinking they were on Linux, and the cherry was me doing this in the distant past to both machines I was testing with, giving them the same problem in all versions of Unity and Xcode.

It would’ve definitely been nicer if il2cpp could’ve failed in some way more visible to me, but I definitely caused my own pain here, and I suspect it’s also the reason the Android NDK mistakenly tried to use Linux tooling.

Don’t fake yer /proc folks!