From 1204696f08c91e17154d5b9c946d7fe8532510de Mon Sep 17 00:00:00 2001 From: Riccardo Cipolleschi Date: Fri, 17 Nov 2023 04:17:58 -0800 Subject: [PATCH] Defragment Codegen in OSS between Old and New Architecture (#41500) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/41500 Right now, the old architecture uses Codegen in a slightly different way w.r.t. the New Architecture. In the Old Architecture, codegen is used to generate some basic TM and components that are part of Core. Both architectures use the same scripts that actually generates the code, but they are invoked differently. This is causing some maintenance costs that we would like to reduce. ## Changelog: [Internal] - Defragment how Codegen is run between old and new architecture Reviewed By: dmytrorykun Differential Revision: D51349874 fbshipit-source-id: 188d3ed436a30a77bd42a26306d4a08666d3a00b --- .../FBReactNativeSpec.podspec | 58 ----- .../ReactCommon/React-rncore.podspec | 9 - .../cocoapods/__tests__/codegen-test.rb | 217 ------------------ .../cocoapods/__tests__/codegen_utils-test.rb | 3 - .../__tests__/new_architecture-test.rb | 17 +- .../react-native/scripts/cocoapods/codegen.rb | 75 +----- .../scripts/cocoapods/codegen_utils.rb | 7 - .../scripts/cocoapods/new_architecture.rb | 54 ++--- .../react-native/scripts/cocoapods/utils.rb | 16 ++ .../codegen/generate-artifacts-executor.js | 82 +++---- .../react-native/scripts/react_native_pods.rb | 104 +-------- .../MyNativeView.podspec | 8 - .../ScreenshotManager.podspec | 9 - packages/rn-tester/Podfile | 7 +- packages/rn-tester/Podfile.lock | 82 +++++-- 15 files changed, 165 insertions(+), 583 deletions(-) delete mode 100644 packages/react-native/React/FBReactNativeSpec/FBReactNativeSpec.podspec diff --git a/packages/react-native/React/FBReactNativeSpec/FBReactNativeSpec.podspec b/packages/react-native/React/FBReactNativeSpec/FBReactNativeSpec.podspec deleted file mode 100644 index 4480a83562a479..00000000000000 --- a/packages/react-native/React/FBReactNativeSpec/FBReactNativeSpec.podspec +++ /dev/null @@ -1,58 +0,0 @@ -# Copyright (c) Meta Platforms, Inc. and affiliates. -# -# This source code is licensed under the MIT license found in the -# LICENSE file in the root directory of this source tree. - -require "json" - -react_native_path = "../.." -require_relative "#{react_native_path}/scripts/react_native_pods.rb" - -package = JSON.parse(File.read(File.join(__dir__, "..", "..", "package.json"))) -version = package['version'] - -source = { :git => 'https://github.com/facebook/react-native.git' } -if version == '1000.0.0' - # This is an unpublished version, use the latest commit hash of the react-native repo, which we’re presumably in. - source[:commit] = `git rev-parse HEAD`.strip if system("git rev-parse --git-dir > /dev/null 2>&1") -else - source[:tag] = "v#{version}" -end - -folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -DFOLLY_CFG_NO_COROUTINES=1 -DFOLLY_HAVE_CLOCK_GETTIME=1 -Wno-comma -Wno-shorten-64-to-32' -folly_version = '2023.08.07.00' - -Pod::Spec.new do |s| - s.name = "FBReactNativeSpec" - s.version = version - s.summary = "-" # TODO - s.homepage = "https://reactnative.dev/" - s.license = package["license"] - s.author = "Meta Platforms, Inc. and its affiliates" - s.platforms = min_supported_versions - s.compiler_flags = folly_compiler_flags + ' -Wno-nullability-completeness' - s.source = source - # This podspec is used to trigger the codegen, and built files are generated in a different location. - # We don't want this pod to actually include any files. - s.header_dir = "FBReactNativeSpec" - - s.pod_target_xcconfig = { - "USE_HEADERMAP" => "YES", - "CLANG_CXX_LANGUAGE_STANDARD" => "c++20", - "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/RCT-Folly\"" - } - - s.dependency "RCT-Folly", folly_version - s.dependency "RCTRequired", version - s.dependency "RCTTypeSafety", version - s.dependency "React-Core", version - s.dependency "React-jsi", version - s.dependency "ReactCommon/turbomodule/core", version - - use_react_native_codegen!(s, { - :react_native_path => react_native_path, - :js_srcs_dir => "#{react_native_path}/Libraries", - :library_name => "FBReactNativeSpec", - :library_type => "modules", - }) -end diff --git a/packages/react-native/ReactCommon/React-rncore.podspec b/packages/react-native/ReactCommon/React-rncore.podspec index a4532697403bcb..06b8bc7feff1b7 100644 --- a/packages/react-native/ReactCommon/React-rncore.podspec +++ b/packages/react-native/ReactCommon/React-rncore.podspec @@ -49,13 +49,4 @@ Pod::Spec.new do |s| s.pod_target_xcconfig = { "USE_HEADERMAP" => "YES", "HEADER_SEARCH_PATHS" => header_search_paths.join(' '), "CLANG_CXX_LANGUAGE_STANDARD" => "c++20" } - - - use_react_native_codegen!(s, { - :react_native_path => react_native_sources_path, - :js_srcs_dir => "#{react_native_sources_path}/Libraries", - :library_name => "rncore", - :library_type => "components", - :output_dir => "#{react_native_dependency_path}/ReactCommon" - }) end diff --git a/packages/react-native/scripts/cocoapods/__tests__/codegen-test.rb b/packages/react-native/scripts/cocoapods/__tests__/codegen-test.rb index 6987399ad87f6d..3fcce19e09d728 100644 --- a/packages/react-native/scripts/cocoapods/__tests__/codegen-test.rb +++ b/packages/react-native/scripts/cocoapods/__tests__/codegen-test.rb @@ -40,191 +40,6 @@ def teardown DirMock.reset() end - # ============================================== # - # Test - setup_fabric # - # ============================================== # - def testCheckAndGenerateEmptyThirdPartyProvider_whenFileAlreadyExists_doNothing() - - # Arrange - FileMock.mocked_existing_files([ - @base_path + "/" + @prefix + "/React/Fabric/" + @third_party_provider_header, - @base_path + "/" + @prefix + "/React/Fabric/" + @third_party_provider_implementation, - ]) - - # Act - checkAndGenerateEmptyThirdPartyProvider!(@prefix, false, dir_manager: DirMock, file_manager: FileMock) - - # Assert - assert_equal(Pathname.pwd_invocation_count, 1) - assert_equal(Pod::Config.instance.installation_root.relative_path_from_invocation_count, 1) - assert_equal(FileMock.exist_invocation_params, [ - @base_path + "/" + @prefix + "/React/Fabric/" + @third_party_provider_header, - @base_path + "/" + @prefix + "/React/Fabric/" + @third_party_provider_implementation, - ]) - assert_equal(DirMock.exist_invocation_params, []) - assert_equal(Pod::UI.collected_messages, []) - assert_equal($collected_commands, []) - assert_equal(FileMock.open_files.length, 0) - assert_equal(Pod::Executable.executed_commands.length, 0) - end - - def testCheckAndGenerateEmptyThirdPartyProvider_whenHeaderMissingAndCodegenMissing_dontBuildCodegen() - - # Arrange - FileMock.mocked_existing_files([ - @base_path + "/build/" + @third_party_provider_implementation, - ]) - - # Act - assert_nothing_raised { - checkAndGenerateEmptyThirdPartyProvider!(@prefix, false, dir_manager: DirMock, file_manager: FileMock) - } - - # Assert - assert_equal(Pathname.pwd_invocation_count, 1) - assert_equal(Pod::Config.instance.installation_root.relative_path_from_invocation_count, 1) - assert_equal(FileMock.exist_invocation_params, [ - @base_path + "/" + @prefix + "/React/Fabric/" + @third_party_provider_header, - @base_path + "/" + @prefix + "/React/Fabric/tmpSchemaList.txt", - ]) - assert_equal(DirMock.exist_invocation_params, [ - @base_path + "/"+ @prefix + "/../react-native-codegen", - ]) - assert_equal(Pod::UI.collected_messages, [ - "[Codegen] generating an empty RCTThirdPartyFabricComponentsProvider", - ]) - assert_equal($collected_commands, []) - assert_equal(FileMock.open_files.length, 1) - assert_equal(Pod::Executable.executed_commands.length, 1) - end - - def testCheckAndGenerateEmptyThirdPartyProvider_whenImplementationMissingAndCodegenrepoExists_dontBuildCodegen() - - # Arrange - FileMock.mocked_existing_files([ - @base_path + "/" + @prefix + "/React/Fabric/" + @third_party_provider_header, - @base_path + "/" + @prefix + "/React/Fabric/tmpSchemaList.txt" - ]) - - DirMock.mocked_existing_dirs([ - @base_path + "/"+ @prefix + "/../react-native-codegen", - @base_path + "/"+ @prefix + "/../react-native-codegen/lib" - ]) - - # Act - checkAndGenerateEmptyThirdPartyProvider!(@prefix, false, dir_manager: DirMock, file_manager: FileMock) - - # Assert - assert_equal(Pathname.pwd_invocation_count, 1) - assert_equal(Pod::Config.instance.installation_root.relative_path_from_invocation_count, 1) - assert_equal(FileMock.exist_invocation_params, [ - @base_path + "/" + @prefix + "/React/Fabric/" + @third_party_provider_header, - @base_path + "/" + @prefix + "/React/Fabric/" + @third_party_provider_implementation, - @base_path + "/" + @prefix + "/React/Fabric/tmpSchemaList.txt", - ]) - assert_equal(DirMock.exist_invocation_params, [ - @base_path + "/"+ @prefix + "/../react-native-codegen", - @base_path + "/"+ @prefix + "/../react-native-codegen/lib", - ]) - assert_equal(Pod::UI.collected_messages, ["[Codegen] generating an empty RCTThirdPartyFabricComponentsProvider"]) - assert_equal($collected_commands, []) - assert_equal(FileMock.open_invocation_count, 1) - assert_equal(FileMock.open_files_with_mode[@prefix + "/React/Fabric/tmpSchemaList.txt"], nil) - assert_equal(FileMock.open_files[0].collected_write, ["[]"]) - assert_equal(FileMock.open_files[0].fsync_invocation_count, 1) - assert_equal(Pod::Executable.executed_commands[0], { - "command" => "node", - "arguments" => [ - @base_path + "/" + @prefix + "/scripts/generate-provider-cli.js", - "--platform", 'ios', - "--schemaListPath", @base_path + "/" + @prefix + "/React/Fabric/tmpSchemaList.txt", - "--outputDir", @base_path + "/" + @prefix + "/React/Fabric" - ] - }) - assert_equal(FileMock.delete_invocation_count, 1) - assert_equal(FileMock.deleted_files, [ @base_path + "/" + @prefix + "/React/Fabric/tmpSchemaList.txt"]) - end - - def testCheckAndGenerateEmptyThirdPartyProvider_whenBothMissing_buildCodegen() - # Arrange - codegen_cli_path = @base_path + "/" + @prefix + "/../react-native-codegen" - DirMock.mocked_existing_dirs([ - codegen_cli_path, - ]) - # Act - checkAndGenerateEmptyThirdPartyProvider!(@prefix, false, dir_manager: DirMock, file_manager: FileMock) - - # Assert - assert_equal(Pathname.pwd_invocation_count, 1) - assert_equal(Pod::Config.instance.installation_root.relative_path_from_invocation_count, 1) - assert_equal(FileMock.exist_invocation_params, [ - @base_path + "/" + @prefix + "/React/Fabric/" + @third_party_provider_header, - @base_path + "/" + @prefix + "/React/Fabric/" + @tmp_schema_list_file - ]) - assert_equal(DirMock.exist_invocation_params, [ - codegen_cli_path, - codegen_cli_path + "/lib", - ]) - assert_equal(Pod::UI.collected_messages, [ - "[Codegen] building #{codegen_cli_path}", - "[Codegen] generating an empty RCTThirdPartyFabricComponentsProvider" - ]) - assert_equal($collected_commands, ["~/app/ios/../../../react-native-codegen/scripts/oss/build.sh"]) - assert_equal(FileMock.open_files[0].collected_write, ["[]"]) - assert_equal(FileMock.open_files[0].fsync_invocation_count, 1) - assert_equal(Pod::Executable.executed_commands[0], { - "command" => "node", - "arguments" => [ - @base_path + "/" + @prefix + "/scripts/generate-provider-cli.js", - "--platform", 'ios', - "--schemaListPath", @base_path + "/" + @prefix + "/React/Fabric/" + @tmp_schema_list_file, - "--outputDir", @base_path + "/" + @prefix + "/React/Fabric" - ] - }) - end - - def testCheckAndGenerateEmptyThirdPartyProvider_withAbsoluteReactNativePath_buildCodegen() - # Arrange - rn_path = 'packages/react-native' - codegen_cli_path = rn_path + "/../react-native-codegen" - DirMock.mocked_existing_dirs([ - @base_path + "/" + codegen_cli_path, - ]) - - # Act - checkAndGenerateEmptyThirdPartyProvider!(rn_path, false, dir_manager: DirMock, file_manager: FileMock) - - # Assert - assert_equal(Pathname.pwd_invocation_count, 1) - assert_equal(Pod::Config.instance.installation_root.relative_path_from_invocation_count, 1) - assert_equal(FileMock.exist_invocation_params, [ - @base_path + "/" + rn_path + "/React/Fabric/" + @third_party_provider_header, - @base_path + "/" + rn_path + "/React/Fabric/" + @tmp_schema_list_file - ]) - assert_equal(DirMock.exist_invocation_params, [ - @base_path + "/" + codegen_cli_path, - @base_path + "/" + codegen_cli_path + "/lib", - ]) - assert_equal(Pod::UI.collected_messages, [ - "[Codegen] building #{@base_path + "/" + codegen_cli_path}", - "[Codegen] generating an empty RCTThirdPartyFabricComponentsProvider" - ]) - assert_equal($collected_commands, [ - @base_path + "/" + rn_path + "/../react-native-codegen/scripts/oss/build.sh", - ]) - assert_equal(FileMock.open_files[0].collected_write, ["[]"]) - assert_equal(FileMock.open_files[0].fsync_invocation_count, 1) - assert_equal(Pod::Executable.executed_commands[0], { - "command" => "node", - "arguments" => [ - @base_path + "/" + rn_path + "/scripts/generate-provider-cli.js", - "--platform", 'ios', - "--schemaListPath", @base_path + "/" + rn_path + "/React/Fabric/" + @tmp_schema_list_file, - "--outputDir", @base_path + "/" + rn_path + "/React/Fabric" - ] - }) - end - # ================= # # Test - RunCodegen # # ================= # @@ -250,36 +65,4 @@ def testRunCodegen_whenNewArchEnabled_runsCodegen assert_equal(codegen_utils_mock.get_react_codegen_spec_params, []) assert_equal(codegen_utils_mock.generate_react_codegen_spec_params, []) end - - def testRunCodegen_whenNewArchDisabled_runsCodegen - # Arrange - app_path = "~/app" - config_file = "" - package_json_file = "~/app/package.json" - codegen_specs = { "name" => "React-Codegen" } - codegen_utils_mock = CodegenUtilsMock.new(:react_codegen_spec => codegen_specs) - - # Act - run_codegen!( - app_path, - config_file, - :new_arch_enabled => false, - :fabric_enabled => true, - :package_json_file => package_json_file, - :codegen_utils => codegen_utils_mock) - - # Assert - assert_equal(codegen_utils_mock.use_react_native_codegen_discovery_params, []) - assert_equal(codegen_utils_mock.get_react_codegen_spec_params, [{ - :fabric_enabled => true, - :folly_version=>"2023.08.07.00", - :package_json_file => "~/app/package.json", - :script_phases => nil - }]) - assert_equal(codegen_utils_mock.generate_react_codegen_spec_params, [{ - :codegen_output_dir=>"build/generated/ios", - :react_codegen_spec=>{"name"=>"React-Codegen"} - }]) - - end end diff --git a/packages/react-native/scripts/cocoapods/__tests__/codegen_utils-test.rb b/packages/react-native/scripts/cocoapods/__tests__/codegen_utils-test.rb index 6dd22eb30142b7..1891202664c4cc 100644 --- a/packages/react-native/scripts/cocoapods/__tests__/codegen_utils-test.rb +++ b/packages/react-native/scripts/cocoapods/__tests__/codegen_utils-test.rb @@ -561,14 +561,12 @@ def get_podspec_no_fabric_no_script }, 'dependencies': { "DoubleConversion": [], - "FBReactNativeSpec": [], "RCT-Folly": [], "RCTRequired": [], "RCTTypeSafety": [], "React-Core": [], "React-jsi": [], "React-jsiexecutor": [], - "React-rncore": [], "ReactCommon/turbomodule/bridging": [], "ReactCommon/turbomodule/core": [], "hermes-engine": [], @@ -583,7 +581,6 @@ def get_podspec_fabric_and_script_phases(script_phases) specs[:dependencies].merge!({ 'React-graphics': [], - 'React-rncore': [], 'React-Fabric': [], 'React-utils': [], 'React-debug': [], diff --git a/packages/react-native/scripts/cocoapods/__tests__/new_architecture-test.rb b/packages/react-native/scripts/cocoapods/__tests__/new_architecture-test.rb index 9dcd4a3f15b0d2..fc698ae2166940 100644 --- a/packages/react-native/scripts/cocoapods/__tests__/new_architecture-test.rb +++ b/packages/react-native/scripts/cocoapods/__tests__/new_architecture-test.rb @@ -188,7 +188,22 @@ def test_installModulesDependencies_whenNewArchDisabledAndSearchPathsAndCompiler [ { :dependency_name => "React-Core" }, { :dependency_name => "RCT-Folly", "version"=>"2023.08.07.00" }, - { :dependency_name => "glog" } + { :dependency_name => "glog" }, + { :dependency_name => "React-RCTFabric" }, + { :dependency_name => "React-Codegen" }, + { :dependency_name => "RCTRequired" }, + { :dependency_name => "RCTTypeSafety" }, + { :dependency_name => "ReactCommon/turbomodule/bridging" }, + { :dependency_name => "ReactCommon/turbomodule/core" }, + { :dependency_name => "React-NativeModulesApple" }, + { :dependency_name => "Yoga" }, + { :dependency_name => "React-Fabric" }, + { :dependency_name => "React-graphics" }, + { :dependency_name => "React-utils" }, + { :dependency_name => "React-debug" }, + { :dependency_name => "React-ImageManager" }, + { :dependency_name => "React-rendererdebug" }, + { :dependency_name => "hermes-engine" } ] ) end diff --git a/packages/react-native/scripts/cocoapods/codegen.rb b/packages/react-native/scripts/cocoapods/codegen.rb index 7842f39f4226c5..4c1ac3dc6b59e5 100644 --- a/packages/react-native/scripts/cocoapods/codegen.rb +++ b/packages/react-native/scripts/cocoapods/codegen.rb @@ -18,47 +18,7 @@ def build_codegen!(react_native_path, relative_installation_root, dir_manager: D system("#{codegen_repo_path}/scripts/oss/build.sh") end -# It generates an empty `ThirdPartyProvider`, required by Fabric to load the components -# -# Parameters: -# - react_native_path: path to the react native framework -# - new_arch_enabled: whether the New Architecture is enabled or not -# - dir_manager: a class that implements the `Dir` interface. Defaults to `Dir`, the Dependency can be injected for testing purposes. -# - file_manager: a class that implements the `File` interface. Defaults to `File`, the Dependency can be injected for testing purposes. -def checkAndGenerateEmptyThirdPartyProvider!(react_native_path, new_arch_enabled, dir_manager: Dir, file_manager: File) - return if new_arch_enabled - - relative_installation_root = Pod::Config.instance.installation_root.relative_path_from(Pathname.pwd) - - output_dir = "#{relative_installation_root}/#{react_native_path}/React/Fabric" - - provider_h_path = "#{output_dir}/RCTThirdPartyFabricComponentsProvider.h" - provider_cpp_path ="#{output_dir}/RCTThirdPartyFabricComponentsProvider.mm" - - if(!file_manager.exist?(provider_h_path) || !file_manager.exist?(provider_cpp_path)) - # build codegen - build_codegen!(react_native_path, relative_installation_root, dir_manager: dir_manager) - - # Just use a temp empty schema list. - temp_schema_list_path = "#{output_dir}/tmpSchemaList.txt" - file_manager.open(temp_schema_list_path, 'w') do |f| - f.write('[]') - f.fsync - end - - Pod::UI.puts '[Codegen] generating an empty RCTThirdPartyFabricComponentsProvider' - Pod::Executable.execute_command( - 'node', - [ - "#{basePath(react_native_path, relative_installation_root)}/scripts/generate-provider-cli.js", - "--platform", 'ios', - "--schemaListPath", temp_schema_list_path, - "--outputDir", "#{output_dir}" - ]) - file_manager.delete(temp_schema_list_path) if file_manager.exist?(temp_schema_list_path) - end -end - +# keeping the run_codegen! method for testing purposes def run_codegen!( app_path, config_file_dir, @@ -74,28 +34,17 @@ def run_codegen!( codegen_utils: CodegenUtils.new() ) - if new_arch_enabled - codegen_utils.use_react_native_codegen_discovery!( - disable_codegen, - app_path, - :react_native_path => react_native_path, - :fabric_enabled => fabric_enabled, - :hermes_enabled => hermes_enabled, - :config_file_dir => config_file_dir, - :codegen_output_dir => codegen_output_dir, - :config_key => config_key, - :folly_version => folly_version - ) - else - # Generate a podspec file for generated files. - # This gets generated in use_react_native_codegen_discovery when codegen discovery is enabled. - react_codegen_spec = codegen_utils.get_react_codegen_spec( - package_json_file, - :fabric_enabled => fabric_enabled, - :hermes_enabled => hermes_enabled - ) - codegen_utils.generate_react_codegen_podspec!(react_codegen_spec, codegen_output_dir) - end + codegen_utils.use_react_native_codegen_discovery!( + disable_codegen, + app_path, + :react_native_path => react_native_path, + :fabric_enabled => fabric_enabled, + :hermes_enabled => hermes_enabled, + :config_file_dir => config_file_dir, + :codegen_output_dir => codegen_output_dir, + :config_key => config_key, + :folly_version => folly_version + ) end def basePath(react_native_path, relative_installation_root) diff --git a/packages/react-native/scripts/cocoapods/codegen_utils.rb b/packages/react-native/scripts/cocoapods/codegen_utils.rb index a39c77ed9a9611..9f98a9dfa0984f 100644 --- a/packages/react-native/scripts/cocoapods/codegen_utils.rb +++ b/packages/react-native/scripts/cocoapods/codegen_utils.rb @@ -159,13 +159,6 @@ def get_react_codegen_spec(package_json_file, folly_version: '2023.08.07.00', fa }); end - if new_arch_disabled - spec[:dependencies].merge!({ - 'React-rncore': [], - 'FBReactNativeSpec': [], - }) - end - if script_phases Pod::UI.puts "[Codegen] Adding script_phases to React-Codegen." spec[:'script_phases'] = script_phases diff --git a/packages/react-native/scripts/cocoapods/new_architecture.rb b/packages/react-native/scripts/cocoapods/new_architecture.rb index 20ae33fbe87b57..7bf30e43f604e1 100644 --- a/packages/react-native/scripts/cocoapods/new_architecture.rb +++ b/packages/react-native/scripts/cocoapods/new_architecture.rb @@ -75,17 +75,6 @@ def self.modify_flags_for_new_architecture(installer, is_new_arch_enabled) end end - # Set "RCT_DYNAMIC_FRAMEWORKS=1" if pod are installed with USE_FRAMEWORKS=dynamic - # This helps with backward compatibility. - if pod_name == 'React-RCTFabric' && ENV['USE_FRAMEWORKS'] == 'dynamic' - Pod::UI.puts "Setting -DRCT_DYNAMIC_FRAMEWORKS=1 to React-RCTFabric".green - rct_dynamic_framework_flag = " -DRCT_DYNAMIC_FRAMEWORKS=1" - target_installation_result.native_target.build_configurations.each do |config| - prev_build_settings = config.build_settings['OTHER_CPLUSPLUSFLAGS'] != nil ? config.build_settings['OTHER_CPLUSPLUSFLAGS'] : "$(inherithed)" - config.build_settings['OTHER_CPLUSPLUSFLAGS'] = prev_build_settings + rct_dynamic_framework_flag - end - end - target_installation_result.native_target.build_configurations.each do |config| if config.name == "Release" current_flags = config.build_settings['OTHER_CPLUSPLUSFLAGS'] != nil ? config.build_settings['OTHER_CPLUSPLUSFLAGS'] : "$(inherited)" @@ -138,27 +127,28 @@ def self.install_modules_dependencies(spec, new_arch_enabled, folly_version) if new_arch_enabled current_config["OTHER_CPLUSPLUSFLAGS"] = @@new_arch_cpp_flags - spec.dependency "React-RCTFabric" # This is for Fabric Component - spec.dependency "React-Codegen" - - spec.dependency "RCTRequired" - spec.dependency "RCTTypeSafety" - spec.dependency "ReactCommon/turbomodule/bridging" - spec.dependency "ReactCommon/turbomodule/core" - spec.dependency "React-NativeModulesApple" - spec.dependency "Yoga" - spec.dependency "React-Fabric" - spec.dependency "React-graphics" - spec.dependency "React-utils" - spec.dependency "React-debug" - spec.dependency "React-ImageManager" - spec.dependency "React-rendererdebug" - - if ENV["USE_HERMES"] == nil || ENV["USE_HERMES"] == "1" - spec.dependency "hermes-engine" - else - spec.dependency "React-jsi" - end + end + + spec.dependency "React-RCTFabric" # This is for Fabric Component + spec.dependency "React-Codegen" + + spec.dependency "RCTRequired" + spec.dependency "RCTTypeSafety" + spec.dependency "ReactCommon/turbomodule/bridging" + spec.dependency "ReactCommon/turbomodule/core" + spec.dependency "React-NativeModulesApple" + spec.dependency "Yoga" + spec.dependency "React-Fabric" + spec.dependency "React-graphics" + spec.dependency "React-utils" + spec.dependency "React-debug" + spec.dependency "React-ImageManager" + spec.dependency "React-rendererdebug" + + if ENV["USE_HERMES"] == nil || ENV["USE_HERMES"] == "1" + spec.dependency "hermes-engine" + else + spec.dependency "React-jsi" end spec.pod_target_xcconfig = current_config diff --git a/packages/react-native/scripts/cocoapods/utils.rb b/packages/react-native/scripts/cocoapods/utils.rb index 4a8bd34d71e039..eb89a3de20045d 100644 --- a/packages/react-native/scripts/cocoapods/utils.rb +++ b/packages/react-native/scripts/cocoapods/utils.rb @@ -318,6 +318,22 @@ def self.updateOSDeploymentTarget(installer) end end + def self.set_dynamic_frameworks_flags(installer) + installer.target_installation_results.pod_target_installation_results.each do |pod_name, target_installation_result| + + # Set "RCT_DYNAMIC_FRAMEWORKS=1" if pod are installed with USE_FRAMEWORKS=dynamic + # This helps with backward compatibility. + if pod_name == 'React-RCTFabric' && ENV['USE_FRAMEWORKS'] == 'dynamic' + Pod::UI.puts "Setting -DRCT_DYNAMIC_FRAMEWORKS=1 to React-RCTFabric".green + rct_dynamic_framework_flag = " -DRCT_DYNAMIC_FRAMEWORKS=1" + target_installation_result.native_target.build_configurations.each do |config| + prev_build_settings = config.build_settings['OTHER_CPLUSPLUSFLAGS'] != nil ? config.build_settings['OTHER_CPLUSPLUSFLAGS'] : "$(inherithed)" + config.build_settings['OTHER_CPLUSPLUSFLAGS'] = prev_build_settings + rct_dynamic_framework_flag + end + end + end + end + # ========= # # Utilities # # ========= # diff --git a/packages/react-native/scripts/codegen/generate-artifacts-executor.js b/packages/react-native/scripts/codegen/generate-artifacts-executor.js index dc8a5bab381212..7dc8b92366ed83 100644 --- a/packages/react-native/scripts/codegen/generate-artifacts-executor.js +++ b/packages/react-native/scripts/codegen/generate-artifacts-executor.js @@ -378,23 +378,12 @@ function generateCode(iosOutputDir, library, tmpDir, node, pathToSchema) { function generateNativeCodegenFiles( libraries, - fabricEnabled, iosOutputDir, node, codegenCliPath, schemaPaths, ) { - let fabricEnabledTypes = ['components', 'all']; libraries.forEach(library => { - if ( - !fabricEnabled && - fabricEnabledTypes.indexOf(library.config.type) >= 0 - ) { - console.log( - `[Codegen] ${library.config.name} skipped because fabric is not enabled.`, - ); - return; - } const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), library.config.name)); const pathToSchema = generateSchema(tmpDir, library, node, codegenCliPath); generateCode(iosOutputDir, library, tmpDir, node, pathToSchema); @@ -408,44 +397,37 @@ function generateNativeCodegenFiles( }); } -function createComponentProvider( - fabricEnabled, - schemaPaths, - node, - iosOutputDir, -) { - if (fabricEnabled) { - console.log('\n\n>>>>> Creating component provider'); - // Save the list of spec paths to a temp file. - const schemaListTmpPath = `${os.tmpdir()}/rn-tmp-schema-list.json`; - const fd = fs.openSync(schemaListTmpPath, 'w'); - fs.writeSync(fd, JSON.stringify(schemaPaths)); - fs.closeSync(fd); - console.log(`Generated schema list: ${schemaListTmpPath}`); - - const outputDir = path.join( - REACT_NATIVE_PACKAGE_ROOT_FOLDER, - 'React', - 'Fabric', - ); +function createComponentProvider(schemaPaths, node, iosOutputDir) { + console.log('\n\n>>>>> Creating component provider'); + // Save the list of spec paths to a temp file. + const schemaListTmpPath = `${os.tmpdir()}/rn-tmp-schema-list.json`; + const fd = fs.openSync(schemaListTmpPath, 'w'); + fs.writeSync(fd, JSON.stringify(schemaPaths)); + fs.closeSync(fd); + console.log(`Generated schema list: ${schemaListTmpPath}`); - // Generate FabricComponentProvider. - // Only for iOS at this moment. - executeNodeScript(node, [ - `${path.join( - REACT_NATIVE_PACKAGE_ROOT_FOLDER, - 'scripts', - 'generate-provider-cli.js', - )}`, - '--platform', - 'ios', - '--schemaListPath', - schemaListTmpPath, - '--outputDir', - outputDir, - ]); - console.log(`Generated provider in: ${outputDir}`); - } + const outputDir = path.join( + REACT_NATIVE_PACKAGE_ROOT_FOLDER, + 'React', + 'Fabric', + ); + + // Generate FabricComponentProvider. + // Only for iOS at this moment. + executeNodeScript(node, [ + `${path.join( + REACT_NATIVE_PACKAGE_ROOT_FOLDER, + 'scripts', + 'generate-provider-cli.js', + )}`, + '--platform', + 'ios', + '--schemaListPath', + schemaListTmpPath, + '--outputDir', + outputDir, + ]); + console.log(`Generated provider in: ${outputDir}`); } function findCodegenEnabledLibraries( @@ -541,7 +523,6 @@ function execute( codegenConfigFilename, codegenConfigKey, baseCodegenConfigFileDir, - fabricEnabled, ) { if (!isAppRootValid(appRootDir)) { return; @@ -568,14 +549,13 @@ function execute( generateNativeCodegenFiles( libraries, - fabricEnabled, iosOutputDir, node, codegenCliPath, schemaPaths, ); - createComponentProvider(fabricEnabled, schemaPaths, node, iosOutputDir); + createComponentProvider(schemaPaths, node, iosOutputDir); cleanupEmptyFilesAndFolders(iosOutputDir); } catch (err) { console.error(err); diff --git a/packages/react-native/scripts/react_native_pods.rb b/packages/react-native/scripts/react_native_pods.rb index ed040142261bfd..0bb0bd50cd542b 100644 --- a/packages/react-native/scripts/react_native_pods.rb +++ b/packages/react-native/scripts/react_native_pods.rb @@ -105,7 +105,6 @@ def use_react_native! ( # The Pods which should be included in all projects pod 'FBLazyVector', :path => "#{prefix}/Libraries/FBLazyVector" - pod 'FBReactNativeSpec', :path => "#{prefix}/React/FBReactNativeSpec" if !NewArchitectureHelper.new_arch_enabled pod 'RCTRequired', :path => "#{prefix}/Libraries/Required" pod 'RCTTypeSafety', :path => "#{prefix}/Libraries/TypeSafety", :modular_headers => true pod 'React', :path => "#{prefix}/" @@ -174,7 +173,6 @@ def use_react_native! ( # If the New Arch is turned off, we will use the Old Renderer, though. # RNTester always installed Fabric, this change is required to make the template work. setup_fabric!(:react_native_path => prefix) - checkAndGenerateEmptyThirdPartyProvider!(prefix, NewArchitectureHelper.new_arch_enabled) if !fabric_enabled relative_installation_root = Pod::Config.instance.installation_root.relative_path_from(Pathname.pwd) @@ -286,6 +284,7 @@ def react_native_post_install( ReactNativePodsUtils.apply_xcode_15_patch(installer) ReactNativePodsUtils.apply_ats_config(installer) ReactNativePodsUtils.updateOSDeploymentTarget(installer) + ReactNativePodsUtils.set_dynamic_frameworks_flags(installer) NewArchitectureHelper.set_clang_cxx_language_standard_if_needed(installer) NewArchitectureHelper.modify_flags_for_new_architecture(installer, NewArchitectureHelper.new_arch_enabled) @@ -293,104 +292,3 @@ def react_native_post_install( Pod::UI.puts "Pod install took #{Time.now.to_i - $START_TIME} [s] to run".green end - -# === LEGACY METHOD === -# We need to keep this while we continue to support the old architecture. -# ===================== -def use_react_native_codegen!(spec, options={}) - return if NewArchitectureHelper.new_arch_enabled - # TODO: Once the new codegen approach is ready for use, we should output a warning here to let folks know to migrate. - - # The prefix to react-native - react_native_path = options[:react_native_path] ||= ".." - - # Library name (e.g. FBReactNativeSpec) - library_name = options[:library_name] ||= "#{spec.name.gsub('_','-').split('-').collect(&:capitalize).join}Spec" - Pod::UI.puts "[Codegen] Found #{library_name}" - - relative_installation_root = Pod::Config.instance.installation_root.relative_path_from(Pathname.pwd) - output_dir = options[:output_dir] ||= $CODEGEN_OUTPUT_DIR - output_dir_module = "#{output_dir}/#{$CODEGEN_MODULE_DIR}" - output_dir_component = "#{output_dir}/#{$CODEGEN_COMPONENT_DIR}" - - codegen_config = { - "modules" => { - :js_srcs_pattern => "Native*.js", - :generated_dir => "#{relative_installation_root}/#{output_dir_module}/#{library_name}", - :generated_files => [ - "#{library_name}.h", - "#{library_name}-generated.mm" - ] - }, - "components" => { - :js_srcs_pattern => "*NativeComponent.js", - :generated_dir => "#{relative_installation_root}/#{output_dir_component}/#{library_name}", - :generated_files => [ - "ComponentDescriptors.h", - "EventEmitters.cpp", - "EventEmitters.h", - "Props.cpp", - "Props.h", - "States.cpp", - "States.h", - "RCTComponentViewHelpers.h", - "ShadowNodes.cpp", - "ShadowNodes.h" - ] - } - } - - # The path to JavaScript files - js_srcs_dir = options[:js_srcs_dir] ||= "./" - library_type = options[:library_type] - - if library_type - if !codegen_config[library_type] - raise "[Codegen] invalid library_type: #{library_type}. Check your podspec to make sure it's set to 'modules' or 'components'. Removing the option will generate files for both" - end - js_srcs_pattern = codegen_config[library_type][:js_srcs_pattern] - end - - if library_type - generated_dirs = [ codegen_config[library_type][:generated_dir] ] - generated_files = codegen_config[library_type][:generated_files].map { |filename| "#{codegen_config[library_type][:generated_dir]}/#{filename}" } - else - generated_dirs = [ codegen_config["modules"][:generated_dir], codegen_config["components"][:generated_dir] ] - generated_files = codegen_config["modules"][:generated_files].map { |filename| "#{codegen_config["modules"][:generated_dir]}/#{filename}" } - generated_files = generated_files.concat(codegen_config["components"][:generated_files].map { |filename| "#{codegen_config["components"][:generated_dir]}/#{filename}" }) - end - - if js_srcs_pattern - file_list = `find #{js_srcs_dir} -type f -name #{js_srcs_pattern}`.split("\n").sort - input_files = file_list.map { |filename| "${PODS_TARGET_SRCROOT}/#{filename}" } - else - input_files = [ js_srcs_dir ] - end - - # Prepare filesystem by creating empty files that will be picked up as references by CocoaPods. - prepare_command = "mkdir -p #{generated_dirs.join(" ")} && touch -a #{generated_files.join(" ")}" - system(prepare_command) # Always run prepare_command when a podspec uses the codegen, as CocoaPods may skip invoking this command in certain scenarios. Replace with pre_integrate_hook after updating to CocoaPods 1.11 - spec.prepare_command = prepare_command - - env_files = ["$PODS_ROOT/../.xcode.env.local", "$PODS_ROOT/../.xcode.env"] - - spec.script_phase = { - :name => 'Generate Specs', - :input_files => input_files + env_files, # This also needs to be relative to Xcode - :output_files => ["${DERIVED_FILE_DIR}/codegen-#{library_name}.log"].concat(generated_files.map { |filename| "${PODS_TARGET_SRCROOT}/#{filename}"} ), - # The final generated files will be created when this script is invoked at Xcode build time. - :script => get_script_phases_no_codegen_discovery( - react_native_path: react_native_path, - codegen_output_dir: output_dir, - codegen_module_dir: output_dir_module, - codegen_component_dir: output_dir_component, - library_name: library_name, - library_type: library_type, - js_srcs_pattern: js_srcs_pattern, - js_srcs_dir: js_srcs_dir, - file_list: file_list - ), - :execution_position => :before_compile, - :show_env_vars_in_log => true - } -end diff --git a/packages/rn-tester/NativeComponentExample/MyNativeView.podspec b/packages/rn-tester/NativeComponentExample/MyNativeView.podspec index 23f1db01e1cc11..2e4eb0613d9f41 100644 --- a/packages/rn-tester/NativeComponentExample/MyNativeView.podspec +++ b/packages/rn-tester/NativeComponentExample/MyNativeView.podspec @@ -30,12 +30,4 @@ Pod::Spec.new do |s| s.requires_arc = true install_modules_dependencies(s) - - # Enable codegen for this library - use_react_native_codegen!(s, { - :library_name => "MyNativeViewSpec", - :react_native_path => "../../react-native", - :js_srcs_dir => "./js", - :library_type => "components" - }) end diff --git a/packages/rn-tester/NativeModuleExample/ScreenshotManager.podspec b/packages/rn-tester/NativeModuleExample/ScreenshotManager.podspec index 2082df5691ed09..17daaf5934d9fd 100644 --- a/packages/rn-tester/NativeModuleExample/ScreenshotManager.podspec +++ b/packages/rn-tester/NativeModuleExample/ScreenshotManager.podspec @@ -23,13 +23,4 @@ Pod::Spec.new do |s| s.requires_arc = true install_modules_dependencies(s) - - # s.dependency "..." - - # Enable codegen for this library - use_react_native_codegen!(s, { - :react_native_path => "../../react-native", - :js_srcs_dir => "./", - :library_type => "modules", - }) end diff --git a/packages/rn-tester/Podfile b/packages/rn-tester/Podfile index 8991d28a670e07..1aff97a42fc655 100644 --- a/packages/rn-tester/Podfile +++ b/packages/rn-tester/Podfile @@ -60,11 +60,8 @@ def pods(target_name, options = {}) # RNTester native modules and components pod 'ScreenshotManager', :path => "NativeModuleExample" - - if ENV['RCT_NEW_ARCH_ENABLED'] == '1' - pod 'MyNativeView', :path => "NativeComponentExample" - pod 'NativeCxxModuleExample', :path => "NativeCxxModuleExample" - end + pod 'MyNativeView', :path => "NativeComponentExample" + pod 'NativeCxxModuleExample', :path => "NativeCxxModuleExample" end target 'RNTester' do diff --git a/packages/rn-tester/Podfile.lock b/packages/rn-tester/Podfile.lock index 2d38f0181b3f63..b4e0b2c0f58db8 100644 --- a/packages/rn-tester/Podfile.lock +++ b/packages/rn-tester/Podfile.lock @@ -2,13 +2,6 @@ PODS: - boost (1.83.0) - DoubleConversion (1.1.6) - FBLazyVector (1000.0.0) - - FBReactNativeSpec (1000.0.0): - - RCT-Folly (= 2023.08.07.00) - - RCTRequired (= 1000.0.0) - - RCTTypeSafety (= 1000.0.0) - - React-Core (= 1000.0.0) - - React-jsi (= 1000.0.0) - - ReactCommon/turbomodule/core (= 1000.0.0) - fmt (9.1.0) - glog (0.3.5) - hermes-engine (1000.0.0): @@ -20,6 +13,44 @@ PODS: - hermes-engine/inspector (1000.0.0) - hermes-engine/inspector_chrome (1000.0.0) - hermes-engine/Public (1000.0.0) + - MyNativeView (0.0.1): + - glog + - hermes-engine + - RCT-Folly (= 2023.08.07.00) + - RCTRequired + - RCTTypeSafety + - React-Codegen + - React-Core + - React-debug + - React-Fabric + - React-graphics + - React-ImageManager + - React-NativeModulesApple + - React-RCTFabric + - React-rendererdebug + - React-utils + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - Yoga + - NativeCxxModuleExample (0.0.1): + - glog + - hermes-engine + - RCT-Folly (= 2023.08.07.00) + - RCTRequired + - RCTTypeSafety + - React-Codegen + - React-Core + - React-debug + - React-Fabric + - React-graphics + - React-ImageManager + - React-NativeModulesApple + - React-RCTFabric + - React-rendererdebug + - React-utils + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - Yoga - OCMock (3.9.1) - RCT-Folly (2023.08.07.00): - boost @@ -58,7 +89,6 @@ PODS: - React-callinvoker (1000.0.0) - React-Codegen (1000.0.0): - DoubleConversion - - FBReactNativeSpec - glog - hermes-engine - RCT-Folly @@ -72,7 +102,6 @@ PODS: - React-jsiexecutor - React-NativeModulesApple - React-rendererdebug - - React-rncore - React-utils - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core @@ -1097,8 +1126,23 @@ PODS: - React-perflogger (= 1000.0.0) - ScreenshotManager (0.0.1): - glog + - hermes-engine - RCT-Folly (= 2023.08.07.00) + - RCTRequired + - RCTTypeSafety + - React-Codegen - React-Core + - React-debug + - React-Fabric + - React-graphics + - React-ImageManager + - React-NativeModulesApple + - React-RCTFabric + - React-rendererdebug + - React-utils + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - Yoga - SocketRocket (0.7.0) - Yoga (0.0.0) @@ -1106,10 +1150,11 @@ DEPENDENCIES: - boost (from `../react-native/third-party-podspecs/boost.podspec`) - DoubleConversion (from `../react-native/third-party-podspecs/DoubleConversion.podspec`) - FBLazyVector (from `../react-native/Libraries/FBLazyVector`) - - FBReactNativeSpec (from `../react-native/React/FBReactNativeSpec`) - fmt (from `../react-native/third-party-podspecs/fmt.podspec`) - glog (from `../react-native/third-party-podspecs/glog.podspec`) - hermes-engine (from `../react-native/sdks/hermes-engine/hermes-engine.podspec`) + - MyNativeView (from `NativeComponentExample`) + - NativeCxxModuleExample (from `NativeCxxModuleExample`) - OCMock (~> 3.9.1) - RCT-Folly (from `../react-native/third-party-podspecs/RCT-Folly.podspec`) - RCT-Folly/Fabric (from `../react-native/third-party-podspecs/RCT-Folly.podspec`) @@ -1172,8 +1217,6 @@ EXTERNAL SOURCES: :podspec: "../react-native/third-party-podspecs/DoubleConversion.podspec" FBLazyVector: :path: "../react-native/Libraries/FBLazyVector" - FBReactNativeSpec: - :path: "../react-native/React/FBReactNativeSpec" fmt: :podspec: "../react-native/third-party-podspecs/fmt.podspec" glog: @@ -1181,6 +1224,10 @@ EXTERNAL SOURCES: hermes-engine: :podspec: "../react-native/sdks/hermes-engine/hermes-engine.podspec" :tag: '' + MyNativeView: + :path: NativeComponentExample + NativeCxxModuleExample: + :path: NativeCxxModuleExample RCT-Folly: :podspec: "../react-native/third-party-podspecs/RCT-Folly.podspec" RCTRequired: @@ -1278,17 +1325,18 @@ SPEC CHECKSUMS: boost: 26fad476bfa736552bbfa698a06cc530475c1505 DoubleConversion: fea03f2699887d960129cc54bba7e52542b6f953 FBLazyVector: f4492a543c5a8fa1502d3a5867e3f7252497cfe8 - FBReactNativeSpec: 03da6018f583d64c5944bc4afffb12368e3642a8 fmt: 4c2741a687cc09f0634a2e2c72a838b99f1ff120 glog: c5d68082e772fa1c511173d6b30a9de2c05a69a2 hermes-engine: 2788dfc2ed3699d11b14e815f0c608fc8d770d6b + MyNativeView: 1fb0d21fda6ef12fd5f425f9888c81345a86a3e7 + NativeCxxModuleExample: 19d10636011c914264a5922c6f0f22a2e8fd0910 OCMock: 9491e4bec59e0b267d52a9184ff5605995e74be8 RCT-Folly: 823c6f6ec910a75d4ad28898b4a11cdee140b92a RCTRequired: 82c56a03b3efd524bfdb581a906add903f78f978 RCTTypeSafety: 5f57d4ae5dfafc85a0f575d756c909b584722c52 React: cb6dc75e09f32aeddb4d8fb58a394a67219a92fe React-callinvoker: bae59cbd6affd712bbfc703839dad868ff35069d - React-Codegen: 20baee7c8f2303bc5f34d9e72f93ca55de6cbde3 + React-Codegen: c1e6ea0005a6ecf187d2772f14e5386f1c1f4853 React-Core: f09ea29184cc7f33015a0748588fcfe1d43b3dd1 React-CoreModules: ad1b7cb8efe5f3c7e88548b6ea6aad8507774471 React-cxxreact: 04bf6a12caa850f5d2c7bd6d66dfecd4741989b5 @@ -1321,16 +1369,16 @@ SPEC CHECKSUMS: React-RCTText: d9925903524a7b179cf7803162a98038e0bfb4fd React-RCTVibration: 14322c13fb0c5cc2884b714b11d277dc7fc326c4 React-rendererdebug: 2e58409db231638bc3e78143d8844066a3302939 - React-rncore: 63aced0ca8aff46f8e762663ca4afebb5eedb627 + React-rncore: e903b3d2819a25674403c548ec103f34bf02ba2b React-runtimeexecutor: e1c32bc249dd3cf3919cb4664fd8dc84ef70cff7 React-runtimescheduler: 6529d155a98010b6e8f0a3a86d4184b89a886633 React-utils: 87ed8c079c9991831112fe716f2686c430699fc3 ReactCommon: 4511ea0e8f349de031de7cad88c2ecf871ab69f9 ReactCommon-Samples: cfc3383af93a741319e038977c2ae1082e4ff49e - ScreenshotManager: 2b23b74d25f5e307f7b4d21173a61a3934e69475 + ScreenshotManager: 753da20873c2ada484bdee4143a7248084d3fd35 SocketRocket: abac6f5de4d4d62d24e11868d7a2f427e0ef940d Yoga: 455fa6867657b570a05655dd515c8c6588618fa8 -PODFILE CHECKSUM: c0120ff99aea9c7141bc22179e0f6be99c81a601 +PODFILE CHECKSUM: 426f495a1ad44f3cabea3b7dd2b66a0b71083e26 COCOAPODS: 1.13.0