Managed - EAS Build fails for iOS Simulator

I’ve recently switched my Managed Workflow project over to EAS Build Services. I have an EAS build working on a custom dev client on my physical phone.

I am now trying to build a custom client for my iOS Simulator (in the cloud, not locally) but it is failing in the Run fastlane stage. Here is the error:

❌  ld: in /Users/expo/workingdir/build/ios/Pods/GoogleSignIn/Frameworks/GoogleSignIn.framework/GoogleSignIn(GIDEMMErrorHandler_3a47e13d8ca81b41e9cdb7ef5468004a.o), building for iOS Simulator, but linking in object file built for iOS, file '/Users/expo/workingdir/build/ios/Pods/GoogleSignIn/Frameworks/GoogleSignIn.framework/GoogleSignIn' for architecture arm64

❌  clang: error: linker command failed with exit code 1 (use -v to see invocation)

Here is my eas.json:

{
  "build": {
    "release": {},
    "development": {
      "ios": {
        "developmentClient": true,
        "distribution": "internal"
      }
    },
    "preview": {
      "ios": {
        "simulator": true
      }
    }
  }
}

Here are all my google related packages:

    "expo-firebase-analytics": "~4.1.0",
    "expo-google-app-auth": "^8.1.7",
    "expo-google-sign-in": "~9.2.1",

Looks like the particular error message has appeared here, in a react-native-google-signin package. Could it be that EAS iOS build process runs on some arm64 machine and thus why this error is getting thrown? Seems unlikely though…

Not exactly sure where the problem stems from or how I can reconcile it. Has anyone ran into this particular error and a fix? Much thanks in advance.

Here’s my expo diagnostics if it helps:

 Expo CLI 4.8.1 environment info:
    System:
      OS: macOS 11.3.1
      Shell: 5.8 - /bin/zsh
    Binaries:
      Node: 14.17.3 - /usr/local/bin/node
      npm: 6.14.13 - /usr/local/bin/npm
      Watchman: 2021.06.07.00 - /usr/local/bin/watchman
    Managers:
      CocoaPods: 1.10.2 - /usr/local/bin/pod
    SDKs:
      iOS SDK:
        Platforms: iOS 14.5, DriverKit 20.4, macOS 11.3, tvOS 14.5, watchOS 7.4
    IDEs:
      Xcode: 12.5.1/12E507 - /usr/bin/xcodebuild
    npmPackages:
      expo: ^42.0.0 => 41.0.1 
      react: 16.13.1 => 16.13.1 
      react-dom: 16.13.1 => 16.13.1 
      react-native: https://github.com/expo/react-native/archive/sdk-42.0.0.tar.gz => 0.63.2 
      react-native-web: ~0.13.12 => 0.13.18 
      react-navigation: ^4.0.0 => 4.4.4 
    npmGlobalPackages:
      expo-cli: 4.8.1
    Expo Workflow: managed

Try adding this plugin to your project to disable the architectures:

File: withSimulatorExcludedArchitectures.js

const { withXcodeProject } = require('@expo/config-plugins');

/**
 * Exclude building for arm64 on simulator devices in the pbxproj project.
 * Without this, production builds targeting simulators will fail.
 */
function setExcludedArchitectures(project) {
    const configurations = project.pbxXCBuildConfigurationSection();
    // @ts-ignore
    for (const { buildSettings } of Object.values(configurations || {})) {
        // Guessing that this is the best way to emulate Xcode.
        // Using `project.addToBuildSettings` modifies too many targets.
        if (typeof (buildSettings === null || buildSettings === void 0 ? void 0 : buildSettings.PRODUCT_NAME) !== 'undefined') {
            buildSettings['"EXCLUDED_ARCHS[sdk=iphonesimulator*]"'] = '"arm64"';
        }
    }
    return project;
}

const withExcludedSimulatorArchitectures = (c) => {
    return withXcodeProject(c, (config) => {
      config.modResults = setExcludedArchitectures(config.modResults);
      return config;
    });
};

module.exports = withExcludedSimulatorArchitectures;

Then in your app.json

{
  "expo": {
    "plugins": [
      "./withSimulatorExcludedArchitectures.js"
    ]
  }
}

Now rebuilding should disable arm64 for simulator builds. You can test this locally (on a new branch) with:

expo run:ios --configuration Release (targets a simulator by default)

9 Likes

Great, this worked. Thank you so much!