facebook / react-native

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

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

Closed toscalivia83 closed 1 year ago

toscalivia83 commented 1 year ago

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:

Steps to reproduce

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

Screenshot 2023-06-25 at 23 33 47
cipolleschi commented 1 year ago

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 commented 1 year ago

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 commented 1 year ago

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

cipolleschi commented 1 year ago

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 commented 1 year ago

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 commented 1 year ago

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 commented 1 year ago

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

harouf commented 1 year ago

I am also facing the same issue. Any workaround?

Lakston commented 1 year ago

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 commented 1 year ago

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 commented 1 year ago

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 commented 1 year ago

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 commented 1 year ago
  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 commented 1 year ago

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 commented 1 year ago

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 commented 1 year ago

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 commented 1 year ago

@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[bot] commented 1 year ago
:warning: Missing Reproducible Example
:information_source: 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 commented 1 year ago

@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 commented 1 year ago

@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 commented 1 year ago

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 commented 1 year ago

@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 commented 1 year ago

@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 commented 1 year ago

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

fmorau commented 1 year ago

@cipolleschi but Sure, I will πŸ‘ πŸ‘ You only know, when you "measure" :)

cipolleschi commented 1 year ago

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 commented 1 year ago

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 commented 1 year ago

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 commented 1 year ago

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 commented 1 year ago

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 aΜ€ 15 10 08

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

regards :)

cipolleschi commented 1 year ago

@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 commented 1 year ago

@cipolleschi we use the 1.12.1.

cipolleschi commented 1 year ago

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 commented 1 year ago

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 commented 1 year ago

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 commented 1 year ago

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 commented 1 year ago

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 commented 1 year ago

@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 commented 1 year ago

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:

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 commented 11 months ago

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 commented 11 months ago
    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_catalystenabled => false )" adds needed turbo files. but It may cause other issue with Folly or reanimated libs, which can be fixed using patches.

wkwyatt commented 11 months ago

@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 commented 11 months ago

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 commented 11 months ago

@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 commented 10 months ago

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 https://github.com/facebook/react-native/issues/38283

cipolleschi commented 10 months ago

@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 commented 10 months ago

@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 commented 10 months ago

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 commented 10 months ago

@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 commented 5 months ago

@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