How to Convert Intel macOS Libraries to arm64 for Apple Silicon Simulators

This guide explains why Intel‑based macOS libraries need architecture conversion for Apple Silicon simulators, compares XCFramework and Rosetta solutions, and provides a step‑by‑step method using lipo, ar, and custom Swift code to replace load commands and rebuild arm64 binaries for simulator use.

Sohu Tech Products
Sohu Tech Products
Sohu Tech Products
How to Convert Intel macOS Libraries to arm64 for Apple Silicon Simulators

Background

Older Macs used Intel x86_64 CPUs and the iOS simulator also ran on x86_64. Apple’s transition to Apple Silicon introduced arm64 for both devices and simulators. The traditional lipo -based fat binary cannot contain two slices with the same architecture name, so an arm64 library built for devices cannot be used directly by an arm64 simulator.

Problem

The simulator architecture changed from x86_64 to arm64, causing lipo to reject merging two arm64 slices (device and simulator) and resulting in build failures.

Apple‑provided solutions

XCFramework : separate slices per platform, but converting many third‑party libraries is impractical.

Rosetta simulator : run the simulator under Rosetta to use the x86_64 slice; this option is unavailable for the visionOS simulator.

Manual conversion for visionOS

Modify the Mach‑O load commands of the arm64 slice so that the same binary works for both device and simulator.

Key difference

Using otool -l shows that device binaries contain LC_VERSION_MIN_IPHONEOS while simulator binaries contain LC_BUILD_VERSION. Replacing the former with the latter (and adjusting related fields) makes the binary compatible with the simulator.

Conversion steps

Extract the arm64 slice from the fat library:

lipo -thin arm64 path/to/lib.xcframework/lib.a -output lib.arm64

Unpack the slice into object files: ar x lib.arm64 Patch each object file :

Replace the load command LC_VERSION_MIN_IPHONEOS with LC_BUILD_VERSION.

Adjust cmdsize to include any build_tool_version entries.

Recalculate offsets for the header, load commands and data sections.

The Swift helper used by the original tool is reproduced below:

static func updatePreiOS12ObjectFile(lc: Data, minos: UInt32, sdk: UInt32) -> Data {
    let offset = UInt32(abs(MemoryLayout<build_version_command>.stride - MemoryLayout<version_min_command>.stride))
    let cmd = Int32(bitPattern: lc.loadCommand)
    switch cmd {
    case LC_SEGMENT_64:
        return updateSegment64(lc, offset)
    case LC_VERSION_MIN_IPHONEOS:
        return createVersionMin(lc, offset, minos: minos, sdk: sdk)
    case LC_DATA_IN_CODE, LC_LINKER_OPTIMIZATION_HINT:
        return updateDataInCode(lc, offset)
    case LC_SYMTAB:
        return updateSymTab(lc, offset)
    case LC_BUILD_VERSION:
        return updateVersionMin(lc, offset, minos: minos, sdk: sdk)
    default:
        return lc
    }
}

Re‑assemble the modified objects into a new arm64 library:

ar cr lib.arm64 *.o

Handling bitcode and build‑tool versions

If the library contains embedded bitcode, the build_tool_version structure must be accounted for when adjusting cmdsize. The relevant structs are:

struct build_tool_version {
    uint32_t tool;
    uint32_t version;
};

struct build_version_command {
    uint32_t cmd;       // LC_BUILD_VERSION
    uint32_t cmdsize;   // sizeof(build_version_command) + (ntools * sizeof(build_tool_version))
    uint32_t platform;
    uint32_t minos;
    uint32_t sdk;
    uint32_t ntools;
};

When bitcode is present, you can convert it to LLVM IR with llvm‑dis, edit the load commands, and re‑assemble with llvm‑as. Use the same LLVM version as Xcode to avoid incompatibilities.

Verification

After rebuilding, the library links without architecture‑conflict errors and runs on an arm64 simulator (including visionOS) without Rosetta.

References

https://bogo.wtf/arm64-to-sim.html

https://github.com/luosheng/arm64-to-sim

iOSMach-OARM64lipoBinaryXCFrameworkSimulator
Sohu Tech Products
Written by

Sohu Tech Products

A knowledge-sharing platform for Sohu's technology products. As a leading Chinese internet brand with media, video, search, and gaming services and over 700 million users, Sohu continuously drives tech innovation and practice. We’ll share practical insights and tech news here.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.