aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build
diff options
context:
space:
mode:
authorGravatar mstaib <mstaib@google.com>2017-04-12 16:37:48 +0000
committerGravatar Jakob Buchgraber <buchgr@google.com>2017-04-13 09:36:45 +0200
commitb127fbbb9cec67407d6d19d3664d57700c085158 (patch)
tree5e99542e2eb3d983e8c1f9a6f341e2e5d84a5c9f /src/main/java/com/google/devtools/build
parentf76ad07c5ab4984ce6836d8ac15e7265742f30c7 (diff)
Add feature_flags attribute to Android binary rules.
This is the first actual user of the config_feature_flag rule, able to actually set its value (and thus give a point to using it!) This feature is not fully launched yet, but it is usable in any build containing this change. RELNOTES: None. PiperOrigin-RevId: 152948153
Diffstat (limited to 'src/main/java/com/google/devtools/build')
-rw-r--r--src/main/java/com/google/devtools/build/lib/BUILD1
-rw-r--r--src/main/java/com/google/devtools/build/lib/bazel/rules/android/BazelAndroidBinaryRule.java4
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinary.java12
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/AndroidFeatureFlagSetProvider.java82
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/AndroidRuleClasses.java8
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/config/ConfigFeatureFlagProvider.java9
6 files changed, 110 insertions, 6 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/BUILD b/src/main/java/com/google/devtools/build/lib/BUILD
index afbafdf117..cd90d661d8 100644
--- a/src/main/java/com/google/devtools/build/lib/BUILD
+++ b/src/main/java/com/google/devtools/build/lib/BUILD
@@ -984,6 +984,7 @@ java_library(
":vfs",
"//src/main/java/com/google/devtools/build/lib:skylarkinterface",
"//src/main/java/com/google/devtools/build/lib/actions",
+ "//src/main/java/com/google/devtools/build/lib/rules/config",
"//src/main/java/com/google/devtools/build/lib/rules/cpp",
"//src/main/java/com/google/devtools/common/options",
"//src/main/protobuf:android_deploy_info_java_proto",
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/android/BazelAndroidBinaryRule.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/BazelAndroidBinaryRule.java
index 8fedd68833..a5a4fe57d3 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/rules/android/BazelAndroidBinaryRule.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/BazelAndroidBinaryRule.java
@@ -25,7 +25,9 @@ import com.google.devtools.build.lib.packages.RuleClass;
import com.google.devtools.build.lib.packages.RuleClass.Builder;
import com.google.devtools.build.lib.rules.android.AndroidBinaryOnlyRule;
import com.google.devtools.build.lib.rules.android.AndroidConfiguration;
+import com.google.devtools.build.lib.rules.android.AndroidFeatureFlagSetProvider;
import com.google.devtools.build.lib.rules.android.AndroidRuleClasses;
+import com.google.devtools.build.lib.rules.config.ConfigFeatureFlagTransitionFactory;
import com.google.devtools.build.lib.rules.cpp.CppConfiguration;
import com.google.devtools.build.lib.rules.cpp.CppRuleClasses;
import com.google.devtools.build.lib.rules.java.JavaConfiguration;
@@ -82,6 +84,8 @@ public class BazelAndroidBinaryRule implements RuleDefinition {
</ul>
<!-- #END_BLAZE_RULE.IMPLICIT_OUTPUTS --> */
.setImplicitOutputsFunction(AndroidRuleClasses.ANDROID_BINARY_IMPLICIT_OUTPUTS)
+ .cfg(
+ new ConfigFeatureFlagTransitionFactory(AndroidFeatureFlagSetProvider.FEATURE_FLAG_ATTR))
.build();
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinary.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinary.java
index 655d546568..29dad5109b 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinary.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinary.java
@@ -809,7 +809,7 @@ public abstract class AndroidBinary implements RuleConfiguredTargetFactory {
return builder
.setFilesToBuild(filesToBuild)
- .add(
+ .addProvider(
RunfilesProvider.class,
RunfilesProvider.simple(
new Runfiles.Builder(
@@ -818,16 +818,20 @@ public abstract class AndroidBinary implements RuleConfiguredTargetFactory {
.addRunfiles(ruleContext, RunfilesProvider.DEFAULT_RUNFILES)
.addTransitiveArtifacts(filesToBuild)
.build()))
- .add(
+ .addProvider(
JavaSourceInfoProvider.class,
JavaSourceInfoProvider.fromJavaTargetAttributes(resourceClasses, javaSemantics))
- .add(
+ .addProvider(
ApkProvider.class,
ApkProvider.create(
NestedSetBuilder.create(Order.STABLE_ORDER, zipAlignedApk),
coverageMetadata,
NestedSetBuilder.create(Order.STABLE_ORDER, applicationManifest.getManifest())))
- .add(AndroidPreDexJarProvider.class, AndroidPreDexJarProvider.create(jarToDex))
+ .addProvider(AndroidPreDexJarProvider.class, AndroidPreDexJarProvider.create(jarToDex))
+ .addProvider(
+ AndroidFeatureFlagSetProvider.class,
+ AndroidFeatureFlagSetProvider.create(
+ AndroidFeatureFlagSetProvider.getAndValidateFlagMapFromRuleContext(ruleContext)))
.addOutputGroup("mobile_install_full" + INTERNAL_SUFFIX, fullInstallOutputGroup)
.addOutputGroup(
"mobile_install_incremental" + INTERNAL_SUFFIX, incrementalInstallOutputGroup)
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidFeatureFlagSetProvider.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidFeatureFlagSetProvider.java
new file mode 100644
index 0000000000..315aea19c6
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidFeatureFlagSetProvider.java
@@ -0,0 +1,82 @@
+// Copyright 2017 The Bazel Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.devtools.build.lib.rules.android;
+
+import com.google.auto.value.AutoValue;
+import com.google.common.collect.ImmutableMap;
+import com.google.devtools.build.lib.analysis.RuleConfiguredTarget.Mode;
+import com.google.devtools.build.lib.analysis.RuleContext;
+import com.google.devtools.build.lib.analysis.TransitiveInfoCollection;
+import com.google.devtools.build.lib.analysis.TransitiveInfoProvider;
+import com.google.devtools.build.lib.cmdline.Label;
+import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
+import com.google.devtools.build.lib.packages.BuildType;
+import com.google.devtools.build.lib.packages.NonconfigurableAttributeMapper;
+import com.google.devtools.build.lib.packages.RuleClass.ConfiguredTargetFactory.RuleErrorException;
+import com.google.devtools.build.lib.rules.config.ConfigFeatureFlagProvider;
+import java.util.Map;
+
+/**
+ * Provider for checking the set of feature flags used by an android_binary.
+ *
+ * <p>Because the feature flags are completely replaced by android_binary, android_test uses this
+ * provider to ensure that the test sets the same flags as the binary. Otherwise, the dependencies
+ * of the android_test will be compiled with different flags from the android_binary code which runs
+ * in the same Android virtual machine, which may cause compatibility issues at runtime.
+ */
+@AutoValue
+@Immutable
+public abstract class AndroidFeatureFlagSetProvider implements TransitiveInfoProvider {
+
+ /** The name of the attribute used by Android rules to set config_feature_flags. */
+ public static final String FEATURE_FLAG_ATTR = "feature_flags";
+
+ AndroidFeatureFlagSetProvider() {}
+
+ /** Creates a new AndroidFeatureFlagSetProvider with the given flags. */
+ public static AndroidFeatureFlagSetProvider create(Map<Label, String> flags) {
+ return new AutoValue_AndroidFeatureFlagSetProvider(ImmutableMap.copyOf(flags));
+ }
+
+ /**
+ * Builds a map which can be used with create, confirming that the desired flag values were
+ * actually received, and producing an error if they were not (because dynamic configurations are
+ * not enabled).
+ */
+ public static ImmutableMap<Label, String> getAndValidateFlagMapFromRuleContext(
+ RuleContext ruleContext) throws RuleErrorException {
+ Map<Label, String> expectedValues =
+ NonconfigurableAttributeMapper.of(ruleContext.getRule())
+ .get(FEATURE_FLAG_ATTR, BuildType.LABEL_KEYED_STRING_DICT);
+ Iterable<? extends TransitiveInfoCollection> actualTargets =
+ ruleContext.getPrerequisites(FEATURE_FLAG_ATTR, Mode.TARGET);
+ for (TransitiveInfoCollection target : actualTargets) {
+ Label label = target.getLabel();
+ String expectedValue = expectedValues.get(label);
+ String actualValue = ConfigFeatureFlagProvider.fromTarget(target).getValue();
+
+ if (!expectedValue.equals(actualValue)) {
+ // TODO(mstaib): when static configurations are removed, remove this error case
+ ruleContext.attributeError(
+ FEATURE_FLAG_ATTR,
+ "Setting " + FEATURE_FLAG_ATTR + " requires dynamic configurations to be enabled");
+ throw new RuleErrorException();
+ }
+ }
+ return ImmutableMap.copyOf(expectedValues);
+ }
+
+ public abstract ImmutableMap<Label, String> getFlags();
+}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidRuleClasses.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidRuleClasses.java
index 7a05c36d0c..7c289e3ccb 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidRuleClasses.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidRuleClasses.java
@@ -16,6 +16,7 @@ package com.google.devtools.build.lib.rules.android;
import static com.google.devtools.build.lib.packages.Attribute.ConfigurationTransition.HOST;
import static com.google.devtools.build.lib.packages.Attribute.attr;
import static com.google.devtools.build.lib.packages.BuildType.LABEL;
+import static com.google.devtools.build.lib.packages.BuildType.LABEL_KEYED_STRING_DICT;
import static com.google.devtools.build.lib.packages.BuildType.LABEL_LIST;
import static com.google.devtools.build.lib.packages.BuildType.TRISTATE;
import static com.google.devtools.build.lib.packages.ImplicitOutputsFunction.fromTemplates;
@@ -46,6 +47,7 @@ import com.google.devtools.build.lib.packages.RuleClass.Builder;
import com.google.devtools.build.lib.packages.RuleClass.Builder.RuleClassType;
import com.google.devtools.build.lib.packages.TriState;
import com.google.devtools.build.lib.rules.android.AndroidConfiguration.ConfigurationDistinguisher;
+import com.google.devtools.build.lib.rules.config.ConfigFeatureFlagProvider;
import com.google.devtools.build.lib.rules.cpp.CppOptions;
import com.google.devtools.build.lib.rules.java.JavaCompilationArgsProvider;
import com.google.devtools.build.lib.rules.java.JavaConfiguration;
@@ -795,6 +797,12 @@ public final class AndroidRuleClasses {
Rex suggests an updated package map that can be saved and reused for subsequent builds.
*/
.add(attr("rex_package_map", LABEL).legacyAllowAnyFileType().undocumented("experimental"))
+ .add(attr(AndroidFeatureFlagSetProvider.FEATURE_FLAG_ATTR, LABEL_KEYED_STRING_DICT)
+ .undocumented("the feature flag feature has not yet been launched")
+ .allowedRuleClasses("config_feature_flag")
+ .allowedFileTypes()
+ .nonconfigurable("defines an aspect of configuration")
+ .mandatoryProviders(ImmutableList.of(ConfigFeatureFlagProvider.SKYLARK_IDENTIFIER)))
.advertiseProvider(JavaCompilationArgsProvider.class)
.build();
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/config/ConfigFeatureFlagProvider.java b/src/main/java/com/google/devtools/build/lib/rules/config/ConfigFeatureFlagProvider.java
index 1bc6481234..265388eb1f 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/config/ConfigFeatureFlagProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/config/ConfigFeatureFlagProvider.java
@@ -46,8 +46,13 @@ public abstract class ConfigFeatureFlagProvider extends SkylarkClassObject
static final ClassObjectConstructor SKYLARK_CONSTRUCTOR =
new NativeClassObjectConstructor(SKYLARK_NAME) {};
- /** Identifier used to retrieve this provider from rules which export it. */
- static final SkylarkProviderIdentifier SKYLARK_IDENTIFIER =
+ /**
+ * Identifier used to retrieve this provider from rules which export it.
+ *
+ * <p>Prefer to use {@link #fromTarget(TransitiveInfoCollection)} for the purposes of getting this
+ * provider from a TransitiveInfoCollection; this should be used for mandatoryProviders only.
+ */
+ public static final SkylarkProviderIdentifier SKYLARK_IDENTIFIER =
SkylarkProviderIdentifier.forKey(SKYLARK_CONSTRUCTOR.getKey());
ConfigFeatureFlagProvider() {