iosunity-game-enginexcode16

New build error after upgrading to XCode 16


I have a iOS project that links in unity as a library. Everything built fine until today after upgrading to XCode16. Now my project cannot build with the below error

Undefined symbols for architecture arm64:
  "__mh_execute_header", referenced from:
      Builder.UnityService.(loadUnityFramework in _C1B4CF2F667E7F31717AD3C6734A533B)() -> __C.UnityFramework? in UnityService.o
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

I have tried upgrading to the lastest unity version to build, and same error. I'm unsure exactly how to debug this, anybody else able to build unity as a library in XCode16, what other debug steps can I take here?


I have confirmed a clean unity project built in the same way does work without the error, so the problem appears to be a dependency my unity project has, but given the vagueness of the error, I don't have any clues on where to start here.

edit: I take it back, even an empty project seems to fail. No idea how I got it to work the other day, but I've been slowly removing dependencies, then opened a blank project to check it's build settings, and even an empty project compiling against iOS is giving me the same compiler error.

I've upgraded to unity 6 and XCode 16.1, and am still getting the same error trying to build a blank unity project as a library. I've added a screenshot of the build logs, not sure if there's more details I can dig from elsewhere.

enter image description here


Solution

  • I have found the answer thanks to this question: Undefined symbols for architecture arm64: "__mh_execute_header" - Unity as a library embedding issue with Xcode 16 beta

    I had a routine I had written and forgot about that looked like this:

    private func loadUnityFramework() -> UnityFramework? {
        let bundlePath: String = Bundle.main.bundlePath + frameworkPath
    
        let bundle = Bundle(path: bundlePath)
        if bundle?.isLoaded == false {
            bundle?.load()
        }
    
        let ufw = bundle?.principalClass?.getInstance()
        if ufw?.appController() == nil {
            let machineHeader = UnsafeMutablePointer<MachHeader>.allocate(capacity: 1)
            machineHeader.pointee = _mh_execute_header
    
            ufw?.setExecuteHeader(machineHeader)
        }
        return ufw
    }
    

    The machine header portion needs to be updated in XCode 16 to the following:

    private func loadUnityFramework() -> UnityFramework? {
        let bundlePath: String = Bundle.main.bundlePath + frameworkPath
    
        let bundle = Bundle(path: bundlePath)
        if bundle?.isLoaded == false {
            bundle?.load()
        }
    
        let ufw = bundle?.principalClass?.getInstance()
        if ufw?.appController() == nil {
            let machineHeader = #dsohandle.assumingMemoryBound(to: MachHeader.self)
    
            ufw?.setExecuteHeader(machineHeader)
        }
        return ufw
    }
    

    This solves the issue for me.