From 144d5149a0c50e464dd1be0769fed2ce33ab26a4 Mon Sep 17 00:00:00 2001 From: John Cater Date: Wed, 9 Sep 2020 17:20:37 -0700 Subject: [PATCH] Update android_sdk_repository to create a valid, but useless, repository if the SDK doesn't actually exist. This allows non-Android builds to proceed but will fail building android code. Fixes #12069. Closes #12070. RELNOTES: Non-android targets can again be built when android_sdk_repository is present but invalid. PiperOrigin-RevId: 330832321 --- .../android/AndroidSdkRepositoryFunction.java | 10 ++--- .../android/AndroidSdkRepositoryRule.java | 3 +- .../android_sdk_repository_empty_template.txt | 44 +++++++++++++++++++ .../android_sdk_repository_template.txt | 5 +++ .../android/android_sdk_integration_test.sh | 36 ++++++++++++++- tools/android/BUILD.tools | 5 ++- 6 files changed, 91 insertions(+), 12 deletions(-) create mode 100644 src/main/java/com/google/devtools/build/lib/bazel/rules/android/android_sdk_repository_empty_template.txt diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/android/AndroidSdkRepositoryFunction.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/AndroidSdkRepositoryFunction.java index 076f2596f6d999..7f15f085586104 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/rules/android/AndroidSdkRepositoryFunction.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/AndroidSdkRepositoryFunction.java @@ -106,12 +106,10 @@ public RepositoryDirectoryValue.Builder fetch( androidSdkPath = fs.getPath(getAndroidHomeEnvironmentVar(directories.getWorkspace(), environ)); } else { - throw new RepositoryFunctionException( - new EvalException( - rule.getLocation(), - "Either the path attribute of android_sdk_repository or the ANDROID_HOME environment " - + "variable must be set."), - Transience.PERSISTENT); + // Write an empty BUILD file that declares errors when referred to. + String buildFile = getStringResource("android_sdk_repository_empty_template.txt"); + writeBuildFile(outputDirectory, buildFile); + return RepositoryDirectoryValue.builder().setPath(outputDirectory); } if (!symlinkLocalRepositoryContents(outputDirectory, androidSdkPath, userDefinedPath)) { diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/android/AndroidSdkRepositoryRule.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/AndroidSdkRepositoryRule.java index 943cafaa26556b..b8ec9bf3dfdbb0 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/rules/android/AndroidSdkRepositoryRule.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/AndroidSdkRepositoryRule.java @@ -41,8 +41,7 @@ private static final ImmutableMap calculateBindings(Rule rule) { builder.put("android/d8_jar_import", Label.parseAbsoluteUnchecked(prefix + "d8_jar_import")); builder.put("android/dx_jar_import", Label.parseAbsoluteUnchecked(prefix + "dx_jar_import")); builder.put("android_sdk_for_testing", Label.parseAbsoluteUnchecked(prefix + "files")); - builder.put( - "has_androidsdk", Label.parseAbsoluteUnchecked("@bazel_tools//tools/android:always_true")); + builder.put("has_androidsdk", Label.parseAbsoluteUnchecked(prefix + "has_androidsdk")); return builder.build(); } diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/android/android_sdk_repository_empty_template.txt b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/android_sdk_repository_empty_template.txt new file mode 100644 index 00000000000000..5912ddb0fdbf34 --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/android_sdk_repository_empty_template.txt @@ -0,0 +1,44 @@ +package(default_visibility = ["//visibility:public"]) + +# android_sdk_repository was used without a valid Android SDK being set. +# Either the path attribute of android_sdk_repository or the ANDROID_HOME +# environment variable must be set. +# This is a minimal BUILD file to allow non-Android builds to continue. + +alias( + name = "has_androidsdk", + actual = "@bazel_tools//tools/android:always_false", +) + +filegroup( + name = "files", + srcs = [":error_message"], +) + +filegroup( + name = "sdk", + srcs = [":error_message"], +) + +filegroup( + name = "d8_jar_import", + srcs = [":error_message"], +) + +filegroup( + name = "dx_jar_import", + srcs = [":error_message"], +) + +genrule( + name = "invalid_android_sdk_repository_error", + outs = [ + "error_message", + "error_message.jar", + ], + cmd = """echo \ + android_sdk_repository was used without a valid Android SDK being set. \ + Either the path attribute of android_sdk_repository or the ANDROID_HOME \ + environment variable must be set. ; \ + exit 1 """, +) diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/android/android_sdk_repository_template.txt b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/android_sdk_repository_template.txt index 5f84ee4b495456..b7ef2f02039546 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/rules/android/android_sdk_repository_template.txt +++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/android_sdk_repository_template.txt @@ -5,6 +5,11 @@ load( "create_android_sdk_rules", "create_system_images_filegroups") +alias( + name = "has_androidsdk", + actual = "@bazel_tools//tools/android:always_true", +) + create_android_sdk_rules( name = "%repository_name%", build_tools_version = "%build_tools_version%", diff --git a/src/test/shell/bazel/android/android_sdk_integration_test.sh b/src/test/shell/bazel/android/android_sdk_integration_test.sh index 56231a1d8e2b85..71663b5e0f2823 100755 --- a/src/test/shell/bazel/android/android_sdk_integration_test.sh +++ b/src/test/shell/bazel/android/android_sdk_integration_test.sh @@ -57,7 +57,7 @@ android_sdk_repository( api_level = 25, ) EOF - bazel build @androidsdk//:files >& $TEST_log && fail "Should have failed" + bazel build @androidsdk//:files >& $TEST_log && fail "Should have failed" || true expect_log "Either the path attribute of android_sdk_repository" } @@ -71,7 +71,7 @@ android_sdk_repository( path = "$TEST_SRCDIR/some_dir", ) EOF - bazel build @androidsdk//:files >& $TEST_log && fail "Should have failed" + bazel build @androidsdk//:files >& $TEST_log && fail "Should have failed" || true expect_log "Unable to read the Android SDK at $TEST_SRCDIR/some_dir, the path may be invalid." \ " Is the path in android_sdk_repository() or \$ANDROID_SDK_HOME set correctly?" } @@ -102,4 +102,36 @@ function test_android_sdk_repository_returns_null_if_env_vars_missing() { ANDROID_HOME=$ANDROID_SDK bazel build @androidsdk//:files || "Build failed" } +# Regression test for https://github.com/bazelbuild/bazel/issues/12069 +function test_android_sdk_repository_present_not_set() { + create_new_workspace + cat >> WORKSPACE < a/BUILD < a/helper.sh <