Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error 'ReactCommon/TurboModuleBinding.h' file not found on react native 0.72.0 on iOS #38067

Closed
toscalivia83 opened this issue Jun 26, 2023 · 52 comments
Labels
Needs: Repro This issue could be improved with a clear list of steps to reproduce the issue. Needs: Triage 🔍 Platform: iOS iOS applications. Type: Upgrade Issue Issues reported from upgrade issue form

Comments

@toscalivia83
Copy link

Description

After upgrading my react native to version 0.72.0, I can't run my react native app on iOS properly as it logs an error saying: "Error 'ReactCommon/TurboModuleBinding.h' file" as show in the picture below.

I tried executing with the suggestions described here but unfortunately the error is still here.

Here is my Podfile:

require_relative '../node_modules/react-native/scripts/react_native_pods'
require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'

platform :ios, '13.0'

require_relative '../node_modules/react-native/scripts/react_native_pods'
require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'

def fix_library_search_paths(installer)
  def fix_config(config)
    lib_search_paths = config.build_settings["LIBRARY_SEARCH_PATHS"]
    if lib_search_paths
      if lib_search_paths.include?("$(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)") || lib_search_paths.include?("\"$(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)\"")
        # $(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME) causes problem with Xcode 12.5 + arm64 (Apple M1)
        # since the libraries there are only built for x86_64 and i386.
        lib_search_paths.delete("$(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)")
        lib_search_paths.delete("\"$(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)\"")
        if !(lib_search_paths.include?("$(SDKROOT)/usr/lib/swift") || lib_search_paths.include?("\"$(SDKROOT)/usr/lib/swift\""))
          # however, $(SDKROOT)/usr/lib/swift is required, at least if user is not running CocoaPods 1.11
          lib_search_paths.insert(0, "$(SDKROOT)/usr/lib/swift")
        end
      end
    end
  end

  def __apply_Xcode_14_3_RC_post_install_workaround(installer)
    installer.pods_project.targets.each do |target|
      target.build_configurations.each do |config|
        current_target = config.build_settings['IPHONEOS_DEPLOYMENT_TARGET']
        minimum_target = min_ios_version_supported
        if current_target.to_f < minimum_target.to_f
          config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = minimum_target
        end
      end
    end
  end

  projects = installer.aggregate_targets
    .map{ |t| t.user_project }
    .uniq{ |p| p.path }
    .push(installer.pods_project)

  projects.each do |project|
    project.build_configurations.each do |config|
      fix_config(config)
    end
    project.native_targets.each do |target|
      target.build_configurations.each do |config|
        fix_config(config)
      end
    end
    project.save()
  end
end

target 'Equitazone' do
  config = use_native_modules!

  use_frameworks! :linkage => :static
  $RNFirebaseAsStaticFramework = true

  use_react_native!(:path => config[:reactNativePath], :hermes_enabled => false)



  pod 'react-native-config/Extension', :path => '../node_modules/react-native-config'

  target 'EquitazoneTests' do
    inherit! :complete
    # Pods for testing
  end

  # Enables Flipper.
  #
  # Note that if you have use_frameworks! enabled, Flipper will not work and
  # you should disable these next few lines.
  # use_flipper!
  post_install do |installer|
    __apply_Xcode_12_5_M1_post_install_workaround(installer)
    installer.pods_project.build_configuration_list.build_configurations.each do |configuration|
      configuration.build_settings['CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES'] = 'YES'
    end
    installer.pods_project.targets.each do |target|
      target.build_configurations.each do |config|
        config.build_settings["ONLY_ACTIVE_ARCH"] = "NO"
        config.build_settings['CODE_SIGN_IDENTITY'] = ''
      end
    end
    fix_library_search_paths(installer)
    __apply_Xcode_14_3_RC_post_install_workaround(installer)
  end
end

target 'Equitazone-tvOS' do
  # Pods for Equitazone-tvOS

  target 'Equitazone-tvOSTests' do
    inherit! :search_paths
    # Pods for testing
  end
end

workspace 'Equitazone.xcworkspace'

React Native Version

0.72.0

Output of npx react-native info

System:
OS: macOS 13.4
CPU: (8) arm64 Apple M1 Pro
Memory: 89.31 MB / 16.00 GB
Shell:
version: "5.9"
path: /bin/zsh
Binaries:
Node:
version: 20.2.0
path: /usr/local/bin/node
Yarn: Not Found
npm:
version: 9.6.6
path: /usr/local/bin/npm
Watchman: Not Found
Managers:
CocoaPods:
version: 1.12.1
path: /usr/local/bin/pod
SDKs:
iOS SDK:
Platforms:
- DriverKit 22.4
- iOS 16.4
- macOS 13.3
- tvOS 16.4
- watchOS 9.4
Android SDK:
API Levels:
- "28"
- "29"
- "30"
- "31"
- "32"
- "33"
Build Tools:
- 29.0.2
- 30.0.2
- 30.0.3
- 31.0.0
- 32.0.0
- 33.0.0
- 34.0.0
System Images:
- android-28 | Google APIs ARM 64 v8a
- android-28 | Google ARM64-V8a Play ARM 64 v8a
- android-29 | Google APIs ARM 64 v8a
- android-29 | Google Play ARM 64 v8a
- android-30 | Google APIs ARM 64 v8a
- android-31 | Google Play ARM 64 v8a
- android-32 | Google APIs ARM 64 v8a
- android-33 | Google APIs ARM 64 v8a
- android-33 | Google Play ARM 64 v8a
Android NDK: 22.1.7171670
IDEs:
Android Studio: 2022.2 AI-222.4459.24.2221.10121639
Xcode:
version: 14.3.1/14E300c
path: /usr/bin/xcodebuild
Languages:
Java:
version: 17.0.1
path: /usr/bin/javac
Ruby:
version: 3.2.2
path: /usr/local/opt/ruby/bin/ruby
npmPackages:
"@react-native-community/cli": Not Found
react:
installed: 18.2.0
wanted: 18.2.0
react-native:
installed: 0.72.0
wanted: ^0.72.0
react-native-macos: Not Found
npmGlobalPackages:
"react-native": Not Found
Android:
hermesEnabled: true
newArchEnabled: false
iOS:
hermesEnabled: false
newArchEnabled: false

Steps to reproduce

  • npm i
  • arch -x86_64 pod install (or tried with pod install only)
  • press run from Xcode on emulator or real device

Snack, code example, screenshot, or link to a repository

Screenshot 2023-06-25 at 23 33 47
@github-actions github-actions bot added the Platform: iOS iOS applications. label Jun 26, 2023
@cipolleschi
Copy link
Contributor

can you try using bundle install and bundle exec pod install? They should take care of using the right version of Cocoapods and dependencies, so that we are aligned to the same versions.

@toscalivia83
Copy link
Author

bundle install worked as soon as I deletee the Gemfile.lock
However when I run bundle exec pod install I get this error:

bundler: failed to load command: pod (/usr/local/lib/ruby/gems/3.2.0/bin/pod)
/usr/local/Cellar/ruby/3.2.2/lib/ruby/3.2.0/bundler/rubygems_integration.rb:308:in `block in replace_bin_path': can't find executable pod for gem cocoapods. cocoapods is not currently included in the bundle, perhaps you meant to add it to your Gemfile? (Gem::Exception)

my ~/.zshrc looks like this:

source /Users/marion/.bash_profile

export PATH="/usr/local/bin:$PATH"
alias adb='/Users/marion/Library/Android/sdk/platform-tools/adb'

export NVM_DIR="$HOME/.nvm"
  [ -s "/usr/local/opt/nvm/nvm.sh" ] && \. "/usr/local/opt/nvm/nvm.sh"  # This loads nvm
  [ -s "/usr/local/opt/nvm/etc/bash_completion.d/nvm" ] && \. "/usr/local/opt/nvm/etc/bash_completion.d/nvm"  # This loads nvm bash_completion

# Add RVM to PATH for scripting. Make sure this is the last PATH variable change.
export PATH="$PATH:$HOME/.rvm/bin"

# The next line updates PATH for the Google Cloud SDK.
if [ -f '/Users/marion/google-cloud-sdk/path.zsh.inc' ]; then . '/Users/marion/google-cloud-sdk/path.zsh.inc'; fi

# The next line enables shell command completion for gcloud.
if [ -f '/Users/marion/google-cloud-sdk/completion.zsh.inc' ]; then . '/Users/marion/google-cloud-sdk/completion.zsh.inc'; fi

export ANDROID_HOME=$HOME/Library/Android/sdk
export PATH=$PATH:$ANDROID_HOME/emulator
export PATH=$PATH:$ANDROID_HOME/platform-tools
export PATH=$PATH:/opt/gradle/gradle-8.1.1/bin
export PATH="/usr/local/opt/ruby/bin:$PATH"

Do you know how I can make it work?
I'm trying to find how to add cocoapods into my Gemfile

@toscalivia83
Copy link
Author

I checked and cocoapods has been installed properly but I'm still having the same error @cipolleschi

@kelset kelset added the Type: Upgrade Issue Issues reported from upgrade issue form label Jun 27, 2023
@cipolleschi
Copy link
Contributor

Does it happens to you in a newly created project?

If you do npx react-native init NewProject --version latest and you try to build it, do you still have the Reactcommon/TurboModuleBinding.h file not found error?

I'm trying to understand what's going on, because I can't repro the issue.

@toscalivia83
Copy link
Author

I tried creating a new repo, and I used npx react-native@latest init NewProject I guess that's what you meant. It seems the command changed recently

It works fine on another project indeed!

Don't really know what to change in my current project to make it work then 😬
Might be related to the usage of firebase?

@cipolleschi
Copy link
Contributor

Yep, very likely so. My suggestion now would be to start adding one change at the time and try pod install/build until we find what is breaking the build. At that point, we could be able to address the issue.
How does it sound?

@Lakston
Copy link

Lakston commented Jul 7, 2023

I'm having the same problem, tried bundle install but it is not fixing it, if anyone has a clue

@harouf
Copy link

harouf commented Jul 7, 2023

I am also facing the same issue. Any workaround?

@Lakston
Copy link

Lakston commented Jul 7, 2023

I double checked that I disabled both hermes and fabric in my podfile:

    :hermes_enabled => false,
    :fabric_enabled => false,

so I dont know why turbomodules would be imported

node_modules/react-native/ReactCommon/react/nativemodule/core/platform/ios/ReactCommon/RCTTurboModule.h:18:9 'ReactCommon/TurboModule.h' file not found

I'm running 0.72.1

@cipolleschi
Copy link
Contributor

Turbomodules are part of React Native and used by React Native even when the New Architecture is not fully enabled, that's why they are included.

Have you disabled Flipper? It is not compatible with use_frameworks!.
Can you share your Podfile?

The best suggestion is to start with a fresh project and try to add one dep at the time to understand what breaks the app. We are running test in CI for a vanilla app with static frameworks and they are passing, so React Native works properly with that set up. There should be some dependency which is misconfigured.

@Lakston
Copy link

Lakston commented Jul 7, 2023

here is my podfile

$RNFirebaseAsStaticFramework = true
# Resolve react_native_pods.rb with node to allow for hoisting
require Pod::Executable.execute_command('node', ['-p',
  'require.resolve(
    "react-native/scripts/react_native_pods.rb",
    {paths: [process.argv[1]]},
  )', __dir__]).strip

platform :ios, min_ios_version_supported
prepare_react_native_project!

# 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
linkage = ENV['USE_FRAMEWORKS']
if linkage != nil
  Pod::UI.puts "Configuring Pod with #{linkage}ally linked Frameworks".green
  use_frameworks! :linkage => linkage.to_sym
end

use_frameworks! :linkage => :static

# Convert all permission pods into static libraries
pre_install do |installer|
  Pod::Installer::Xcode::TargetValidator.send(:define_method, :verify_no_static_framework_transitive_dependencies) {}

  installer.pod_targets.each do |pod|
    if pod.name.eql?('RNPermissions') || pod.name.start_with?('Permission-')
      def pod.build_type;
        # Uncomment the line corresponding to your CocoaPods version
        Pod::BuildType.static_library
        # Pod::Target::BuildType.static_library # < 1.9
      end
    end
  end
end

install! 'cocoapods', :deterministic_uuids => false

target 'AppName' do
  permissions_path = '../node_modules/react-native-permissions/ios'
  pod 'Permission-AppTrackingTransparency', :path => "#{permissions_path}/AppTrackingTransparency"
  pod 'Permission-MediaLibrary', :path => "#{permissions_path}/MediaLibrary"
  pod 'Permission-Notifications', :path => "#{permissions_path}/Notifications"
  pod 'Permission-Camera', :path => "#{permissions_path}/Camera"
  pod 'Permission-PhotoLibrary', :path => "#{permissions_path}/PhotoLibrary"
  pod 'Permission-Contacts', :path => "#{permissions_path}/Contacts"
  pod 'Permission-Microphone', :path => "#{permissions_path}/Microphone"
  pod 'Permission-LocationAlways', :path => "#{permissions_path}/LocationAlways"
  pod 'Permission-LocationWhenInUse', :path => "#{permissions_path}/LocationWhenInUse"
  pod 'Permission-Calendars', :path => "#{permissions_path}/Calendars"
  pod 'Permission-Motion', :path => "#{permissions_path}/Motion"
  pod 'Permission-SpeechRecognition', :path => "#{permissions_path}/SpeechRecognition"
  pod 'Haptica'
  pod 'ffmpeg-kit-react-native', :subspecs => ['min-gpl'], :podspec => '../node_modules/ffmpeg-kit-react-native/ffmpeg-kit-react-native.podspec'
  
  config = use_native_modules!
  
  # Flags change depending on the env values.
  flags = get_default_flags()
  
  use_react_native!(
    :path => config[:reactNativePath],
    # Hermes is now enabled by default. Disable by setting this flag to false.
    :hermes_enabled => false,
    :fabric_enabled => false,
    # Enables Flipper.
    #
    # Note that if you have use_frameworks! enabled, Flipper will not work and
    # you should disable the next line.
    # :flipper_configuration => flipper_config,
    # An absolute path to your application root.
    :app_path => "#{Pod::Config.instance.installation_root}/.."
    )
    
  pod 'react-native-sms', :path => '../node_modules/react-native-sms'

  target 'AppNameTests' do
    inherit! :search_paths
    # Pods for testing
  end
end

target 'AppName-tvOS' do
  # Pods for AppName-tvOS

  target 'AppName-tvOSTests' do
    inherit! :search_paths
    # Pods for testing
  end
end

post_install do |installer|
  installer.pods_project.build_configurations.each do |config|
      config.build_settings['CODE_SIGNING_ALLOWED'] = 'NO'
  end
end

I just tried to run NO_FLIPPER=1 pod install and still having the same problem, also, is there a way to specify no flipper directly in the podfile ?

@cipolleschi
Copy link
Contributor

Hi, ok, there are a couple of more things:

  1. In another issue, they mentioned that you can remove the pre-install hook. I tried to find it but I couldn't... :(
  2. You should move all the pod invocations AFTER the invocation of use_react_native!. We set some variables to make sure we can build with use_frameworks! and that could help
  3. One of the parameters of use_react_native! is :flipper_configuration. You can set that to FlipperConfiguration.disabled and it will be disabled without having to use NO_FLIPPER.

@Lakston
Copy link

Lakston commented Jul 7, 2023

  1. I'll look into that but not sure what part we're talking about exactly :) '
  2. I did, I'll post the updated podfile
  3. Yes I realised I could do that after posting my question!
$RNFirebaseAsStaticFramework = true
# Resolve react_native_pods.rb with node to allow for hoisting
require Pod::Executable.execute_command('node', ['-p',
  'require.resolve(
    "react-native/scripts/react_native_pods.rb",
    {paths: [process.argv[1]]},
  )', __dir__]).strip

platform :ios, min_ios_version_supported
prepare_react_native_project!

# 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 = FlipperConfiguration.disabled
linkage = ENV['USE_FRAMEWORKS']
if linkage != nil
  Pod::UI.puts "Configuring Pod with #{linkage}ally linked Frameworks".green
  use_frameworks! :linkage => linkage.to_sym
end

use_frameworks! :linkage => :static

# Convert all permission pods into static libraries
pre_install do |installer|
  # Pod::Installer::Xcode::TargetValidator.send(:define_method, :verify_no_static_framework_transitive_dependencies) {}

  installer.pod_targets.each do |pod|
    if pod.name.eql?('RNPermissions') || pod.name.start_with?('Permission-')
      def pod.build_type;
        # Uncomment the line corresponding to your CocoaPods version
        Pod::BuildType.static_library
        # Pod::Target::BuildType.static_library # < 1.9
      end
    end
  end
end

install! 'cocoapods', :deterministic_uuids => false

target 'appname' do
  pod 'ffmpeg-kit-react-native', :subspecs => ['min-gpl'], :podspec => '../node_modules/ffmpeg-kit-react-native/ffmpeg-kit-react-native.podspec'   

  config = use_native_modules!
  
  # Flags change depending on the env values.
  flags = get_default_flags()
  
  use_react_native!(
    :path => config[:reactNativePath],
    # Hermes is now enabled by default. Disable by setting this flag to false.
    :hermes_enabled => false,
    :fabric_enabled => false,
    # Enables Flipper.
    #
    # Note that if you have use_frameworks! enabled, Flipper will not work and
    # you should disable the next line.
    # :flipper_configuration => flipper_config,
    # An absolute path to your application root.
    :app_path => "#{Pod::Config.instance.installation_root}/.."
    )

  permissions_path = '../node_modules/react-native-permissions/ios'
  pod 'Permission-AppTrackingTransparency', :path => "#{permissions_path}/AppTrackingTransparency"
  pod 'Permission-MediaLibrary', :path => "#{permissions_path}/MediaLibrary"
  pod 'Permission-Notifications', :path => "#{permissions_path}/Notifications"
  pod 'Permission-Camera', :path => "#{permissions_path}/Camera"
  pod 'Permission-PhotoLibrary', :path => "#{permissions_path}/PhotoLibrary"
  pod 'Permission-Contacts', :path => "#{permissions_path}/Contacts"
  pod 'Permission-Microphone', :path => "#{permissions_path}/Microphone"
  pod 'Permission-LocationAlways', :path => "#{permissions_path}/LocationAlways"
  pod 'Permission-LocationWhenInUse', :path => "#{permissions_path}/LocationWhenInUse"
  pod 'Permission-Calendars', :path => "#{permissions_path}/Calendars"
  pod 'Permission-Motion', :path => "#{permissions_path}/Motion"
  pod 'Permission-SpeechRecognition', :path => "#{permissions_path}/SpeechRecognition"
  pod 'Haptica'
  pod 'react-native-sms', :path => '../node_modules/react-native-sms'

  target 'appnameTests' do
    inherit! :search_paths
    # Pods for testing
  end

end

target 'appname-tvOS' do
  # Pods for appname-tvOS

  target 'appname-tvOSTests' do
    inherit! :search_paths
    # Pods for testing
  end
end

post_install do |installer|
  installer.pods_project.build_configurations.each do |config|
      config.build_settings['CODE_SIGNING_ALLOWED'] = 'NO'
  end
end

@Lakston
Copy link

Lakston commented Jul 7, 2023

could it be that the folder structure of our app has an extra folder ?

our folder structure is like this:

main folder
   -> front
      -> src
      -> ios
      -> node_modules
      -> etc...

so it could cause problems with this maybe ?

# Resolve react_native_pods.rb with node to allow for hoisting
require Pod::Executable.execute_command('node', ['-p',
  'require.resolve(
    "react-native/scripts/react_native_pods.rb",
    {paths: [process.argv[1]]},
  )', __dir__]).strip

our folder structure has not changed and everything worked in previous versions, thagts the only change linked to flder structure in 0.72

@Lakston
Copy link

Lakston commented Jul 7, 2023

Ok I found the problem, hopefully if someone ends up here this will provide some pointers:

the problem came from the RN post install not being run, this part:

  post_install do |installer|
    # https://github.com/facebook/react-native/blob/main/packages/react-native/scripts/react_native_pods.rb#L197-L202
    react_native_post_install(
      installer,
      config[:reactNativePath],
      :mac_catalyst_enabled => false
    )
    __apply_Xcode_12_5_M1_post_install_workaround(installer)
  end

I barely understand how RN works but it seems like config[:reactNativePath] not being run was causing the files not found problem

thanks @cipolleschi for your time, have a great day!

@cipolleschi
Copy link
Contributor

Actually, in your podfile, you used to have:

post_install do |installer|
  installer.pods_project.build_configurations.each do |config|
      config.build_settings['CODE_SIGNING_ALLOWED'] = 'NO'
  end
end

with no call to the react_native_post_install! function.

This is not really a React Native (RN) specific thing, but it is how React Native is integrated with Cocoapods (CP) .

CP is mainly used to install dependencies: you specify the dependencies needed in your project and CP downloads and install them, creating a separate Pods project and a workspace for your code to work with the new Pods project.

Then, there could be the need to customize the Pods project and the workspace. CP offers pre_install and post_install hooks to do these customisations.

RN exposes 2 functions:

  1. use_react_native to streamline the dependencies that an app needs from React Native itself. In this way we can encapsulate the complexity of adding all the RN dependencies
  2. react_native_post_install which is a post_install hook that is used to finalize the project and workspace with all the required flags and configurations. This function needs an installer object, so it has to be called in the post_install CP's hook.

Both functions must be called to have a properly initialized project.

I hope this helps to shed some light on how the framework works! :D

@fmorau
Copy link

fmorau commented Jul 25, 2023

@cipolleschi I have both use_react_native and react_native_post_install called properly, in right places.
But still has this issue in both projects which uses ReactCommon/RCTTurboModule.h: react-native-quick-crypto and react-native-jsi-cpr
I've tried to build with and without new architecture just to test - same issue.
Also with new project it works properly somehow, but the difference is only the amount of Pods required in Podfile
Do you have any other ideas what can I look at?

@github-actions github-actions bot added the Needs: Repro This issue could be improved with a clear list of steps to reproduce the issue. label Jul 25, 2023
@github-actions
Copy link

⚠️ Missing Reproducible Example
ℹ️ We could not detect a reproducible example in your issue report. Please provide either:
  • If your bug is UI related: a Snack
  • If your bug is build/update related: use our Reproducer Template. A reproducer needs to be in a GitHub repository under your username.

@cipolleschi
Copy link
Contributor

@chelovekdrakon I'm sorry that this is happening.

Also with new project it works properly somehow, but the difference is only the amount of Pods required in Podfile

If it is working with a newly created project, I think that the issue is in the local configuration of the podfile or of the project.

What are the differences between the two podfiles?

Alternatively, I can investigate the issue if you can create a reproducer using this repo.

The more likely issue is that:

  1. you are using statically linked frameworks
  2. some header is missing from the header search paths

@fmorau
Copy link

fmorau commented Jul 27, 2023

@cipolleschi thanks a lot for your empathy and willingness to help!

I could solve the issue by updating .podspec file of react-native-jsi-cpr : I had to remove s.dependency 'ReactCommon/turbomodule/core' and add s.dependency 'React' to make it work

With react-native-quick-crypto I found that we were launching one script which was needed in the past updating .podspec to replace s.dependency 'React' to 'React-core', so it ended up with two 'React-core' dependencies, which was the issue

Thanks a lot!
Hope it might help somebody in future with similar issues to double check .podspec of libs they have such issue with :)

@buscanopaul
Copy link

buscanopaul commented Aug 3, 2023

Hi @chelovekdrakon I have a same error while upgrading expo from 48 to 49 'ReactCommon/RCTTurboModule.h' file not found

I created a seperate issue about that. Can you walk us through on how you solved the issue? Here's the link expo#23809

@fmorau
Copy link

fmorau commented Aug 4, 2023

@buscanopaul sure!
I've explained everything above. I had to update .podspec file of libraries I had issues with for them to load all dependencies needed

@cipolleschi
Copy link
Contributor

@chelovekdrakon would you mind open PRs on those repository with the fixes so that newer releases of the libraries would not suffer from this problem?

@fmorau
Copy link

fmorau commented Aug 8, 2023

@cipolleschi I worry, that it might break compatibility, because it worked for me before upgrade...

@fmorau
Copy link

fmorau commented Aug 8, 2023

@cipolleschi but Sure, I will 👍 👍
You only know, when you "measure" :)

@cipolleschi
Copy link
Contributor

the thing is that we made some changes between 0.71 and 0.72 in the cocoapods setup in order to support use_frameworks in the New Architecture. So it was expected that some libraries would break and need an update. 😉

@my5201314zwl
Copy link

I double checked that I disabled both hermes and fabric in my podfile:

    :hermes_enabled => false,
    :fabric_enabled => false,

so I dont know why turbomodules would be imported

node_modules/react-native/ReactCommon/react/nativemodule/core/platform/ios/ReactCommon/RCTTurboModule.h:18:9 'ReactCommon/TurboModule.h' file not found

I'm running 0.72.1

I have the same question.

@my5201314zwl
Copy link

Ok I found the problem, hopefully if someone ends up here this will provide some pointers:

the problem came from the RN post install not being run, this part:

  post_install do |installer|
    # https://github.com/facebook/react-native/blob/main/packages/react-native/scripts/react_native_pods.rb#L197-L202
    react_native_post_install(
      installer,
      config[:reactNativePath],
      :mac_catalyst_enabled => false
    )
    __apply_Xcode_12_5_M1_post_install_workaround(installer)
  end

I barely understand how RN works but it seems like config[:reactNativePath] not being run was causing the files not found problem

thanks @cipolleschi for your time, have a great day!

how to do ?

@my5201314zwl
Copy link

my5201314zwl commented Sep 7, 2023

Ok I found the problem, hopefully if someone ends up here this will provide some pointers:
the problem came from the RN post install not being run, this part:

  post_install do |installer|
    react_native_post_install(
      installer,
      config[:reactNativePath],
      :mac_catalyst_enabled => false
    )
    __apply_Xcode_12_5_M1_post_install_workaround(installer)
  end

I barely understand how RN works but it seems like config[:reactNativePath] not being run was causing the files not found problem
thanks @cipolleschi for your time, have a great day!

how to do ?

my podfile:

require Pod::Executable.execute_command('node', ['-p',
  'require.resolve(
    "react-native/scripts/react_native_pods.rb",
    {paths: [process.argv[1]]},
  )', __dir__]).strip

platform :ios, min_ios_version_supported
prepare_react_native_project!


flipper_config = ENV['NO_FLIPPER'] == "1" ? FlipperConfiguration.disabled : FlipperConfiguration.enabled

linkage = ENV['USE_FRAMEWORKS']
if linkage != nil
  Pod::UI.puts "Configuring Pod with #{linkage}ally linked Frameworks".green
  use_frameworks! :linkage => linkage.to_sym
end

target 'AwesomeP1' do
  config = use_native_modules!

  flags = get_default_flags()

  use_react_native!(
    :path => config[:reactNativePath],
    :hermes_enabled => flags[:hermes_enabled],
    :fabric_enabled => flags[:fabric_enabled],
 
    :flipper_configuration => flipper_config,
    :app_path => "#{Pod::Config.instance.installation_root}/.."
  )

  target 'AwesomeP1Tests' do
    inherit! :complete
  end

  post_install do |installer|
      react_native_post_install(
      installer,
      config[:reactNativePath],
      :mac_catalyst_enabled => false
    )
    __apply_Xcode_12_5_M1_post_install_workaround(installer)
  end
end

@sassiwalid
Copy link

Hello everyone, we have update the react version to 0.72 (We use Xcode 14.2) and we get the same issue like you. this our podfile post installer script

post_install do |installer|
  installer.pods_project.targets.each do |target|
    target.build_configurations.each do |config|
      config.build_settings['ARCHS'] = '${ARCHS_STANDARD_64_BIT}'
      if target.name == "React"
        config.build_settings['ENABLE_BITCODE'] = 'NO'
      end
    end
    if target.respond_to?(:product_type) and target.product_type == "com.apple.product-type.bundle"
      target.build_configurations.each do |config|
          config.build_settings['CODE_SIGNING_ALLOWED'] = 'NO'
      end
    end
    react_native_post_install(
        installer,
        config[:reactNativePath],
        :mac_catalyst_enabled => false
    )
  end
end

but sadly we get this error
Capture d’écran 2023-10-03 à 15 10 08

I see that the issue is already open but maybe someone had fixed it hopefully.

regards :)

@cipolleschi
Copy link
Contributor

@sassiwalid can you create a reproducer for it?
We have CI running for our codebase and the pod install command is not failing, meaning that it is actually applying all the changes and there is no undefined object with an unknown config selector, as reported in your error.

Which version of Cocoapods are you using?

@sassiwalid
Copy link

@cipolleschi we use the 1.12.1.

@cipolleschi
Copy link
Contributor

Same one we use in ci and internally. So, if you can create a reproducer using https://github.com/react-native-community/reproducer-react-native, I would be able to investigate what's going on.

I expect that there is some 3rd party library that is messing with the dependencies.

@sassiwalid
Copy link

Hello @cipolleschi thank you what I made and It's work fine for me

post_install do |installer|
  config = use_native_modules!
  react_native_post_install(
      installer,
      config[:reactNativePath],
      :mac_catalyst_enabled => false
    )
  installer.pods_project.targets.each do |target|
    target.build_configurations.each do |config|
      config.build_settings['ARCHS'] = '${ARCHS_STANDARD_64_BIT}'
      if target.name == "React"
        config.build_settings['ENABLE_BITCODE'] = 'NO'
      end
    end
    if target.respond_to?(:product_type) and target.product_type == "com.apple.product-type.bundle"
      target.build_configurations.each do |config|
          config.build_settings['CODE_SIGNING_ALLOWED'] = 'NO'
      end
    end
  end
end

I used config = use_native_modules! to get the appropriate config because my projet uses a native swift package (this is my interpretation for the error) otherwhise I used the 0.72.4 version sadly. I can't use the last version 0.72.5.

@cipolleschi
Copy link
Contributor

I understand. Potentially, you can uplift the config = use_native_modules! outside the target and the post_install calls, so you only need to call it once.

I'm curious, why you can't use 0.72.5?

@adhamabouelela
Copy link

adhamabouelela commented Oct 9, 2023

I tried to implement the post install process like this and the app built successfully with me also, I am using firebase libraries and I'm not using flipper:

Add this block above the target block:

config = use_native_modules!

post_install do |installer_representation|
    react_native_post_install(
    installer_representation,
    config[:reactNativePath],
    :mac_catalyst_enabled => false
  )
  __apply_Xcode_12_5_M1_post_install_workaround(installer_representation)
  installer_representation.pods_project.targets.each do |target|
    target.build_configurations.each do |config|
      config.build_settings['ONLY_ACTIVE_ARCH'] = 'NO'
        if target.name == 'image-slider'
           config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '12.0'
        end
        config.build_settings['BUILD_LIBRARY_FOR_DISTRIBUTION'] = 'No'
        config.build_settings['APPLICATION_EXTENSION_API_ONLY'] = 'No'
    end
    end
  end

Also I ran pod install like this: NO_FLIPPER=1 npx pod-install and I adjusted the react-native-config.js to be like this:
dependencies: {
...(process.env.NO_FLIPPER ? { 'react-native-flipper': { platforms: { ios: null } } } : {}),
}

@assadminhas
Copy link

assadminhas commented Oct 16, 2023

I am facing the same issue since I upgraded my react native and not able to solve it.
Screenshot 2023-10-16 at 6 33 23 PM

React-native: 0.72.3
Pod version: 1.13.0
xcode 15

Here is my Podfile:

require_relative '../node_modules/react-native/scripts/react_native_pods'
require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'

platform :ios, '13.0'
$RNFirebaseAsStaticFramework = true
project 'MyAppNameHere',
    'DevDebug' => :debug,
    'DevRelease' => :release,
    'DebugDevDB' => :debug,
    'ReleaseDevDB' => :release,
    'Debug' => :debug,
    'Release' => :release

# TodoFlipperIOSSetup - Flipper doesn't work with use_frameworks!
use_frameworks!

target 'MyAppNameHere' do

    config = use_native_modules!

    use_react_native!(:path => config[:reactNativePath])

    rn_path = '../node_modules/react-native'
    rn_maps_path = '../node_modules/react-native-maps'

    # Pods for 'MyAppNameHere'
    #Intercom
    pod 'intercom-react-native', :path => '../node_modules/@intercom/intercom-react-native'
    pod 'FBLazyVector', :path => "../node_modules/react-native/Libraries/FBLazyVector"
    pod 'FBReactNativeSpec', :path => "../node_modules/react-native/React/FBReactNativeSpec"
    pod 'RCTRequired', :path => "../node_modules/react-native/Libraries/RCTRequired"
    pod 'RCTTypeSafety', :path => "../node_modules/react-native/Libraries/TypeSafety"
    pod 'React', :path => '../node_modules/react-native/'
    pod 'React-Core', :path => '../node_modules/react-native/'
    pod 'React-CoreModules', :path => '../node_modules/react-native/React/CoreModules'
    pod 'React-Core/DevSupport', :path => '../node_modules/react-native/'
    pod 'React-RCTActionSheet', :path => '../node_modules/react-native/Libraries/ActionSheetIOS'
    pod 'React-RCTAnimation', :path => '../node_modules/react-native/Libraries/NativeAnimation'
    pod 'React-RCTBlob', :path => '../node_modules/react-native/Libraries/Blob'
    pod 'React-RCTImage', :path => '../node_modules/react-native/Libraries/Image'
    pod 'React-RCTLinking', :path => '../node_modules/react-native/Libraries/LinkingIOS'
    pod 'React-RCTNetwork', :path => '../node_modules/react-native/Libraries/Network'
    pod 'React-RCTSettings', :path => '../node_modules/react-native/Libraries/Settings'
    pod 'React-RCTText', :path => '../node_modules/react-native/Libraries/Text'
    pod 'React-RCTVibration', :path => '../node_modules/react-native/Libraries/Vibration'
    pod 'React-Core/RCTWebSocket', :path => '../node_modules/react-native/'
    # Add any other subspecs you want to use in your project

    pod 'React-cxxreact', :path => '../node_modules/react-native/ReactCommon/cxxreact'
    pod 'React-jsi', :path => '../node_modules/react-native/ReactCommon/jsi'
    pod 'React-jsiexecutor', :path => '../node_modules/react-native/ReactCommon/jsiexecutor'
    pod 'React-jsinspector', :path => '../node_modules/react-native/ReactCommon/jsinspector'
    pod 'React-callinvoker', :path => "../node_modules/react-native/ReactCommon/callinvoker"
    pod 'ReactCommon/turbomodule/core', :path => "../node_modules/react-native/ReactCommon"    
    pod 'Yoga', :path => '../node_modules/react-native/ReactCommon/yoga'

    pod 'DoubleConversion', :podspec => '../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec'
    pod 'glog', :podspec => '../node_modules/react-native/third-party-podspecs/glog.podspec'
    pod 'RCT-Folly', :podspec => '../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec'
    pod 'RNRate', :path => '../node_modules/react-native-rate'
    # react native maps


    pod 'DoubleConversion', :podspec => "#{rn_path}/third-party-podspecs/DoubleConversion.podspec"
    pod 'glog', :podspec => "#{rn_path}/third-party-podspecs/glog.podspec"

    pod 'RCT-Folly', :podspec => "#{rn_path}/third-party-podspecs/RCT-Folly.podspec"

    # react-native-maps dependencies
    pod 'react-native-maps', path: rn_maps_path

    pod 'Firebase/Core', '>= 10.2.0'
    pod 'Firebase/Firestore', '>= 10.2.0'

    pod 'XCDYouTubeKit', '~> 2.8'
    pod 'RCTYouTube', :path => '../node_modules/react-native-youtube'

  pod 'RNIap', :path => '../node_modules/react-native-iap'



  pod 'react-native-fbsdk-next', :path => '../node_modules/react-native-fbsdk-next'

  pod 'CodePush', :path => '../node_modules/react-native-code-push'


  
  pod 'RNFBCrashlytics', :path => '../node_modules/@react-native-firebase/crashlytics'

  pod 'RNCAsyncStorage', :path => '../node_modules/@react-native-async-storage/async-storage'

  pod 'RNGoogleSignin', :path => '../node_modules/@react-native-google-signin/google-signin'

  pod 'react-native-geolocation', :path => '../node_modules/@react-native-community/geolocation'

  pod 'RNDeviceInfo', :path => '../node_modules/react-native-device-info'

  pod 'RNBackgroundFetch', :path => '../node_modules/react-native-background-fetch'

  pod 'RNBackgroundGeolocation', :path => '../node_modules/react-native-background-geolocation-android'

  pod 'react-native-camera', :path => '../node_modules/react-native-camera'



  pod 'RNVectorIcons', :path => '../node_modules/react-native-vector-icons'

  pod 'RNGestureHandler', :path => '../node_modules/react-native-gesture-handler'

  pod 'RNSVG', :path => '../node_modules/react-native-svg'

  pod 'RNPermissions', :path => '../node_modules/react-native-permissions'
  permissions_path = '../node_modules/react-native-permissions/ios'

  pod 'Permission-BluetoothPeripheral', :path => "#{permissions_path}/BluetoothPeripheral"
  pod 'Permission-Camera', :path => "#{permissions_path}/Camera"
  pod 'Permission-Contacts', :path => "#{permissions_path}/Contacts"
  pod 'Permission-LocationAccuracy', :path => "#{permissions_path}/LocationAccuracy"
  pod 'Permission-LocationAlways', :path => "#{permissions_path}/LocationAlways"
  pod 'Permission-LocationWhenInUse', :path => "#{permissions_path}/LocationWhenInUse"
  pod 'Permission-Motion', :path => "#{permissions_path}/Motion"
  pod 'Permission-Notifications', :path => "#{permissions_path}/Notifications"
  pod 'Permission-PhotoLibrary', :path => "#{permissions_path}/PhotoLibrary"
  pod 'Permission-StoreKit', :path => "#{permissions_path}/StoreKit"

  pod 'react-native-slider', :path => '../node_modules/@react-native-community/slider'

  pod 'RNReanimated', :path => '../node_modules/react-native-reanimated'

  pod 'react-native-netinfo', :path => '../node_modules/@react-native-community/netinfo'

  pod 'RNFBApp', :path => '../node_modules/@react-native-firebase/app'

  pod 'RNFBAnalytics', :path => '../node_modules/@react-native-firebase/analytics'

  pod 'RNFBAuth', :path => '../node_modules/@react-native-firebase/auth'

  pod 'RNFBDatabase', :path => '../node_modules/@react-native-firebase/database'

  pod 'RNFBDynamicLinks', :path => '../node_modules/@react-native-firebase/dynamic-links'

  pod 'RNFBFirestore', :path => '../node_modules/@react-native-firebase/firestore'

  pod 'RNFBFunctions', :path => '../node_modules/@react-native-firebase/functions'

  pod 'RNFBMessaging', :path => '../node_modules/@react-native-firebase/messaging'

  pod 'RNFBRemoteConfig', :path => '../node_modules/@react-native-firebase/remote-config'

  pod 'RNFBStorage', :path => '../node_modules/@react-native-firebase/storage'

  pod 'react-native-splash-screen', :path => '../node_modules/react-native-splash-screen'

  pod 'react-native-immediate-phone-call', :path => '../node_modules/react-native-immediate-phone-call'


  pod 'RNBackgroundGeolocationFirebase', :path => '../node_modules/react-native-background-geolocation-firebase'

  pod 'RNLocalize', :path => '../node_modules/react-native-localize'

  pod 'RNAppleAuthentication', :path => '../node_modules/@invertase/react-native-apple-authentication'

  pod 'RNDateTimePicker', :path => '../node_modules/@react-native-community/datetimepicker'
  pod 'react-native-safe-area-context', :path => '../node_modules/react-native-safe-area-context'
  pod 'RNCMaskedView', :path => '../node_modules/@react-native-community/masked-view'
  pod 'RNShare', :path => '../node_modules/react-native-share'
  pod 'RNFBPerf', :path => '../node_modules/@react-native-firebase/perf'
  
end
# Convert all permission pods into static libraries
pre_install do |installer|
  Pod::Installer::Xcode::TargetValidator.send(:define_method, :verify_no_static_framework_transitive_dependencies) {}
  
  installer.pod_targets.each do |pod|
    if pod.name.eql?('RNPermissions') || pod.name.start_with?('Permission-')
      def pod.build_type;
        Pod::BuildType.static_library
        end
      end
    end
  end
post_install do |installer|
    installer.pods_project.targets.each do |target|
        if target.name == 'react-native-google-maps'
            target.build_configurations.each do |config|
                config.build_settings['CLANG_ENABLE_MODULES'] = 'No'
            end
        end
        if target.name == "React"
            target.remove_from_project
        end
        # Fix for
        # Typedef redefinition with different types ('uint8_t' (aka 'unsigned char') vs 'enum clockid_t')
        if target.name == "RCT-Folly"
            target.build_configurations.each do |config|
            config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= ['$(inherited)', 'FOLLY_HAVE_CLOCK_GETTIME=1', '_LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION']
            end
        end
        target.build_configurations.each do |config|
          config.build_settings.delete 'IPHONEOS_DEPLOYMENT_TARGET'
        end
    end
    
    ## Fix for XCode 12.5 error Cannot initialize a parameter of type 'NSArray<id<RCTBridgeModule>> *' with an rvalue of type 'NSArray<Class> *'
    ## https://github.com/facebook/react-native/issues/31412#issuecomment-852691640
    find_and_replace("../node_modules/react-native/React/CxxBridge/RCTCxxBridge.mm",
    "_initializeModules:(NSArray<id<RCTBridgeModule>> *)modules", "_initializeModules:(NSArray<Class> *)modules")
    find_and_replace("../node_modules/react-native/ReactCommon/turbomodule/core/platform/ios/RCTTurboModuleManager.mm",
        "RCTBridgeModuleNameForClass(module))", "RCTBridgeModuleNameForClass(Class(module)))")
    # // TodoFlipperIOSSetup - Uncomment
    # flipper_post_install(installer)
end

## Fix for XCode 12.5 error Cannot initialize a parameter of type 'NSArray<id<RCTBridgeModule>> *' with an rvalue of type 'NSArray<Class> *'
## https://github.com/facebook/react-native/issues/31412#issuecomment-852691640
def find_and_replace(dir, findstr, replacestr)
    Dir[dir].each do |name|
        text = File.read(name)
        replace = text.gsub(findstr,replacestr)
        if text != replace
            puts "Fix: " + name
            File.open(name, "w") { |file| file.puts replace }
            STDOUT.flush
        end
    end
    Dir[dir + '*/'].each(&method(:find_and_replace))
end

@wmohamad
Copy link

@assadminhas we are also facing the same issue. Not sure what's going wrong. We are also not upgrading to the New Architecture, not using Flipper and it always gives the error for turbo module file not found. If anyone has worked out a solution for this, please let us know over here 😪

@cipolleschi
Copy link
Contributor

The reason why it is failing is probably because there is some library that is not configured properly.
I'm working on that actively and already found a couple of libraries that were not set up correctly and submitted PRs for them.

The root cause of this problem is the same as #38283 so, please, keep an eye on that issue for a solution.

For the time being:

  • remove all the custom pod 'podname' dependencies from your podfile. For example, all the React-XXX pods are already installed by the use_react_native! function, you should not double define them.
  • remove all the other dependencies from there and use yarn add with auto-linking to add those dependencies. There is logic to configure those dependencies when autolinking run. By bypassing that mechanism, you are basically bypassing all our automations
  • You podfile should look like this. All the other bits of customisation you add is likely to introduce issues, as we test against that template.

Please, try to reproduce the issue on a clean app. If you can't reproduce it, it is likely that your setup is not correct and it is not a React Native issue.

@wkwyatt
Copy link

wkwyatt commented Nov 17, 2023

Can someone please explain what the resolution of the issue was for
fatal error: 'ReactCommon/TurboModuleBinding.h' file not found

I am still having the issue and tried RN versions 0.72.2 - 0.72.7

@assadminhas
Copy link

  • Moving "use_frameworks! :linkage => :static" outside of target

  • Remove all the custom pod 'podname' dependencies from your podfile. For example, all the React-XXX pods are already installed by the use_react_native! function, you should not double define them.

  • and add

    post_install do |installer|
    # https://github.com/facebook/react-native/blob/main/packages/react-native/scripts/react_native_pods.rb#L197-L202
     react_native_post_install(
      installer,
      config[:reactNativePath],
      :mac_catalyst_enabled => false
    )
    __apply_Xcode_12_5_M1_post_install_workaround(installer)
    
    installer.pods_project.targets.each do |target|
      target.build_configurations.each do |config|
        config.build_settings.delete 'IPHONEOS_DEPLOYMENT_TARGET'
      end
    end
  end

inside of target.

Basically "react_native_post_install(
installer,
config[:reactNativePath],
:mac_catalyst_enabled => false
)" adds needed turbo files. but It may cause other issue with Folly or reanimated libs, which can be fixed using patches.

@wkwyatt
Copy link

wkwyatt commented Nov 22, 2023

@assadminhas Do we have to use config[:reactNativePath]?? Is there something special happening there?

Or can I use a path string "../path/to/project"

@assadminhas
Copy link

reactNativePath is a symbol on the config hash and thats how hash keys are accessed in Ruby, by symbol :reactNativePath

If you are facing error with it then make sure to define config = use_native_modules! and

  use_react_native!(
    :path => config[:reactNativePath],
    :hermes_enabled => flags[:hermes_enabled],
    :fabric_enabled => flags[:fabric_enabled],
    :flipper_configuration => FlipperConfiguration.disabled,
    :app_path => "#{Pod::Config.instance.installation_root}/.."
  )

in the target.

Please go through this Podfile to get an idea how it should look like

@wkwyatt
Copy link

wkwyatt commented Nov 25, 2023

@assadminhas Do we have to use config[:reactNativePath]?? Is there something special happening there?

Or can I use a path string "../path/to/project"

I should have specified that the path to the project is not the normal path and would not be just one level up. How do I make sure config[:reactNativePath] has the correct path?

@fdobre
Copy link

fdobre commented Dec 27, 2023

Any idea is this is fixed in RN 0.73? I have tried 0.72.4, 0.72.6 and 0.72.8 and still the same issue....

If I remove the React-xxx workarounds from the Podfile I get back into #38283

@cipolleschi
Copy link
Contributor

@fdobre can you share your Podfile (please, wrap it into ```) and the exact error you are getting?
Chances are that there is some 3rd party library that is failing your build.

@fdobre
Copy link

fdobre commented Dec 28, 2023

@cipolleschi Thank you for your answer.

The error is:
ReactCommon/TurboModuleBinding.h' file not found

Screenshot 2023-12-28 at 17 28 40
#Podfile
# Resolve react_native_pods.rb with node to allow for hoisting
require Pod::Executable.execute_command('node', ['-p',
  'require.resolve(
    "react-native/scripts/react_native_pods.rb",
    {paths: [process.argv[1]]},
  )', __dir__]).strip

platform :ios, min_ios_version_supported
prepare_react_native_project!

flipper_config = FlipperConfiguration.disabled
linkage = ENV['USE_FRAMEWORKS']
if linkage != nil
  Pod::UI.puts "Configuring Pod with #{linkage}ally linked Frameworks".green
  use_frameworks! :linkage => linkage.to_sym
end

install! 'cocoapods', :deterministic_uuids => false
use_frameworks! :linkage => :static
inhibit_all_warnings!

$RNFirebaseAnalyticsWithoutAdIdSupport = true

source 'https://cdn.cocoapods.org/'

target 'WonderPushNotificationServiceExtension' do
  platform :ios, '12.0'

  pod 'WonderPushExtension', '~> 4.0'
end

# We need to switch StreamAMGSDK and its dependancy YouboraLib to a dynamic linking
# else we get duplicate symbols and can't compile the app
# however the React code requires / is set up with static linkage ^^ see use_frameworks
# therefore we are sorting the problem native pods and leaving them dynamic, rather than changing the entire project
$dynamic_library = ['StreamAMGSDK/PlayKit', 'YouboraLib']
pre_install do |installer|
  Pod::Installer::Xcode::TargetValidator.send(:define_method, :verify_no_static_framework_transitive_dependencies) {}
  installer.pod_targets.each do |pod|
    bt = pod.send(:build_type)
    if $dynamic_library.include?(pod.name)
      puts "** #{pod.name} left as dynamic **"
    else
      puts "#{pod.name} static_library"
      def pod.build_type;
      Pod::BuildType.static_library
    end
  end
end
end


target 'MYAPP' do
  config = use_native_modules!
 # Flags change depending on the env values.
  flags = get_default_flags()
  permissions_path = '../node_modules/react-native-permissions/ios'

  use_react_native!(
    :path => config[:reactNativePath],
    :hermes_enabled => flags[:hermes_enabled],
    :fabric_enabled => flags[:fabric_enabled],
    :flipper_configuration => FlipperConfiguration.disabled,
    :app_path => "#{Pod::Config.instance.installation_root}/.."
  )

  pod 'SwiftLint'
  pod 'GoogleAds-IMA-iOS-SDK', '~> 3.18.1'
  pod 'StreamAMGSDK/PlayKit', '1.3.0'
  pod 'XCGLogger', :modular_headers => true
  pod 'ObjcExceptionBridging', :modular_headers => true
  pod 'react-native-google-cast/NoBluetooth', path: '../node_modules/react-native-google-cast/'
  pod 'google-cast-sdk-no-bluetooth'
  pod 'DailymotionPlayerSDK', '4.0.4'

  pod 'Didomi-XCFramework', '1.95.2'

  pod 'Permission-AppTrackingTransparency', :path => "#{permissions_path}/AppTrackingTransparency"
  pod 'Permission-Notifications', :path => "#{permissions_path}/Notifications"

  pod 'Firebase', '~> 10.17.0', :modular_headers => true
  pod 'FirebaseCore', '~> 10.17.0', :modular_headers => true
  pod 'FirebaseCoreInternal', '~> 10.17.0', :modular_headers => true
  pod 'FirebaseCoreExtension', '~> 10.17.0', :modular_headers => true
  pod 'FirebaseInstallations', '~> 10.17.0', :modular_headers => true
  pod 'Firebase/Performance', '~> 10.17.0', :modular_headers => true
  pod 'Firebase/Crashlytics', '~> 10.17.0', :modular_headers => true
  pod 'Firebase/DynamicLinks', '~> 10.17.0', :modular_headers => true
  pod 'FirebaseABTesting', :modular_headers => true
  pod 'FirebaseRemoteConfig', :modular_headers => true
  pod 'GoogleDataTransport', :modular_headers => true
  pod 'nanopb', :modular_headers => true
  pod 'GoogleUtilities', :modular_headers => true

  def append_header_search_path(target, path)
      target.build_configurations.each do |config|
          # Note that there's a space character after `$(inherited)`.
          config.build_settings["HEADER_SEARCH_PATHS"] ||= "$(inherited) "
          config.build_settings["HEADER_SEARCH_PATHS"] << path
      end
  end


  post_install do |installer|
     react_native_post_install(
      installer,
      config[:reactNativePath],
      :mac_catalyst_enabled => false
    )
    __apply_Xcode_12_5_M1_post_install_workaround(installer)
    
    installer.pods_project.targets.each do |target|
      target.build_configurations.each do |config|
        config.build_settings["CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES"] = true
        config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '12.4'
        config.build_settings["HEADER_SEARCH_PATHS"] ||= "$(inherited) "
        config.build_settings["HEADER_SEARCH_PATHS"] << "${PODS_ROOT}/../../node_modules/react-native/ReactCommon"
        if ["React-cxxreact", "React-NativeModulesApple", "React-runtimescheduler", "React-utils", "StreamAMGSDK/PlayKit"].any? { |t| t == target.name }
        end
        config.build_settings.delete 'IPHONEOS_DEPLOYMENT_TARGET'
      end
    end
  end

end

if I comment next lines from post_install:

 config.build_settings["HEADER_SEARCH_PATHS"] ||= "$(inherited) "
  config.build_settings["HEADER_SEARCH_PATHS"] << "${PODS_ROOT}/../../node_modules/react-native/ReactCommon"
   if ["React-cxxreact", "React-NativeModulesApple", "React-runtimescheduler", "React-utils", "StreamAMGSDK/PlayKit"].any? { |t| t == target.name }
   end

Then I run back into 'react/debug/react_native_assert.h' file not found

Screenshot 2023-12-28 at 17 17 03

I am attempting to upgrade RN from 0.69.6 to 0.72.x. I've spent about 2 days with this issue. Any help or suggestion will be greatly appreciated.

I am taking into consideration even advices to downgrades to RN 0.71.x or to upgrades to RN 0.73.x.

@cipolleschi
Copy link
Contributor

cipolleschi commented Dec 28, 2023

Hum... your Podfile is definitely complicated and that would likely be the problem.
As far as I can see, your app is not a pure React Native app, but you have a lot of Native code, right?
I can see several pods that are not React Native libraries but general swift/iOS ones.

As a rule of thumb, if a library is distributed on npm, it should not appear in the Podfile, but you should install it with yarn add <name of the library>.

In this way, autolinking will take care of adding the library to your app and it will configure it properly.

Secondly, you are mixing static and dynamic frameworks with a cocoapods plugin. This is an unofficial configuration which is not a standard in iOS and we do not support it directly. I have evidence of people being successful with it, but it definitely make things more complicated.

Looking at your Podfile, section by section:

# Resolve react_native_pods.rb with node to allow for hoisting
require Pod::Executable.execute_command('node', ['-p',
  'require.resolve(
    "react-native/scripts/react_native_pods.rb",
    {paths: [process.argv[1]]},
  )', __dir__]).strip

platform :ios, min_ios_version_supported
prepare_react_native_project!

flipper_config = FlipperConfiguration.disabled
-linkage = ENV['USE_FRAMEWORKS']
-if linkage != nil
-  Pod::UI.puts "Configuring Pod with #{linkage}ally linked Frameworks".green
-  use_frameworks! :linkage => linkage.to_sym
-end

install! 'cocoapods', :deterministic_uuids => false
use_frameworks! :linkage => :static
inhibit_all_warnings!

$RNFirebaseAnalyticsWithoutAdIdSupport = true

source 'https://cdn.cocoapods.org/'

you can remove this section because you are setting use_frameworks! :linkage => :static manually.

target 'WonderPushNotificationServiceExtension' do
  platform :ios, '12.0'

  pod 'WonderPushExtension', '~> 4.0'
end

# We need to switch StreamAMGSDK and its dependancy YouboraLib to a dynamic linking
# else we get duplicate symbols and can't compile the app
# however the React code requires / is set up with static linkage ^^ see use_frameworks
# therefore we are sorting the problem native pods and leaving them dynamic, rather than changing the entire project
$dynamic_library = ['StreamAMGSDK/PlayKit', 'YouboraLib']
pre_install do |installer|
  Pod::Installer::Xcode::TargetValidator.send(:define_method, :verify_no_static_framework_transitive_dependencies) {}
  installer.pod_targets.each do |pod|
    bt = pod.send(:build_type)
    if $dynamic_library.include?(pod.name)
      puts "** #{pod.name} left as dynamic **"
    else
      puts "#{pod.name} static_library"
      def pod.build_type;
      Pod::BuildType.static_library
    end
  end
end
- end

This last end seems to be an extra end. Which statement is it closing? Probably it is a typo as the Podfile would not work otherwise.
Also, Youbora does not specify anything related to frameworks. What happen if we remove the all patch from $dynamic_library to the second end?

target 'MYAPP' do
  config = use_native_modules!
 # Flags change depending on the env values.
  flags = get_default_flags()
  permissions_path = '../node_modules/react-native-permissions/ios'

  use_react_native!(
    :path => config[:reactNativePath],
    :hermes_enabled => flags[:hermes_enabled],
    :fabric_enabled => flags[:fabric_enabled],
    :flipper_configuration => FlipperConfiguration.disabled,
    :app_path => "#{Pod::Config.instance.installation_root}/.."
  )

  pod 'SwiftLint'
  pod 'GoogleAds-IMA-iOS-SDK', '~> 3.18.1'
  pod 'StreamAMGSDK/PlayKit', '1.3.0'
  pod 'XCGLogger', :modular_headers => true
  pod 'ObjcExceptionBridging', :modular_headers => true
- pod 'react-native-google-cast/NoBluetooth', path: '../node_modules/react-native-google-cast/'
- pod 'google-cast-sdk-no-bluetooth'
  pod 'DailymotionPlayerSDK', '4.0.4'

- pod 'Didomi-XCFramework', '1.95.2'

-  pod 'Permission-AppTrackingTransparency', :path => "#{permissions_path}/AppTrackingTransparency"
- pod 'Permission-Notifications', :path => "#{permissions_path}/Notifications"

- pod 'Firebase', '~> 10.17.0', :modular_headers => true
- pod 'FirebaseCore', '~> 10.17.0', :modular_headers => true
- pod 'FirebaseCoreInternal', '~> 10.17.0', :modular_headers => true
- pod 'FirebaseCoreExtension', '~> 10.17.0', :modular_headers => true
- pod 'FirebaseInstallations', '~> 10.17.0', :modular_headers => true
- pod 'Firebase/Performance', '~> 10.17.0', :modular_headers => true
- pod 'Firebase/Crashlytics', '~> 10.17.0', :modular_headers => true
- pod 'Firebase/DynamicLinks', '~> 10.17.0', :modular_headers => true
- pod 'FirebaseABTesting', :modular_headers => true
- pod 'FirebaseRemoteConfig', :modular_headers => true
- pod 'GoogleDataTransport', :modular_headers => true
  pod 'nanopb', :modular_headers => true
- pod 'GoogleUtilities', :modular_headers => true

For react-native-google-cast/NoBluetooth, use the react-native-google-cast library (you are already picking it from node_modules, so just remove the line.
For Didomi, use the react-native-package as described here
For Permissions, install react-native-permissions from here

For all the Firebase packages, use the React Native Firebase implementation as described here. This should also install the GoogleDataTransport and the GoogleUtilities pods.

- def append_header_search_path(target, path)
-      target.build_configurations.each do |config|
-          # Note that there's a space character after `$(inherited)`.
-          config.build_settings["HEADER_SEARCH_PATHS"] ||= "$(inherited) "
-          config.build_settings["HEADER_SEARCH_PATHS"] << path
-      end
-  end


  post_install do |installer|
     react_native_post_install(
      installer,
      config[:reactNativePath],
      :mac_catalyst_enabled => false
    )
    __apply_Xcode_12_5_M1_post_install_workaround(installer)
    
-    installer.pods_project.targets.each do |target|
-      target.build_configurations.each do |config|
-        config.build_settings["CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES"] = true
-        config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '12.4'
-        config.build_settings["HEADER_SEARCH_PATHS"] ||= "$(inherited) "
-        config.build_settings["HEADER_SEARCH_PATHS"] << "${PODS_ROOT}/../../node_modules/react-native/ReactCommon"
-        if ["React-cxxreact", "React-NativeModulesApple", "React-runtimescheduler", "React-utils", "StreamAMGSDK/PlayKit"].any? { |t| t == target.name }
-        end
-        config.build_settings.delete 'IPHONEOS_DEPLOYMENT_TARGET'
-      end
-    end
  end

end

Our cocoapods infra should take care of all these steps.

--

Now, after these changes, your project might be quite dirty.

  1. Navigate back to the root of your project and run the yarn add for all the libraries you were managing manually
  2. Let's do a bit of cleanup by, navigating to the iOS folder and then:
bundle install
bundle exec pod deintegrate # this cleans up all the pods and remove all the dirt
bundle exec pod install

Let me know if this work.
We have CI jobs that create React Native apps using Static Frameworks, so I am sure that they work.

Your setup is complex and does not follow all the suggested practices, so it will be hard to fix it, but we can make it work.

@fdobre
Copy link

fdobre commented Jan 3, 2024

@cipolleschi I have applied the changes your recommended (except a few, I had to keep that end that is required by its above def, code wasn't formatted well, keeping the Firebase pods because removing those trigger a lot of pod install errors) and I can confirm that right now the build process goes well beyond the phase it used to crash before.

Right now it's crashing inside the Didomi native code (I will have to replace that with react-native-didomi). Probably it will crash in the StreamAMG native code too, that one will have to be replaced with rn-jwplayer.

Upgrading RN in my project from 0.69 to 0.72.x will be a huge effort. I will come back here immediately after I have a fully functional Podfile.

Big thank you for all your suggestions!

@andreimarkoff
Copy link

@assadminhas Do we have to use config[:reactNativePath]?? Is there something special happening there?
Or can I use a path string "../path/to/project"

I should have specified that the path to the project is not the normal path and would not be just one level up. How do I make sure config[:reactNativePath] has the correct path?

any info on that? 🙏 @wkwyatt @cipolleschi

@cipolleschi
Copy link
Contributor

@andreimarkoff what's the question, exactly? This isssue is 7 month old, I'll need some more info to try and help you... 😅

@andreimarkoff
Copy link

andreimarkoff commented May 27, 2024

@cipolleschi thank you for getting back to me and sorry for late reply.

I am trying to use react native components in existing iOS app, but I am not adding my existing iOS app as a subfolder of react native project, and for that thats how I modified the podfile of an iOS project:

require_relative '../react-native-project-app/node_modules/react-native/scripts/react_native_pods'
require_relative '../react-native-project-app/node_modules/@react-native-community/cli-platform-ios/native_modules'
platform :ios, '14.0'

project 'App', 'App Store' => :release, 'Debug' => :debug, 'Internal Release' => :release


def common_pods
  pod 'IGListKit', '4.0.0'
  pod 'Stripe', '19.4.1'
  pod 'Branch', '1.39.3'
  pod 'Apollo', '0.24.1'
  pod 'LaunchDarkly', '8.0.0'
  pod 'SwiftKeychainWrapper', '3.4.0'
  pod 'ReactiveCocoa', '10.2.0'
  pod 'Analytics', '4.1.6'
end

target 'App' do
  use_frameworks! :linkage => :static
  use_react_native!(
    :hermes_enabled => false,
    :fabric_enabled => false,
    :flipper_configuration => FlipperConfiguration.disabled,
    :app_path => "/Users/andreimarkov/react-native-project-app"
  )

  common_pods
  pod 'pop', '1.0.10'

  target 'AppTests' do
    inherit! :search_paths
  end
post_install do |installer|
    # https://github.com/facebook/react-native/blob/main/packages/react-native/scripts/react_native_pods.rb#L197-L202
    react_native_post_install(
      installer,
      :mac_catalyst_enabled => false,
      # :ccache_enabled => true
    )
    
    installer.pods_project.targets.each do |target|
      target.build_configurations.each do |config|
        config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '12.0'
      end
    end
  end

as you can see I dont have :path => config[:reactNativePath]
so the question is can I hardcode the path for that like I did for the app_path?
Thank you

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Needs: Repro This issue could be improved with a clear list of steps to reproduce the issue. Needs: Triage 🔍 Platform: iOS iOS applications. Type: Upgrade Issue Issues reported from upgrade issue form
Projects
None yet
Development

No branches or pull requests