From 377b444e7aae7377bf2018e41a3a1b64b17a2c22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ramos?= Date: Wed, 2 Dec 2020 11:18:53 -0800 Subject: [PATCH] Integrate Native Module codegen into Xcode build pipeline (#30449) Summary: Move the codegen invocation out of Podfiles and into the FBReactNativeSpec Pod itself. With this change, developers do not need to modify their existing project's Podfiles, and yet the codegen will be integrated into their projects automatically by way of the FBReactNativeSpec Pod. This is accomplished in part by injecting a script build phase into the Pods Xcode project that is generated by CocoaPods. The build phase will save the output of the codegen script to a log in the derived files directory. The codegen will be executed if the codegen log file is not present, or if the contents of the Libraries directory has changed. The codegen will thus be invoked in these situations: **RNTester:** * When `packages/rn-tester/RNTesterPods.xcworkspace` is built, if the codegen output logfile is not present or if the input files have changed. **OSS React Native apps:** * When `ios/AwesomeProject.xcworkspace` is built, if the codegen output file is not present or if the input files have changed. Normally, this should not happen, as we do not expect folks to update the contents of `node_modules/react-native/Libraries`. Pull Request resolved: https://github.com/facebook/react-native/pull/30449 Changelog: [Internal] - Moved codegen invocation out of Podfile and into FBReactNativeSpec Pod Reviewed By: fkgozali Differential Revision: D25138896 fbshipit-source-id: 6c6738664fc3ea87642530e2b4d3ec4d946b3545 --- .gitignore | 1 - .../FBReactNativeSpec.podspec | 18 +++++ package.json | 1 + packages/rn-tester/Podfile | 10 --- packages/rn-tester/Podfile.lock | 18 ++--- scripts/generate-native-modules-specs.sh | 78 +++++++++++++------ scripts/react_native_pods.rb | 18 ----- template/ios/Podfile | 4 - 8 files changed, 84 insertions(+), 64 deletions(-) diff --git a/.gitignore b/.gitignore index 272b9bbfba849b..7dd758b61058ae 100644 --- a/.gitignore +++ b/.gitignore @@ -103,7 +103,6 @@ package-lock.json /Libraries/FBReactNativeSpec/FBReactNativeSpec /packages/react-native-codegen/lib /ReactCommon/fabric/components/rncore/ -/schema-native-modules.json /schema-rncore.json # Visual studio diff --git a/Libraries/FBReactNativeSpec/FBReactNativeSpec.podspec b/Libraries/FBReactNativeSpec/FBReactNativeSpec.podspec index de5e03607754d2..d02b4c9b84aca5 100644 --- a/Libraries/FBReactNativeSpec/FBReactNativeSpec.podspec +++ b/Libraries/FBReactNativeSpec/FBReactNativeSpec.podspec @@ -9,13 +9,22 @@ package = JSON.parse(File.read(File.join(__dir__, "..", "..", "package.json"))) version = package['version'] source = { :git => 'https://github.com/facebook/react-native.git' } +codegen_path_prefix = ".." 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 + codegen_path_prefix = "packages" else source[:tag] = "v#{version}" end +react_native_path = File.join(__dir__, "..", "..") +srcs_dir = File.join(__dir__, "..") +codegen_script_path = File.join(react_native_path, "scripts", "generate-native-modules-specs.sh") +codegen_path = File.join(react_native_path, codegen_path_prefix, "react-native-codegen") +generated_files = [File.join(__dir__, "FBReactNativeSpec", "FBReactNativeSpec.h"), File.join(__dir__, "FBReactNativeSpec", "FBReactNativeSpec-generated.mm")] +codegen_command = "CODEGEN_PATH=#{codegen_path} sh '#{codegen_script_path}' | tee \"${SCRIPT_OUTPUT_FILE_0}\"" + folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32' folly_version = '2020.01.13.00' @@ -44,4 +53,13 @@ Pod::Spec.new do |s| s.dependency "React-Core", version s.dependency "React-jsi", version s.dependency "ReactCommon/turbomodule/core", version + + s.prepare_command = "touch #{generated_files.reduce() { |str, file| str + " " + file }}" + s.script_phase = { + :name => 'Generate Native Modules Code', + :input_files => [srcs_dir], + :output_files => ["$(DERIVED_FILE_DIR)/FBReactNativeSpec-codegen.log"], + :script => codegen_command, + :execution_position => :before_compile + } end diff --git a/package.json b/package.json index 2a1a84cfd1d77c..42df7b41226dd5 100644 --- a/package.json +++ b/package.json @@ -38,6 +38,7 @@ "README.md", "rn-get-polyfills.js", "scripts/compose-source-maps.js", + "scripts/generate-native-modules-specs.sh", "scripts/generate-native-modules-specs-cli.js", "scripts/ios-configure-glog.sh", "scripts/launchPackager.bat", diff --git a/packages/rn-tester/Podfile b/packages/rn-tester/Podfile index e939c4f2f0b7a8..efc5c339ad5b98 100644 --- a/packages/rn-tester/Podfile +++ b/packages/rn-tester/Podfile @@ -60,16 +60,6 @@ def frameworks_pre_install(installer) end end -pre_install do |installer| - frameworks_pre_install(installer) if ENV['USE_FRAMEWORKS'] == '1' - if ENV['USE_CODEGEN'] != '0' - prefix_path = "../.." - codegen_path = "../../packages/react-native-codegen" - system("./#{codegen_path}/scripts/oss/build.sh") or raise "Could not build react-native-codegen package" - codegen_pre_install(installer, {path:prefix_path, codegen_path:codegen_path}) - end -end - post_install do |installer| flipper_post_install(installer) end diff --git a/packages/rn-tester/Podfile.lock b/packages/rn-tester/Podfile.lock index 6ba9855fd1872b..57bce624639667 100644 --- a/packages/rn-tester/Podfile.lock +++ b/packages/rn-tester/Podfile.lock @@ -15,12 +15,12 @@ PODS: - Flipper-Folly (~> 2.2) - Flipper-RSocket (~> 1.1) - Flipper-DoubleConversion (1.1.7) - - Flipper-Folly (2.2.0): + - Flipper-Folly (2.3.0): - boost-for-react-native - CocoaLibEvent (~> 1.0) - Flipper-DoubleConversion - Flipper-Glog - - OpenSSL-Universal (= 1.0.2.19) + - OpenSSL-Universal (= 1.0.2.20) - Flipper-Glog (0.3.6) - Flipper-PeerTalk (0.0.4) - Flipper-RSocket (1.1.0): @@ -58,9 +58,9 @@ PODS: - FlipperKit/Core - FlipperKit/FlipperKitNetworkPlugin - glog (0.3.5) - - OpenSSL-Universal (1.0.2.19): - - OpenSSL-Universal/Static (= 1.0.2.19) - - OpenSSL-Universal/Static (1.0.2.19) + - OpenSSL-Universal (1.0.2.20): + - OpenSSL-Universal/Static (= 1.0.2.20) + - OpenSSL-Universal/Static (1.0.2.20) - RCT-Folly (2020.01.13.00): - boost-for-react-native - DoubleConversion @@ -490,16 +490,16 @@ SPEC CHECKSUMS: CocoaLibEvent: 2fab71b8bd46dd33ddb959f7928ec5909f838e3f DoubleConversion: cde416483dac037923206447da6e1454df403714 FBLazyVector: fe973c09b2299b5e8154186ecf1f6554b4f70987 - FBReactNativeSpec: 20a9345af9157362b51ab0258d842cb7bb347d19 + FBReactNativeSpec: 4b0a53603445208c324b4a23d77590c399894efc Flipper: be611d4b742d8c87fbae2ca5f44603a02539e365 Flipper-DoubleConversion: 38631e41ef4f9b12861c67d17cb5518d06badc41 - Flipper-Folly: c12092ea368353b58e992843a990a3225d4533c3 + Flipper-Folly: e4493b013c02d9347d5e0cb4d128680239f6c78a Flipper-Glog: 1dfd6abf1e922806c52ceb8701a3599a79a200a6 Flipper-PeerTalk: 116d8f857dc6ef55c7a5a75ea3ceaafe878aadc9 Flipper-RSocket: 64e7431a55835eb953b0bf984ef3b90ae9fdddd7 FlipperKit: ab353d41aea8aae2ea6daaf813e67496642f3d7d glog: 40a13f7840415b9a77023fbcae0f1e6f43192af3 - OpenSSL-Universal: 8b48cc0d10c1b2923617dfe5c178aa9ed2689355 + OpenSSL-Universal: ff34003318d5e1163e9529b08470708e389ffcdd RCT-Folly: b39288cedafe50da43317ec7d91bcc8cc0abbf33 RCTRequired: d3d4ce60e1e2282864d7560340690a3c8c646de1 RCTTypeSafety: 4da4f9f218727257c50fd3bf2683a06cdb4fede3 @@ -528,6 +528,6 @@ SPEC CHECKSUMS: Yoga: 69ef0b2bba5387523f793957a9f80dbd61e89631 YogaKit: f782866e155069a2cca2517aafea43200b01fd5a -PODFILE CHECKSUM: cd671238f92c51cd349a1c778fd089994174b101 +PODFILE CHECKSUM: 3adfe268d800503789170d1862bde422ee204fe8 COCOAPODS: 1.10.0 diff --git a/scripts/generate-native-modules-specs.sh b/scripts/generate-native-modules-specs.sh index 5edfa3e421e14d..d667c46901fe99 100755 --- a/scripts/generate-native-modules-specs.sh +++ b/scripts/generate-native-modules-specs.sh @@ -4,54 +4,88 @@ # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. -# This script collects the JavaScript spec definitions for native -# modules, then uses react-native-codegen to generate native code. -# The script will copy the generated code to the final location by -# default. Optionally, call the script with a path to the desired -# output location. +# This script collects the JavaScript spec definitions for core +# native modules, then uses react-native-codegen to generate +# native code. +# The script will use the local react-native-codegen package by +# default. Optionally, set the CODEGEN_PATH to point to the +# desired codegen library (e.g. when using react-native-codegen +# from npm). # # Usage: -# ./scripts/generate-native-modules-specs.sh [output-dir] +# ./scripts/generate-native-modules-specs.sh # # Example: -# ./scripts/generate-native-modules-specs.sh ./codegen-out +# CODEGEN_PATH=.. ./scripts/generate-native-modules-specs.sh # shellcheck disable=SC2038 set -e THIS_DIR=$(cd -P "$(dirname "$(readlink "${BASH_SOURCE[0]}" || echo "${BASH_SOURCE[0]}")")" && pwd) +TEMP_DIR=$(mktemp -d /tmp/react-native-codegen-XXXXXXXX) RN_DIR=$(cd "$THIS_DIR/.." && pwd) -CODEGEN_DIR=$(cd "$RN_DIR/packages/react-native-codegen" && pwd) -OUTPUT_DIR="${1:-$RN_DIR/Libraries/FBReactNativeSpec/FBReactNativeSpec}" -SCHEMA_FILE="$RN_DIR/schema-native-modules.json" +CODEGEN_PATH="${CODEGEN_PATH:-$(cd "$RN_DIR/packages" && pwd)}" +CODEGEN_DIR="$CODEGEN_PATH/react-native-codegen" + YARN_BINARY="${YARN_BINARY:-$(command -v yarn)}" +cleanup () { + set +e + rm -rf "$TEMP_DIR" + set -e +} + describe () { printf "\\n\\n>>>>> %s\\n\\n\\n" "$1" } step_build_codegen () { - describe "Building react-native-codegen package" - pushd "$CODEGEN_DIR" >/dev/null || exit - "$YARN_BINARY" - "$YARN_BINARY" build - popd >/dev/null || exit + if [ ! -d "$CODEGEN_DIR/lib" ]; then + describe "Building react-native-codegen package" + pushd "$CODEGEN_DIR" >/dev/null || exit + "$YARN_BINARY" + "$YARN_BINARY" build + popd >/dev/null || exit + fi } -step_gen_schema () { +run_codegen () { + SRCS_DIR=$1 + LIBRARY_NAME=$2 + OUTPUT_DIR=$3 + + SCHEMA_FILE="$TEMP_DIR/schema-$LIBRARY_NAME.json" + + if [ ! -d "$CODEGEN_DIR/lib" ]; then + describe "Building react-native-codegen package" + pushd "$CODEGEN_DIR" >/dev/null || exit + "$YARN_BINARY" + "$YARN_BINARY" build + popd >/dev/null || exit + fi + describe "Generating schema from flow types" - SRCS_DIR=$(cd "$RN_DIR/Libraries" && pwd) "$YARN_BINARY" node "$CODEGEN_DIR/lib/cli/combine/combine-js-to-schema-cli.js" "$SCHEMA_FILE" "$SRCS_DIR" -} -step_gen_specs () { describe "Generating native code from schema (iOS)" pushd "$RN_DIR" >/dev/null || exit "$YARN_BINARY" --silent node scripts/generate-native-modules-specs-cli.js ios "$SCHEMA_FILE" "$OUTPUT_DIR" popd >/dev/null || exit } -step_build_codegen -step_gen_schema -step_gen_specs +# Handle Core Modules +run_codegen_core_modules () { + LIBRARY_NAME="FBReactNativeSpec" + SRCS_DIR=$(cd "$RN_DIR/Libraries" && pwd) + OUTPUT_DIR="$SRCS_DIR/$LIBRARY_NAME/$LIBRARY_NAME" + + run_codegen "$SRCS_DIR" "$LIBRARY_NAME" "$OUTPUT_DIR" +} + +main() { + run_codegen_core_modules +} + +trap cleanup EXIT +main "$@" diff --git a/scripts/react_native_pods.rb b/scripts/react_native_pods.rb index 14d6166f3da6c1..a77938c0510588 100644 --- a/scripts/react_native_pods.rb +++ b/scripts/react_native_pods.rb @@ -108,21 +108,3 @@ def flipper_post_install(installer) end end end - -# Pre Install processing for Native Modules -def codegen_pre_install(installer, options={}) - # Path to React Native - prefix = options[:path] ||= "../node_modules/react-native" - - # Path to react-native-codegen - codegen_path = options[:codegen_path] ||= "#{prefix}/../react-native-codegen" - - # Handle Core Modules - Dir.mktmpdir do |dir| - native_module_spec_name = "FBReactNativeSpec" - schema_file = dir + "/schema-#{native_module_spec_name}.json" - srcs_dir = "#{prefix}/Libraries" - schema_generated = system("node #{codegen_path}/lib/cli/combine/combine-js-to-schema-cli.js #{schema_file} #{srcs_dir}") or raise "Could not generate Native Module schema" - specs_generated = system("node #{prefix}/scripts/generate-native-modules-specs-cli.js ios #{schema_file} #{srcs_dir}/#{native_module_spec_name}/#{native_module_spec_name}") or raise "Could not generate code for #{native_module_spec_name}" - end -end diff --git a/template/ios/Podfile b/template/ios/Podfile index 04f68e5431fb93..6701249e83ac20 100644 --- a/template/ios/Podfile +++ b/template/ios/Podfile @@ -13,10 +13,6 @@ target 'HelloWorld' do # Pods for testing end - pre_install do |installer| - codegen_pre_install(installer) - end - # Enables Flipper. # # Note that if you have use_frameworks! enabled, Flipper will not work and