Fix: Building for iOS Simulator, but Linking in arm64 Object File

Fix: Building for iOS Simulator, but Linking in arm64 Object File

Written by

in

Quick answer: This error means a dependency contains an arm64 slice built for iOS devices, while Xcode is trying to link the arm64 slice for the iOS Simulator. On an Intel Mac, exclude arm64 for the simulator in your target and Pods, or set ONLY_ACTIVE_ARCH to Yes for local builds. On Apple silicon, update the dependency to an XCFramework with an arm64 simulator slice instead of excluding arm64.

Why this happens

Xcode 12 added arm64 as a valid architecture for the iOS Simulator so apps could run natively on Apple silicon. On an Intel Mac, the simulator still runs x86_64, but the build system can still try to link an arm64 simulator slice when it builds all architectures.

The error appears when one object file or framework in the link step has an arm64 slice built for iOS device, not for iOS Simulator. The linker sees building for iOS Simulator and rejects the device-only slice. lipo -info can make this confusing: it may print arm64, but it does not say whether that arm64 slice is for device or simulator.

CocoaPods makes this more likely because prebuilt pods may ship a fat framework with device arm64 and Intel simulator x86_64, but no arm64 simulator slice. The same mismatch can also produce Unable to load standard library for target 'arm64-apple-ios11.0'.

How to fix it

1. Exclude arm64 for the simulator on Intel Macs

This is the accepted fix for the Xcode 12-era error. In your app target, open Build Settings, find Excluded Architectures under Architectures, and add Any iOS Simulator SDK with value arm64.

If you use custom .xcconfig files, add this line:

EXCLUDED_ARCHS[sdk=iphonesimulator*] = arm64

You must do the same for the Pods project. Manual changes to the Pods project are overwritten by pod install, so add a post_install hook to your Podfile:

post_install do |installer|
  installer.pods_project.build_configurations.each do |config|
    config.build_settings['EXCLUDED_ARCHS[sdk=iphonesimulator*]'] = 'arm64'
  end
end

Then run pod install, clean the build folder, and rebuild. In Xcode, use Product > Clean Build Folder. If the error persists, delete DerivedData for the project and build again.

2. Use ONLY_ACTIVE_ARCH for local simulator builds

The top-voted workaround is to set Build Active Architecture Only (ONLY_ACTIVE_ARCH) to Yes. Xcode then builds only the architecture for the selected run destination. For a simulator on an Intel Mac, that is x86_64, so Xcode does not try to link the device arm64 slice.

In Build Settings, set ONLY_ACTIVE_ARCH to Yes for Debug. If you also run Release builds in the simulator, set it there too. Keep it set to No for the configuration you use to archive for the App Store.

In an .xcconfig file:

ONLY_ACTIVE_ARCH = YES

For Pods, the same post_install pattern works:

post_install do |installer|
  installer.pods_project.build_configurations.each do |config|
    config.build_settings['ONLY_ACTIVE_ARCH'] = 'YES'
  end
end

This is a workaround, not a repair. It hides the missing simulator slice rather than adding it.

3. On Apple silicon, update the dependency instead

Do not exclude arm64 on an Apple silicon Mac. There, arm64 is the native simulator architecture. Excluding it forces a fallback to x86_64 or causes a different failure.

If a binary dependency lacks an arm64 simulator slice, ask the vendor for an XCFramework that includes one, or build the dependency from source. For CocoaPods, check whether a newer pod version supports Apple silicon simulators. For Swift packages, make sure the package builds for the simulator rather than shipping a prebuilt device-only binary.

You can confirm your Mac architecture with:

uname -m

If it prints arm64, you are on Apple silicon. If it prints x86_64, you are on an Intel Mac or running under Rosetta.

4. Check the slice, not just the architecture name

lipo -info lists architectures, but it cannot tell you whether an arm64 slice was built for iOS device or iOS Simulator. A framework can contain arm64 and still be unusable for the simulator.

When a vendor says a framework supports arm64, ask specifically whether it includes an arm64 simulator slice. For source-built pods, verify the pod target is building for the simulator SDK rather than reusing a device-only binary.

How to prevent it

  • Keep CocoaPods and binary dependencies current, especially when moving between Intel and Apple silicon Macs.
  • Prefer XCFrameworks that explicitly include device and simulator slices.
  • Do not edit the Pods project by hand; put architecture settings in the Podfile post_install hook.
  • Keep ONLY_ACTIVE_ARCH set to No for archive configurations so you do not ship a single-architecture build.
  • After changing EXCLUDED_ARCHS or ONLY_ACTIVE_ARCH, run pod install, clean the build folder, and rebuild.

FAQ

Does lipo -info tell me whether arm64 is for device or simulator?

No. lipo -info only lists architecture names. It cannot distinguish an arm64 device slice from an arm64 simulator slice.

Should I exclude arm64 on an Apple silicon Mac?

No. On Apple silicon, arm64 is the native simulator architecture. Excluding it is an Intel-era workaround. Update the dependency or build it from source instead.

Will excluding arm64 for the simulator affect my App Store archive?

No, if you scope it with EXCLUDED_ARCHS[sdk=iphonesimulator*]. That setting only affects simulator builds. Device and archive builds still use arm64. Be careful with ONLY_ACTIVE_ARCH: leaving it enabled for Release can produce a single-architecture archive.

Sources & credits

Parts of this guide are adapted from content licensed under CC BY-SA 4.0; this article is shared under the same license.