Read android sdk from toolchain instead of attribute when --incompatible_enable_android_toolchain_resolution is set.
@@ -19,7 +19,11 @@ import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.analysis.FilesToRunProvider;
import com.google.devtools.build.lib.analysis.RuleContext;
import com.google.devtools.build.lib.analysis.TransitiveInfoCollection;
+import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
+import com.google.devtools.build.lib.analysis.platform.ToolchainInfo;
+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.BuiltinProvider;
import com.google.devtools.build.lib.packages.NativeInfo;
import com.google.devtools.build.lib.packages.RuleClass.ConfiguredTargetFactory.RuleErrorException;
@@ -100,8 +104,62 @@ public final class AndroidSdkProvider extends NativeInfo
/**
* Returns the Android SDK associated with the rule being analyzed or null if the Android SDK is
* not specified.
+ *
+ * <p>First tries to read from toolchains if
+ * --incompatible_enable_android_toolchain_resolution=true, else, uses the legacy attribute..
*/
public static AndroidSdkProvider fromRuleContext(RuleContext ruleContext) {
+ BuildConfiguration configuration = ruleContext.getConfiguration();
+ if (configuration != null
+ && configuration.hasFragment(AndroidConfiguration.class)
+ && configuration
+ .getFragment(AndroidConfiguration.class)
+ .incompatibleUseToolchainResolution()) {
+ if (ruleContext.getToolchainContext() == null) {
+ ruleContext.ruleError(
+ String.format(
+ "'%s' rule '%s' requested sdk toolchain resolution via"
+ + " --incompatible_enable_android_toolchain_resolution but doesn't use"
+ + " toolchain resolution.",
+ ruleContext.getRuleClassNameForLogging(), ruleContext.getLabel()));
+ return null;
+ }
+ Label toolchainType =
+ ruleContext
+ .attributes()
+ .get(ANDROID_SDK_TOOLCHAIN_TYPE_ATTRIBUTE_NAME, BuildType.NODEP_LABEL);
+ if (toolchainType == null) {
+ ruleContext.ruleError(
+ String.format(
+ "'%s' rule '%s' requested sdk toolchain resolution via"
+ + " --incompatible_enable_android_toolchain_resolution but doesn't have"
+ + " toolchain type attribute '%s'.",
+ ruleContext.getRuleClassNameForLogging(),
+ ruleContext.getLabel(),
+ ANDROID_SDK_TOOLCHAIN_TYPE_ATTRIBUTE_NAME));
+ return null;
+ }
+ ToolchainInfo info = ruleContext.getToolchainContext().forToolchainType(toolchainType);
+ if (info == null) {
+ ruleContext.ruleError(
+ String.format(
+ "'%s' rule '%s' requested sdk toolchain resolution via"
+ + " --incompatible_enable_android_toolchain_resolution but doesn't have a"
+ + " toolchain for '%s'.",
+ ruleContext.getRuleClassNameForLogging(), ruleContext.getLabel(), toolchainType));
+ return null;
+ }
+ try {
+ return (AndroidSdkProvider) info.getValue("android_sdk_info");
+ } catch (EvalException e) {
+ ruleContext.ruleError(
+ String.format(
+ "Android SDK toolchain for %s didn't have an 'android_sdk_info' provider: %s",
+ ruleContext.getLabel(), e.getMessage()));
+ return null;
+ }
+ }
+
return ruleContext.getPrerequisite(":android_sdk", AndroidSdkProvider.PROVIDER);
}
