Skip to content

Commit

Permalink
Fix building RN Android from source on Windows. (#30535)
Browse files Browse the repository at this point in the history
Summary:
Running `.\gradlew installArchives` is currently broken on Windows. This is because .sh scripts were added in the codegen module, which cannot be run by the Command Prompt on Windows. It can be worked around by installing eg. Git Bash., which can be then leveraged using the code modifications in this PR, which include sanitizing mixed Linux-Windows relative paths, and other minor Windows-specific adjustments.

It's required that the user adds a Windows Environment variable storing the path to their bash binary named `REACT_WINDOWS_BASH`.

Pair-programmed with davinci26
## Changelog

<!-- Help reviewers and the release process by writing your own changelog entry. For an example, see:
https://github.com/facebook/react-native/wiki/Changelog
-->

[Android] [Fix] - Fix building React Android on Windows.

Fixes #30271

Pull Request resolved: #30535

Reviewed By: ShikaSD

Differential Revision: D25909760

Pulled By: appden

fbshipit-source-id: ea0e6e7c161a5e4a937d46e8e6972ce142fead4e
  • Loading branch information
Igor Klemenski authored and facebook-github-bot committed Jan 28, 2021
1 parent fc1f0df commit 5dc1522
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 4 deletions.
22 changes: 21 additions & 1 deletion packages/react-native-codegen/android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
* LICENSE file in the root directory of this source tree.
*/

import org.apache.tools.ant.taskdefs.condition.Os

buildscript {
repositories {
mavenLocal()
Expand Down Expand Up @@ -42,5 +44,23 @@ task('buildCodegenCLI', type: Exec) {
nodeModulesDir.mkdirs();
outputs.dirs(libDir, nodeModulesDir)

commandLine("$codegenRoot/scripts/oss/build.sh")
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
// Convert path to Linux format: use canonical path to strip it off relative elements in the middle of the string.
// Then replace baskslashes with slashes, remove leading colon, add leading slash.
// Eg. D:\path1\sub2/.. -> /D/path1/path2
String canonicalPath = new File(codegenRoot).getCanonicalPath()
String linuxPath = canonicalPath.replace('\\', '/');
linuxPath = linuxPath.replace(':', '')
linuxPath = '/' + linuxPath

// Get the location of bash in the system; assume environment variable created to store it.
String bashHome = "$System.env.REACT_WINDOWS_BASH"
if (bashHome == null) {
throw new GradleException("REACT_WINDOWS_BASH is not defined.")
}
commandLine(bashHome, "-c", "$linuxPath/scripts/oss/build.sh")
}
else {
commandLine("$codegenRoot/scripts/oss/build.sh")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ public void apply(final Project project) {
final File generatedSchemaFile = new File(generatedSrcDir, "schema.json");

// 2. Task: produce schema from JS files.
String os = System.getProperty("os.name").toLowerCase();

project
.getTasks()
.register(
Expand Down Expand Up @@ -62,7 +64,7 @@ public void apply(final Project project) {

ImmutableList<String> execCommands =
new ImmutableList.Builder<String>()
.add("yarn")
.add(os.contains("windows") ? "yarn.cmd" : "yarn")
.addAll(ImmutableList.copyOf(extension.nodeExecutableAndArgs))
.add(extension.codegenGenerateSchemaCLI().getAbsolutePath())
.add(generatedSchemaFile.getAbsolutePath())
Expand Down Expand Up @@ -96,7 +98,7 @@ public void apply(final Project project) {

ImmutableList<String> execCommands =
new ImmutableList.Builder<String>()
.add("yarn")
.add(os.contains("windows") ? "yarn.cmd" : "yarn")
.addAll(ImmutableList.copyOf(extension.nodeExecutableAndArgs))
.add(extension.codegenGenerateNativeModuleSpecsCLI().getAbsolutePath())
.add("android")
Expand Down
12 changes: 11 additions & 1 deletion packages/react-native-codegen/scripts/oss/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,22 @@ if [[ ${FBSOURCE_ENV:-0} -eq 1 ]]; then
"$YARN_BINARY" run build

popd >/dev/null

else
# Run yarn install in a separate tmp dir to avoid conflict with the rest of the repo.
# Note: OSS-only.
TMP_DIR=$(mktemp -d)

cp -R "$CODEGEN_DIR/." "$TMP_DIR"
# On Windows this script gets run by a seprate Git Bash instance, which cannot perform the copy
# due to file locks created by the host process. Need to exclude .lock files while copying.
# Using in-memory tar operation because piping `find` and `grep` doesn't preserve folder structure
# during recursive copying, and `rsync` is not installed by default in Git Bash.
# As an added benefit, blob copy is faster.
if [ "$OSTYPE" = "msys" ] || [ "$OSTYPE" = "cygwin" ]; then
tar cf - --exclude='*.lock' "$CODEGEN_DIR" | (cd "$TMP_DIR" && tar xvf - );
else
cp -R "$CODEGEN_DIR/." "$TMP_DIR";
fi

pushd "$TMP_DIR" >/dev/null

Expand Down

0 comments on commit 5dc1522

Please sign in to comment.