facebook / react-native

A framework for building native applications using React
https://reactnative.dev
MIT License
118.71k stars 24.29k forks source link

release build fails on iOS: Undefined symbol: _OBJC_CLASS_$_FlipperClient #39378

Closed saadalla closed 7 months ago

saadalla commented 1 year ago

Description

My app works fine in debug Scheme, when switching build to "release" it fails with below errors:

Undefined symbol: _OBJCCLASS$_FKUserDefaultsPlugin Undefined symbol: _OBJCCLASS$_FlipperClient Undefined symbol: _OBJCCLASS$_FlipperKitLayoutPlugin Undefined symbol: _OBJCCLASS$_FlipperKitNetworkPlugin Undefined symbol: _OBJCCLASS$_FlipperKitReactPlugin Undefined symbol: _OBJCCLASS$_SKDescriptorMapper Undefined symbol: _OBJCCLASS$_SKIOSNetworkAdapter Linker command failed with exit code 1 (use -v to see invocation)

Screenshot 2023-09-10 at 3 53 05 PM (2)

React Native Version

0.72.3

Output of npx react-native info

info Fetching system and libraries information... System: OS: macOS 13.4.1 CPU: (10) arm64 Apple M2 Pro Memory: 671.23 MB / 16.00 GB Shell: version: "5.9" path: /bin/zsh Binaries: Node: version: 18.16.1 path: /usr/local/bin/node Yarn: version: 1.22.19 path: /usr/local/bin/yarn npm: version: 9.5.1 path: /usr/local/bin/npm Watchman: version: 2023.07.10.00 path: /opt/homebrew/bin/watchman Managers: CocoaPods: version: 1.12.1 path: /Users/saadalla/.rbenv/shims/pod SDKs: iOS SDK: Platforms:

Steps to reproduce

I just followed the instructions from your official documentation.

Configure release scheme on xcode To configure your app to be built using the Release scheme, go to Product → Scheme → Edit Scheme. Select the Run tab in the sidebar, then set the Build Configuration dropdown to Release.

Screenshot 2023-09-10 at 4 07 16 PM (2)

Then click code build button

Snack, screenshot, or link to a repository

https://github.com/saadalla/RN-Linking-email-error.git

This problem exists for all my apps, this one can be used to reproduce

github-actions[bot] commented 1 year ago
:warning: Newer Version of React Native is Available!
:information_source: You are on a supported minor version, but it looks like there's a newer patch available - 0.72.4. Please upgrade to the highest patch for your minor or latest and verify if the issue persists (alternatively, create a new project and repro the issue in it). If it does not repro, please let us know so we can close out this issue. This helps us ensure we are looking at issues that still exist in the most recent releases.
saadalla commented 1 year ago

I upgraded to latest patch available - 0.72.4 same problem, no change what so ever

saadalla commented 1 year ago

Please help. I am stuck here for a while. Any ideas ??

tannguyen05 commented 1 year ago

same issue!

iiKurt commented 1 year ago

Same issue. This is really bad :// I created a new react native project from scratch, tried to build as release... and same error. :/

edit: managed to reproduce it with the ReproducerApp

npm install pod install

Xcode: Product > Archive

Xcode build output: Undefined symbols for architecture arm64: "_OBJCCLASS$_FKUserDefaultsPlugin", referenced from: objc-class-ref in libReact-RCTAppDelegate.a(RCTAppSetupUtils.o) "_OBJCCLASS$_FlipperClient", referenced from: objc-class-ref in libReact-RCTAppDelegate.a(RCTAppSetupUtils.o) "_OBJCCLASS$_FlipperKitLayoutPlugin", referenced from: objc-class-ref in libReact-RCTAppDelegate.a(RCTAppSetupUtils.o) "_OBJCCLASS$_FlipperKitNetworkPlugin", referenced from: objc-class-ref in libReact-RCTAppDelegate.a(RCTAppSetupUtils.o) "_OBJCCLASS$_FlipperKitReactPlugin", referenced from: objc-class-ref in libReact-RCTAppDelegate.a(RCTAppSetupUtils.o) "_OBJCCLASS$_SKDescriptorMapper", referenced from: objc-class-ref in libReact-RCTAppDelegate.a(RCTAppSetupUtils.o) "_OBJCCLASS$_SKIOSNetworkAdapter", referenced from: objc-class-ref in libReact-RCTAppDelegate.a(RCTAppSetupUtils.o) ld: symbol(s) not found for architecture arm64 clang: error: linker command failed with exit code 1 (use -v to see invocation)

Xcode 15.0 on macOS Ventura 13.5.1

jIrwinCline commented 1 year ago

Any luck? I'm facing this on my release build test in XCode too

saadalla commented 1 year ago

The only way out I could find after several weeks is to go back and rebuild the app on React 0.71.13 and I no longer have this issue. Painful but at least it works.

cipolleschi commented 1 year ago

I'll have a look at it next week. I'm sorry for the issue it caused

Roshdy commented 12 months ago

any update?

cipolleschi commented 12 months ago

For 0.72, you should re-install your pods with

PRODUCTION=1 bundle exec pod install

To remove Flipper from the Release build. We are aware that Flipper can't be built in Release mode, but we are deprecating Flipper in 0.73 and it will be removed in 0.74.

Roshdy commented 12 months ago

Unfortunately it produced 'RCTAppDelegate.h' file not found error

I tried with PRODUCTION=1 NO_FLIPPER=1 bundle exec pod install to avoid changing Podfile

cipolleschi commented 12 months ago

uhm... PRODUCTION=1 should imply NO_FLIPPER=1... 🤔 If it doesn't, it's a bug.

Can you confirm that:

Anyway, that's the supposed way to build 0.72 in Release mode.

Roshdy commented 12 months ago

Actually using PRODUCTION=1 alone while having flipper in package.json gives an error in FlipperReactNativeJavascriptPlugin.h

That's why I tried with NO_FLIPPER=1

If it helps, i'll post my rn-info

System:
  OS: macOS 14.0
  CPU: (12) x64 Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz
  Memory: 124.80 MB / 16.00 GB
  Shell:
    version: "5.9"
    path: /bin/zsh
Binaries:
  Node:
    version: 19.7.0
    path: ~/.nvm/versions/node/v19.7.0/bin/node
  Yarn:
    version: 1.22.19
    path: /usr/local/bin/yarn
  npm:
    version: 9.5.0
    path: ~/.nvm/versions/node/v19.7.0/bin/npm
  Watchman:
    version: 2023.10.02.00
    path: /usr/local/bin/watchman
Managers:
  CocoaPods:
    version: 1.12.1
    path: /Users/roshdy/.rvm/gems/ruby-2.7.7/bin/pod
SDKs:
  iOS SDK:
    Platforms:
      - DriverKit 23.0
      - iOS 17.0
      - macOS 14.0
      - tvOS 17.0
      - watchOS 10.0
  Android SDK:
    API Levels:
      - "27"
      - "30"
      - "31"
      - "33"
      - "34"
    Build Tools:
      - 27.0.3
      - 28.0.3
      - 30.0.2
      - 30.0.3
      - 31.0.0
      - 33.0.0
      - 34.0.0
    System Images:
      - android-33 | Google Play Intel x86_64 Atom
    Android NDK: Not Found
IDEs:
  Android Studio: 2022.3 AI-223.8836.35.2231.10811636
  Xcode:
    version: 15.0/15A240d
    path: /usr/bin/xcodebuild
Languages:
  Java:
    version: 20.0.2
    path: /usr/bin/javac
  Ruby:
    version: 2.7.7
    path: /Users/roshdy/.rvm/rubies/ruby-2.7.7/bin/ruby
npmPackages:
  "@react-native-community/cli": Not Found
  react:
    installed: 18.2.0
    wanted: 18.2.0
  react-native:
    installed: 0.72.5
    wanted: 0.72.5
  react-native-macos: Not Found
npmGlobalPackages:
  "*react-native*": Not Found
Android:
  hermesEnabled: true
  newArchEnabled: false
iOS:
  hermesEnabled: true
  newArchEnabled: false
Roshdy commented 12 months ago

Sorry, i didn't confirm 😅

Roshdy commented 11 months ago

I moved react-native-flipper in package.json from dependencies to devDependencies.

I managed to build the application and Archive it successfully 🥳

I used the full command PRODUCTION=1 NO_FLIPPER=1 bundle exec pod install

araujobarret commented 11 months ago

I have the same issue, your solution works @Roshdy but I'd hope for React Native and Flipper to co-exist in a better way not only for DX's sake but build time. Became quite time-consuming to install the Pods deps again for release and then again to debug mode in order to generate the release build, whereas on the Android side things are way less complicated.

cipolleschi commented 11 months ago

Flipper is going to be deprecated in React Native 0.73 and removed in React Native 0.74, so we will not incur in these problems anymore soon.

chrisshaddad commented 11 months ago

Flipper is going to be deprecated in React Native 0.73 and removed in React Native 0.74, so we will not incur in these problems anymore soon.

@cipolleschi do you recommend any other alternative libraries for React Native?

cipolleschi commented 11 months ago

We are working on a replacement for Flipper. In 0.73, it will still be experimental, hence why Flipper is only deprecated in 0.73. In 0.74 we will provide a debugger that should replace Flipper.

marcosab10 commented 11 months ago

The only thing that worked to me was replace all the part from "post_install" on Podfile to the code below.

use_flipper!()

post_install do |installer| react_native_post_install(installer) installer.pods_project.build_configurations.each do |config| config.build_settings["EXCLUDED_ARCHS[sdk=iphonesimulator*]"] = "arm64" end end

After that. Run the following commands in terminal on iOS folder.

pod deintegrate && pod install

Now clean build cache on Xcode and run the project.

Shortcut: CMD + SHIFT + K

rolfen commented 7 months ago

@cipolleschi do you recommend any other alternative libraries for React Native?

I'm debugging with Visual Studio Code (Attach to Hermes Application in my case). The only thing that is missing is the Network Tab which is why I would use Flipper sometimes.

lunaleaps commented 7 months ago

Feel free to leave comments on the experimental debugger discussion: https://github.com/react-native-community/discussions-and-proposals/discussions/733

and our announcement/docs about it: https://reactnative.dev/blog/2023/12/06/0.73-debugging-improvements-stable-symlinks#experimental-new-debugger

Closing this issue for now

rolfen commented 7 months ago

What I did, I removed the react-native-flipper npm package, commented out all references to flipper in the Podfile, the npm install and cd ios; PRODUCTION=1 pod install

Also did bundle install before pod install but I don't know if it changed anything.

I may have broken another configuration but Release works for me now.

It seems that react-native-flipper was trying to access linked libraries which are excluded in build mode.

What tipped me off is a comment in Podfile, along with maybe a suggestion for a better fix. This seems to be a known issue. Not sure why they'd have a comment in Podfile instead of fixing it.

# If you are using a `react-native-flipper` your iOS build will fail when `NO_FLIPPER=1` is set.
# because `react-native-flipper` depends on (FlipperKit,...) that will be excluded
#
# To fix this you can also exclude `react-native-flipper` using a `react-native.config.js`
# ```js
# module.exports = {
#   dependencies: {
#     ...(process.env.NO_FLIPPER ? { 'react-native-flipper': { platforms: { ios: null } } } : {}),
# ```
# flipper_config = ENV['NO_FLIPPER'] == "1" ? FlipperConfiguration.disabled : FlipperConfiguration.enabled

My env:

  System:
    OS: macOS 14.3.1
  Binaries:
    Node: 18.19.1 - /opt/local/bin/node
    npm: 10.5.0 - /opt/local/bin/npm
  Managers:
    CocoaPods: 1.15.2 - /usr/local/bin/pod
  IDEs:
    Xcode: 15.2/15C500b - /usr/bin/xcodebuild
  npmPackages:
    react-native: ^0.71.11 => 0.71.11 
funwithgui commented 5 months ago

Hey guys, I've been stuck on this for days. Getting the same error:

Undefined symbols for architecture arm64:
  "_OBJC_CLASS_$_FKUserDefaultsPlugin", referenced from:
      objc-class-ref in libReact-RCTAppDelegate.a(RCTAppSetupUtils.o)
  "_OBJC_CLASS_$_FlipperClient", referenced from:
      objc-class-ref in libReact-RCTAppDelegate.a(RCTAppSetupUtils.o)
  "_OBJC_CLASS_$_FlipperKitLayoutPlugin", referenced from:
      objc-class-ref in libReact-RCTAppDelegate.a(RCTAppSetupUtils.o)
  "_OBJC_CLASS_$_FlipperKitNetworkPlugin", referenced from:
      objc-class-ref in libReact-RCTAppDelegate.a(RCTAppSetupUtils.o)
  "_OBJC_CLASS_$_FlipperKitReactPlugin", referenced from:
      objc-class-ref in libReact-RCTAppDelegate.a(RCTAppSetupUtils.o)
  "_OBJC_CLASS_$_SKDescriptorMapper", referenced from:
      objc-class-ref in libReact-RCTAppDelegate.a(RCTAppSetupUtils.o)
  "_OBJC_CLASS_$_SKIOSNetworkAdapter", referenced from:
      objc-class-ref in libReact-RCTAppDelegate.a(RCTAppSetupUtils.o)
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

I've ran:

  1. PRODUCTION=1 NO_FLIPPER=1 bundle exec pod install
  2. PRODUCTION=1 bundle exec pod install
  3. just bundle exec pod install
  4. Build the Debug and Release (Release actually fails with another error)
  5. Remove and reinstalled absolutely everything related (xcode, yarn, npm, watchman, all ruby versions except the system one, etc), removed the repo, started from scratch.
  6. Different version of Xcode (15.2, which is what a colleague is using)

All to always end up on the same error...

This is the output of npx react-native info

System:
  OS: macOS 14.4.1
  CPU: (8) arm64 Apple M2
  Memory: 650.75 MB / 16.00 GB
  Shell:
    version: "5.9"
    path: /bin/zsh
Binaries:
  Node:
    version: 21.7.3
    path: /opt/homebrew/bin/node
  Yarn:
    version: 1.22.22
    path: /opt/homebrew/bin/yarn
  npm:
    version: 10.5.0
    path: /opt/homebrew/bin/npm
  Watchman:
    version: 2024.04.15.00
    path: /opt/homebrew/bin/watchman
Managers:
  CocoaPods:
    version: 1.15.2
    path: /Users/<redacted>/.rvm/gems/ruby-3.3.0/bin/pod
SDKs:
  iOS SDK:
    Platforms:
      - DriverKit 23.4
      - iOS 17.4
      - macOS 14.4
      - tvOS 17.4
      - visionOS 1.1
      - watchOS 10.4
  Android SDK: Not Found
IDEs:
  Android Studio: 2023.2 AI-232.10300.40.2321.11668458
  Xcode:
    version: 15.3/15E204a
    path: /usr/bin/xcodebuild
Languages:
  Java:
    version: 17.0.11
    path: /usr/bin/javac
  Ruby:
    version: 3.3.0
    path: /Users/<redacted>/.rvm/rubies/ruby-3.3.0/bin/ruby
npmPackages:
  "@react-native-community/cli": Not Found
  react: Not Found
  react-native: Not Found
  react-native-macos: Not Found
npmGlobalPackages:
  "*react-native*": Not Found
Android:
  hermesEnabled: true
  newArchEnabled: false
iOS:
  hermesEnabled: true
  newArchEnabled: false

If anyone has a solution, would extremely grateful

cipolleschi commented 5 months ago

@funwithgui on which version of React Native are you?

I suggest you to:

  1. run bundle install from the project/ios folder to make sure to use the right Ruby dependencies
  2. run bundle exec pod deintegrate to uninstall your pods properly
  3. depending on your version:
    1. For React Native < 0.73: PRODUCTION=1 NO_FLIPPER=1 bundle exec pod install
    2. For React Native >= 0.73: NO_FLIPPER=1 bundle exec pod install
  4. Open the project from Xcode
  5. Clean the build: ⌘+K
  6. Switch to the proper configuration from the drop down menu
  7. Build

These steps should work.

From the error it looks like that you don't have Flipper installed, correctly, but that the RCTAppDelegate is still receiving a build flag that tells it that Flipper should be there... and, of course, it can't find it.

But I need the RN version to see what's going on.

lazarevartem commented 4 months ago

Had same issue after update Xcode up to v15.

Solved this issue just with pod install command in /ios folder of project

funwithgui commented 4 months ago

@cipolleschi Thanks for the response, will try these steps! Re. react-native version we're on 0.72.9

@lazarevartem Unfortunately that one was on of the first things I tried unsuccessfully :(

twboc commented 2 months ago

Undefined symbol: _OBJCCLASS$_FlipperClient Linker command failed with exit code 1 (use -v to see invocation)

This is an error that caused some confusion and many answers that partially solve the issue but none of them address the issues in a coherent way.

WHAT CAUSES THE ERROR:

In release builds it is caused by trying to line to react-native-flipper library that is not provided for linking yet required in installer.generated_aggregate_target.xcconfigs

You can find these files in Targets Support Files > Pods-yourAppName in Xcode. You can find it under OTHER_LDFLAGS with value -l"react-native-flipper"

In my opinion this is an oversight on behalf of the react-native-flipper team.

Most likely in your build output log you will find something like this.:

Undefined symbols for architecture arm64: "_OBJCCLASS$_FlipperClient", referenced from: in libreact-native-flipper.a4 ld: symbol(s) not found for architecture arm64 clang: error: linker command failed with exit code 1 (use -v to see invocation)

If you inspect FlipperReactNativeJavaScriptPluginManager file you will see that it is trying to:

#import <FlipperKit/FlipperClient.h>

And since there is no library to be linked the linker fails and the whole build fails.

YOU MIGHT ALREADY TRIED THIS SOLUTIONS:

use_flipper!(['Debug'])

use_flipper!({'Flipper' => '0.126.0', configurations: ['Debug', 'Dev.Debug']})

:flipper_configuration => FlipperConfiguration.enabled(["Debug"]),
PRODUCTION=1 bundle exec pod install

They might have worked but they are very dependant on the version of react-native-flipper that you use.

use_flipper! - deprecated in newer versions, FlipperConfiguration.enabled(["Debug"]) - this will not work in older versions.

PRODUCTION=1 - env variable is not always available in your build,

As you can see here the PRODUCTION=1 is available only since this commit: https://github.com/facebook/flipper/commit/0c442bf4b186859a0262ef259ba70d4996da3f3f

YET FOR OLDER VERSIONS IT WILL CONTINUE INCLUDES

But still the pods require other pods: https://github.com/facebook/flipper/commit/44f5e35675f7198d720cc5075ec1f822e110d669#diff-ca0a0286a67452f62d0a79751348c6688482fbce1e93212428494f071904eda1

And going from FlipperKit.podspec https://github.com/facebook/flipper/blob/main/iOS/Podfile

Which will include Flipper.podspect https://github.com/facebook/flipper/blob/main/Flipper.podspec

And along the way one of them is going to add that pesky ld flag again.

HOW TO SOLVE THIS ISSUE: If you are running the newest version of react-native-flipper and have access to build env variables all you have to do is pass

PRODUCTION=1 bundle exec pod install

flag and following this commit it will work.

https://github.com/facebook/flipper/commit/0c442bf4b186859a0262ef259ba70d4996da3f3f

If you are not so lucky and have to run older version of react-native-flipper you have to delete the linker flag from your release pods

Targets Support Files > Pods-yourAppName You can do it manually just to try out if your build will produce an archive for TestFlight or release

Or add a post install function that will remove the undesired linker flag.

def flipper_remove(generated_aggregate_target, config_name, config_file)
    xcconfig_path = generated_aggregate_target.xcconfig_path(config_name)
    if File.exist?(xcconfig_path)
      puts "FLIPPER: Found xcconfig file: #{File.basename(xcconfig_path)}"
      xcconfig_content = File.read(xcconfig_path)
      modified_content = xcconfig_content.gsub('-l"react-native-flipper"', '')
      File.open(xcconfig_path, 'w') { |file| file.write(modified_content) }
    else
      puts "FLIPPER: xcconfig file does not exist: #{File.basename(xcconfig_path)}"
    end
end

post_install do |installer|
    installer.generated_aggregate_targets.each do |generated_aggregate_target|
        generated_aggregate_target.xcconfigs.each do |config_name, config_file|
            next unless config_name == 'Release'
            flipper_remove(generated_aggregate_target, config_name, config_file)
        end
    end
end