react-native-community/upgrade-support

Solution: Upgrading from 0.61.5 to 0.62.0 "Undefined symbol: _swift_getFunctionReplacement"

chestercharles opened this issue ยท 31 comments

Environment

System:
    OS: macOS 10.15.3
    CPU: (12) x64 Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz
    Memory: 123.51 MB / 16.00 GB
    Shell: 3.2.57 - /bin/bash
  Binaries:
    Node: 12.14.0 - /usr/local/bin/node
    Yarn: 1.22.4 - /usr/local/bin/yarn
    npm: 6.13.4 - /usr/local/bin/npm
    Watchman: 4.9.0 - /usr/local/bin/watchman
  SDKs:
    iOS SDK:
      Platforms: iOS 13.4, DriverKit 19.0, macOS 10.15, tvOS 13.4, watchOS 6.2
    Android SDK:
      API Levels: 23, 25, 26, 27, 28, 29
      Build Tools: 23.0.1, 25.0.3, 26.0.1, 27.0.3, 28.0.3, 29.0.0
      System Images: android-19 | ARM EABI v7a, android-19 | Google APIs ARM EABI v7a, android-27 | Google APIs Intel x86 Atom, android-27 | Google Play Intel x86 Atom, android-28 | Google Play Intel x86 Atom, android-29 | Google APIs Intel x86 Atom
  IDEs:
    Android Studio: 3.4 AI-183.6156.11.34.5522156
    Xcode: 11.4/11E146 - /usr/bin/xcodebuild
  npmPackages:
    react: 16.11.0 => 16.11.0 
    react-native: 0.62.0 => 0.62.0 
  npmGlobalPackages:
    react-native-clean-project: 3.2.4
    react-native-cli: 2.0.1
    react-native-create-library: 3.1.2
    react-native-template-typescript: 5.2.0
    react-native: 0.60.4

Upgrading version

Upgrading from 0.61.5 to 0.62.0

Problem

Initial upgrade steps

  1. I started by following the 0.61.5 to 0.62.0 RN upgrade helper. I performed all the changes shown in the diffs from the upgrade helper tool.

  2. For the project.pbxproj changes, I proceeded to follow all four steps in the React Native 0.62 upgrade explanation in this repo.

I encountered the following errors when attempting to build iOS

Showing All Errors Only
Undefined symbol: _swift_getFunctionReplacement
Undefined symbol: _swift_getOrigOfReplaceable

More detailed error

Undefined symbols for architecture x86_64:
  "_swift_getFunctionReplacement", referenced from:
      _swift_getFunctionReplacement50 in libswiftCompatibilityDynamicReplacements.a(DynamicReplaceable.cpp.o)
     (maybe you meant: _swift_getFunctionReplacement50)
  "_swift_getOrigOfReplaceable", referenced from:
      _swift_getOrigOfReplaceable50 in libswiftCompatibilityDynamicReplacements.a(DynamicReplaceable.cpp.o)
     (maybe you meant: _swift_getOrigOfReplaceable50)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

I found that some folks with the same error details in this issue thread from TelegramMessenger (completely unrelated to my app) but they seemed to find a solution by enabling dead code stripping.

I enabled Dead Code Stripping in Build Settings for DEBUG in EACH target of my project (we have 4). Dead code stripping was already enabled in the release configuration for all the targets and in the project build settings/
image

After enabling dead code stripping, I was able to build but the app would crash immediately with the following error

This copy of libswiftCore.dylib requires an OS version prior to 12.2.0

In order to fix this, I followed the steps in this SO answer, namely:

  • Added a Dummy.swift file to the project (I already had bridging header files from following the steps in issue #13 of this repo.
  • Set Always Embed Swift Standard Libraries to YES in the build settings for my project and all my targets.

Solution

So in summary, my complete upgrade steps were

  1. Follow the 0.61.5 to 0.62.0 RN upgrade helper.

  2. For the project.pbxproj changes, follow all four steps in the React Native 0.62 upgrade explanation in this repo.

  3. Enable Dead Code Stripping in Build Settings for both debug and release in each project target

  4. Set Always Embed Swift Standard Libraries to YES in the build settings for my project and all my targets.

  5. Either add a Dummy.swift file to the project, or don't delete the dummy swift file that you created in step 2 (the issue #13 in this repo).

I also had a few problems with android

Problem 1

What went wrong:
A problem occurred evaluating project ':react-native-webview'.
Could not initialize class org.jetbrains.kotlin.gradle.plugin.sources.DefaultKotlinSourceSetKt

Solution1

Upgrade react-native-webview per react-native-webview/react-native-webview#1011


Problem 2

error: cannot find symbol
        }catch (InvocationTargetException

This was coming from the initializeFlipper method in MainApplication.java.

Solution 2

Add this to MainApplication.java imports

import java.lang.reflect.InvocationTargetException;

setting DEAD_CODE_STRIPPING to TRUE solved it for me ๐Ÿ™

@chestercharles ur solution in addition of

1- setting FB_SONARKIT_ENABLED=1

Go to Build Settings
Find Preprocessor Macros
To Debug add new value:
FB_SONARKIT_ENABLED=1

2- include /usr/lib/swift into Linking -> runpath search path ,
Also, for the record, after I built my app, it crashed on launch with Thread 1: signal SIGABRT
Searching a bit deeper, I found this message: This copy of libswiftCore.dylib requires an OS version prior to 12.2.0.
I added a File.swift in my projects, and it was ok. But if I removed the file again, it crashed again.
So, in xCode, I went to BuildSettings -> Linking -> runpath search path , and manually changed each build line to:

/usr/lib/swift
$(inherited)

both those step with yours managed to make it work
PS the above fixes where from other issue here and no credits goes to me

I managed to solve this issue just a few moments, ago.
For me the problem was I entered the library search paths with quotes (") like so:

"$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)"

opposed to

$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)

and followed the rest of the guides in #13

@chestercharles 's solution working on 0.61.5 => 0.62.2, I've followed the rest of the guides in #13 and facing issue "Undefined symbol: _swift_getFunctionReplacement".
So I've set Dead Code Stripping => YES then build successful.

I followed both the OP instructions and I've added FB_SONARKIT and LD_RUNPATH_SEARCH_PATHS AND it worked ๐ŸŽ‰

Then I dug into the changes and realised that we don't need the dummy file, it just looks that way because when you add it, it sets Always Embed Swift Standard Libraries to YES, and when you remove it, it sets it to NO ๐Ÿ˜ So you can delete it, just revert the 2 lines that relate to Always Embed... OR re-added them as the OP did in step 4 - the same goes for FB_SONARKIT_ENABLED , which should be added automatically, but sometimes isn't ๐Ÿ˜

The rest of the changes are needed, as described in Setting up Flipper for iOS and Troubleshooting - since these are listed under setting up Flipper, I think they must be added to the original guide since I don't see how anything can work if you don't do them ๐Ÿ˜ @pvinis?

Edit: I didn't notice I was getting a warning:

[!] The `MadbarzMobileApp [Release]` target overrides the `ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES` build setting defined in `Pods/Target Support Files/Pods-MadbarzMobileApp/Pods-MadbarzMobileApp.release.xcconfig'. This can lead to problems with the CocoaPods installation

but managed to fix it.

Instructions on how to manually add Flipper 0.62+ on Flipper site vs upgrade-support repo are pretty different. Check https://fbflipper.com/docs/getting-started/react-native-ios . Shouldn't we point to Flipper site to follow react native instructions?

The troubleshooting page https://fbflipper.com/docs/troubleshooting/ covers most of the solutions mentioned here

After I implemented the solution, I kept getting the "No bundle url present" error. To fix it, I had to select my project -> select Build Settings -> Deployment (iOS) -> Strip Debug Symbols during Copy -> Set Debug to Yes. The reason is that in AppDelegate.m you have this piece of code:

#if DEBUG
  return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
#else
  return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
#endif

In my case, since DEBUG was false, React Native was looking for a main.jsbundle file. After I set Debug to "Yes", the error disappeared and my app ran without any issues.

Screenshot 2020-05-13 at 09 03 14

I am getting the error:

ld: library not found for -lAppAuth

after adding FB_SONARKIT_ENABLED=1. Any ideas?

This is such a pain :(

After I add these various fixes my app for iOS does build but freeze at startup, locked on the logo during app launch.

Flipper does not report any errors, and there is no errors in the console outputs.
The js bundle is sent to the device but no trace of my console logs launched during index.js.

These are the last errors reported in Xcode log output (appearing after my require cycles warnings), but I don't know if these are real errors or not.

2020-06-09 08:57:35.738183+0200 pcea[34435:1741152] [] nw_socket_handle_socket_event [C5.1:1] Socket SO_ERROR [61: Connection refused]
2020-06-09 08:57:35.742129+0200 pcea[34435:1741152] [] nw_socket_handle_socket_event [C5.2:1] Socket SO_ERROR [61: Connection refused]
2020-06-09 08:57:35.744455+0200 pcea[34435:1741163] [] nw_connection_get_connected_socket [C5] Client called nw_connection_get_connected_socket on unconnected nw_connection
2020-06-09 08:57:35.745232+0200 pcea[34435:1741163] TCP Conn 0x600001710900 Failed : error 0:61 [61]
2020-06-09 08:57:35.805 [error][tid:com.facebook.react.JavaScript] TypeError: undefined is not an object (evaluating '_reactNative.TouchableHighlight.propTypes.style')
2020-06-09 08:57:35.810 [fatal][tid:com.facebook.react.ExceptionsManagerQueue] Unhandled JS Exception: TypeError: undefined is not an object (evaluating '_reactNative.TouchableHighlight.propTypes.style')
2020-06-09 08:57:35.828 [error][tid:com.facebook.react.JavaScript] Invariant Violation: Module AppRegistry is not a registered callable module (calling runApplication)
2020-06-09 08:57:35.896 [fatal][tid:com.facebook.react.ExceptionsManagerQueue] Unhandled JS Exception: Invariant Violation: Module AppRegistry is not a registered callable module (calling runApplication)
2020-06-09 08:57:35.958454+0200 pcea[34435:1741598] 6.8.1 - [Firebase/Analytics][I-ACS031010] Tracking view controller. Class, ID: UIViewController, 170578337242257097
2020-06-09 08:57:35.959882+0200 pcea[34435:1741598] 6.8.1 - [Firebase/Analytics][I-ACS031013] Screen view event not logged. App is not active.
2020-06-09 08:57:36.256990+0200 pcea[34435:1741598] 6.8.1 - [Firebase/Analytics][I-ACS031006] View controller already tracked. Class, ID: UIViewController, 170578337242257097

EDIT : It could be related to this issue likern/react-native-enhanced-popup-menu#8
EDIT 2 : It was only related to PropTypes and has been fixed by the library I used, but debugging was hard :/ https://github.com/mxck/react-native-material-menu/releases/tag/v1.1.2

After I implemented the solution, I kept getting the "No bundle url present" error. To fix it, I had to select my project -> select Build Settings -> Deployment (iOS) -> Strip Debug Symbols during Copy -> Set Debug to Yes. The reason is that in AppDelegate.m you have this piece of code:

#if DEBUG
  return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
#else
  return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
#endif

In my case, since DEBUG was false, React Native was looking for a main.jsbundle file. After I set Debug to "Yes", the error disappeared and my app ran without any issues.

Screenshot 2020-05-13 at 09 03 14

Facing the same issue but Strip Debug Symbols During Copy didn't help :(

@AlexandrDobrovolskiy I had a problem where I set DEBUG macro to false after following #25 (comment).

Go to Build Settings
Find Preprocessor Macros
To Debug add new value:
FB_SONARKIT_ENABLED=1

If you're like me and new to Xcode, this instruction might not be clear enough. Here's a screenshot of the correct config:

image

The key is the $(inherited) so we don't lose DEBUG=1 :)

I also noticed that removing that second entry ($(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)) makes the project build without making any other changes.

I wonder if we really need that, because from the error message it sounds like it's looking for _swift_getFunctionReplacement50 instead of _swift_getFunctionReplacement without 50 which I assume has to do with swift 5.

What will happen if we just omit that second file (since the project get's built)? Any ideas?

Following the SOLUTIONS in the topic works for me, just one thing:

Enable Dead Code Stripping --> This needed to be done for the TARGETS level, not PROJECT level

I did these steps from React Native 0.62 upgrade (Xcode) and set to project.pbxproj the following configs:

Change this:

IPHONEOS_DEPLOYMENT_TARGET = 9.0;

To this:

IPHONEOS_DEPLOYMENT_TARGET = 10.0;
LD_RUNPATH_SEARCH_PATHS = "/usr/lib/swift $(inherited)";
LIBRARY_SEARCH_PATHS = (
    "\"$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)\"",
    "\"$(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)\"",
    "\"$(inherited)\"",
);

Remove DEAD_CODE_STRIPPING and add ENABLE_BITCODE = NO.

And it worked fine! ๐Ÿš€

Following the SOLUTIONS in the topic works for me, just one thing:

Enable Dead Code Stripping --> This needed to be done for the TARGETS level, not PROJECT level

This is very important. I had been setting on Project level and wasting my time. Thanks @ptgamr.

This has been driving me crazy. I've lost track of the amount of things I've tried haha. A build setting in Xcode that got rid of these errors for me (giving way to entirely new errors instead.... kill..... me..... ) was "Don't Dead-Strip Inits and Terms".

Nothing helped. Want to see home widget preview.

I have the same problem, and I can't see home widget preview, anyone have any idea?

ninjz commented

@Piero87 Did you make sure that: Enable Dead Code Stripping is set on the TARGETS level like @ptgamr says? It works fine on my end.

@ninjz Yes I have tried a dozen of times, no luck

Today I did something that I was hesitating a little bit but worked, I just created a new project and copy and paste everything from the old one, now it is working.

I have updated the react-native version 0.61.5 to 0.63.3 and I am also facing the below issue.
Undefined symbol: _swift_getFunctionReplacement
Undefined symbol: _swift_getOrigOfReplaceable

I tried the above solution but none of the solutions work for me.

I am facing the same issue got these errors when build xcode

Undefined symbol: _swift_getFunctionReplacement
Undefined symbol: _swift_getOrigOfReplaceable

My xcode version is 12.1

None of those solutions works for me.

I am facing the same issue got these errors when build xcode

Undefined symbol: _swift_getFunctionReplacement
Undefined symbol: _swift_getOrigOfReplaceable

My xcode version is 12.1

None of those solutions works for me.

It works after I set "Don't Dead Strip Inits and Terms" to "Yes"

image

as @helderburato said, you just have to do:
Remove DEAD_CODE_STRIPPING and add ENABLE_BITCODE = NO

Thanks these infos helped me to run on 0.63.2

@shufisyahida you saved my day!!! :D

Following the SOLUTIONS in the topic works for me, just one thing:

Enable Dead Code Stripping --> This needed to be done for the TARGETS level, not PROJECT level

Thanks mate this helped me.

fukemy commented

Enable Dead Code Stripping -

can u provide podfile code? @onebuck-code @ptgamr