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: 4779f822459cea2c30fd544eee19a49e8d80153d
This commit is contained in:
Héctor Ramos
2020-12-02 14:27:50 -08:00
committed by Facebook GitHub Bot
parent a4a517a09d
commit c901c1fbce
8 changed files with 84 additions and 64 deletions
+56 -22
View File
@@ -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 "$@"
-18
View File
@@ -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