flipper: `react-native-flipper` 0.171 and up are causing linking errors on iOS Release build

šŸ› Bug Report

Starting with react-native-flipper 0.171, every app using this package will fail to link in Release mode on iOS, with the following error:

Undefined symbols for architecture arm64
āŒ   "_OBJC_CLASS_$_FlipperClient", referenced from:
āš ļø       objc-class-ref in libreact-native-flipper.a(FlipperReactNativeJavaScriptPluginManager.o)
āŒ ld: symbol(s) not found for architecture arm64

To Reproduce

  • npx react-native init TestRNProject
  • cd TestRNProject
  • yarn install react-native-flipper
  • cd ios && pod install
  • yarn ios --configuration Release

The build will fail with:

Processing Info.plist
āŒ Undefined symbols for architecture arm64
āŒ   "_OBJC_CLASS_$_FlipperClient", referenced from:
āš ļø       objc-class-ref in libreact-native-flipper.a(FlipperReactNativeJavaScriptPluginManager.o)
āŒ ld: symbol(s) not found for architecture arm64
āŒ clang: error: linker command failed with exit code 1 (use -v to see invocation)
** ARCHIVE FAILED **

Source of the problem

This issue is caused by this commit: https://github.com/facebook/flipper/commit/f65364c79c2267a1616cc64e883289f58454e253

It does not appear on react-native-flipper 0.164.0` and lower, and started with 0.171.1 (the next released version).

As @as4 commented on the commit, -DFB_SONARKIT_ENABLED is always set in Release mode by flipper.podspec, even if Flipper is not enabled by the app Podfile in this configuration, so react-native-flipper tries to link with FlipperClient, which is not compiled.

The solution could be to not have -DFB_SONARKIT_ENABLED defined if the RN app’s Podfile disables Flipper, or to use another constant in react-native-client to check if Flipper is really enabled for this build.

Environment

I tested with with:

  • React Native 0.71.0
  • react-native-flipper 0.177.0
  • macOS 13.1
  • XCode 14.2

About this issue

  • Original URL
  • State: open
  • Created a year ago
  • Reactions: 12
  • Comments: 27

Most upvoted comments

This worked from me:

PRODUCTION=1 pod install

I believe this is as a result of FlipperKit not being linked during release builds: https://github.com/facebook/flipper/issues/976#issuecomment-659416957

What solved this for me, was following the upgrade guide to 0.71.1 and utilising the NO_FLIPPER environment variable outlined in the community upgrade tool:

  • See their Podfile here (Lines 7 ~ 16 and Line 41)
  • Ensure you also set the recommended JS configuration outlined in the comment above flipper_config in the Podfile
  • Set environment variable NO_FLIPPER = 1 when running your release build

Downgrade flipper to version 0.164.0 on IOS, this solves the issue.

@rossyman Yes this is a workaround. But the code should check is Flipper will be linked, and make react-native-flipper a no-op when Flipper will not be linked to the build.

https://github.com/facebook/flipper/issues/4627#issuecomment-1513704583

I have fixed the error ā€˜Undefined symbol: OBJC_CLASS$_FlipperClient …’ by adding ā€˜Release’ to FlipperConfiguration: :flipper_configuration => flipper_config = FlipperConfiguration.enabled(["Release","Debug"], { 'Flipper' => '0.191.1' })

When it comes to product flavours: flipper_config = FlipperConfiguration.enabled(["Beta.Debug", "Production.Debug", "Staging.Debug", "Beta.Release", "Production.Release", "Staging.Release"], { 'Flipper' => '0.191.1' })

This this will help and works fro me.

This worked from me: install flipper to devDependencies, not dependencies. yarn add -D react-native-flipper And in podfile: :flipper_configuration => FlipperConfiguration.enabled(["Debug"], { 'Flipper' => '0.163.0' }),

I think, I have figured out the setup to support latest installable flipper v0.203.0 + react-native-flipper

  1. Setup scripts for switching between dev and prod environment in a way that when you switch to dev it will install pods as usual, but when you switch to prod it will install pods with NO_FLIPPER=1, basically uninstalling flipper.

  2. Almost all files in path node_modules/react-native-flipper/ios (except node_modules/react-native-flipper/ios/FlipperModule.h) are wrapped with

 #if defined(DEBUG) || defined(FB_SONARKIT_ENABLED)

changing it to

 #if DEBUG || FB_SONARKIT_ENABLED

does the trick, I also wrapped the only file that didn’t have this node_modules/react-native-flipper/ios/FlipperModule.h for just in case.

I’m not 100% sure on what’s going on, but my guess is that during prod build, DEBUG variable gets defined to 0 or false so defined(DEBUG) is always truthy.

  1. My react-native.config.js looks like this:
module.exports = {
  assets: ['./assets/fonts'],
  ...(process.env.NO_FLIPPER
    ? { 'react-native-flipper': { platforms: { ios: null } } }
    : {}),
};

NO_FLIPPER=1 pod install leads to another error

Where to set NO_FLIPPER = 1?

From your ios directory, run NO_FLIPPER=1 pod install then try archiving

That mean every time after archiving, i need to excute pod install to restore the flipper. And archiving should do NO_FLIPPER=1 pod install, Right?

any solution now?? Set environment variable NO_FLIPPER = 1 when running your release build

Where to set NO_FLIPPER = 1?

In our case app broken after release of new IOS 17.4. We tried fix it for several days, and I decided to try update all packages with command: yarn upgrade --latest and it helped!

This worked from me:

PRODUCTION=1 pod install

Works for me. I used,

PRODUCTION=1 arch -x86_64 pod install

But it removes Flipper and cannot build in to a device directly.

Log

`Ignoring digest-crc-0.6.4 because its extensions are not built. Try: gem pristine digest-crc --version 0.6.4 Ignoring unf_ext-0.0.8 because its extensions are not built. Try: gem pristine unf_ext --version 0.0.8 react-native-flipper: Found PRODUCTION=1, react-native-flipper will be disabled for production builds Auto-linking React Native modules for target '**': CodePush, RNCAsyncStorage, RNCMaskedView, RNCPicker, RNDateTimePicker, RNDeviceInfo, RNGestureHandler, RNImageCropPicker, RNKeychain, RNLocalize, RNPermissions, RNReanimated, RNSVG, RNScreens, RNSketchCanvas, RNVectorIcons, appcenter-core, appcenter-crashes, pushwoosh-react-native-plugin, react-native-app-auth, react-native-background-upload, react-native-blob-util, react-native-camera, react-native-config, react-native-flipper, react-native-geolocation-service, react-native-heic-converter, react-native-maps, react-native-netinfo, react-native-orientation-locker, react-native-pdf, react-native-safe-area-context, and react-native-webview Framework build type is static library [Codegen] Generating ./build/generated/ios/React-Codegen.podspec.json Analyzing dependencies [Codegen] Found FBReactNativeSpec react-native-flipper: Found PRODUCTION=1, react-native-flipper will be disabled for production builds Downloading dependencies Installing react-native-flipper 0.190.0 Removing CocoaAsyncSocket Removing Flipper Removing Flipper-Boost-iOSX Removing Flipper-DoubleConversion Removing Flipper-Fmt Removing Flipper-Folly Removing Flipper-Glog Removing Flipper-PeerTalk Removing Flipper-RSocket Removing FlipperKit Removing OpenSSL-Universal Removing SocketRocket Removing YogaKit Removing libevent Generating Pods project Setting REACT_NATIVE build settings Setting CLANG_CXX_LANGUAGE_STANDARD to c++17 on ////ios/*******.xcodeproj Pod install took 52 [s] to run Integrating client project Pod installation complete! There are 75 dependencies from the Podfile and 86 total pods installed.

[!] Do not use ā€œpod installā€ from inside Rosetta2 (x86_64 emulation on arm64).

[!] - Emulated x86_64 is slower than native arm64

[!] - May result in mixed architectures in rubygems (eg: ffi_c.bundle files may be x86_64 with an arm64 interpreter)

[!] Run ā€œenv /usr/bin/arch -arm64 /bin/bash --loginā€ then try again.

[!] Your project does not explicitly specify the CocoaPods master specs repo. Since CDN is now used as the default, you may safely remove it from your repos directory via ā€˜pod repo remove master’. To suppress this warning please add ā€˜warn_for_unused_master_specs_repo => false’ to your Podfile.`

This is a duplicate to #4278 😦 It would be great if this would get fixed at some point so that we can upgrade to the most recent versions.

In my case the problem was different.

Using in Podfile the default flipper configuration:

    :flipper_configuration => FlipperConfiguration.enabled(["Debug"]),

I found that when launched pod install --verbose I saw that the branch version was different, in my case was 1.76.0.1.9. The 1.76.0.1.9 missed asm folder needed to link the code.

In the screen I put the right version.

Screenshot 2023-01-20 alle 10 46 28

To fix, call pod repo list and update the CDN (usually named as trunk) with

pod repo update trunk (if at your side is named trunk)

Launch again pod install --verbose and you will see the same and right version of the Pod.