diff options
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/rules/android/AndroidConfiguration.java')
-rw-r--r-- | src/main/java/com/google/devtools/build/lib/rules/android/AndroidConfiguration.java | 63 |
1 files changed, 60 insertions, 3 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidConfiguration.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidConfiguration.java index ee55622edb..0383f03191 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidConfiguration.java +++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidConfiguration.java @@ -31,6 +31,7 @@ import com.google.devtools.build.lib.analysis.config.InvalidConfigurationExcepti import com.google.devtools.build.lib.packages.Attribute.SplitTransition; import com.google.devtools.build.lib.syntax.Label; import com.google.devtools.common.options.Converters; +import com.google.devtools.common.options.EnumConverter; import com.google.devtools.common.options.Option; import java.util.List; @@ -40,9 +41,48 @@ import java.util.List; */ public class AndroidConfiguration extends BuildConfiguration.Fragment { /** + * Value used to avoid multiple configurations from conflicting. + * + * <p>This is set to {@code ANDROID} in Android configurations and to {@code MAIN} otherwise. This + * influences the output directory name: if it didn't, an Android and a non-Android configuration + * would conflict if they had the same toolchain identifier. + * + * <p>Note that this is not just a theoretical concern: even if {@code --crosstool_top} and + * {@code --android_crosstool_top} point to different labels, they may end up being redirected to + * the same thing, and this is exactly what happens on OSX X. + */ + public enum ConfigurationDistinguisher { + MAIN(null), + ANDROID("android"); + + private final String suffix; + + private ConfigurationDistinguisher(String suffix) { + this.suffix = suffix; + }; + } + + /** + * Converter for {@link com.google.devtools.build.lib.rules.android.AndroidConfiguration.ConfigurationDistinguisher} + */ + public static final class ConfigurationDistinguisherConverter + extends EnumConverter<ConfigurationDistinguisher> { + public ConfigurationDistinguisherConverter() { + super(ConfigurationDistinguisher.class, "Android configuration distinguisher"); + } + } + + /** * Android configuration options. */ public static class Options extends FragmentOptions { + // Spaces make it impossible to specify this on the command line + @Option(name = "Android configuration distinguisher", + defaultValue = "MAIN", + converter = ConfigurationDistinguisherConverter.class, + category = "undocumented") + public ConfigurationDistinguisher configurationDistinguisher; + @Option(name = "android_crosstool_top", defaultValue = "null", category = "semantics", @@ -120,8 +160,8 @@ public class AndroidConfiguration extends BuildConfiguration.Fragment { labelMap.put("android_proguard", proguard); } - if (androidCrosstoolTop != null) { - labelMap.put("android_crosstool_top", androidCrosstoolTop); + if (realAndroidCrosstoolTop() != null) { + labelMap.put("android_crosstool_top", realAndroidCrosstoolTop()); } labelMap.put("android_sdk", realSdk()); @@ -136,6 +176,21 @@ public class AndroidConfiguration extends BuildConfiguration.Fragment { : sdk; } + // This method is here because Constants.ANDROID_DEFAULT_CROSSTOOL cannot be a constant, because + // we replace the class file in the .jar after compilation. However, that means that we cannot + // use it as an attribute value in an annotation. + public Label realAndroidCrosstoolTop() { + if (androidCrosstoolTop != null) { + return androidCrosstoolTop; + } + + if (Constants.ANDROID_DEFAULT_CROSSTOOL.equals("null")) { + return null; + } + + return Label.parseAbsoluteUnchecked(Constants.ANDROID_DEFAULT_CROSSTOOL); + } + @Override public ImmutableList<String> getDefaultsRules() { return ImmutableList.of("android_tools_defaults_jar(name = 'android_jar')"); @@ -173,6 +228,7 @@ public class AndroidConfiguration extends BuildConfiguration.Fragment { private final boolean legacyNativeSupport; private final String cpu; private final boolean fatApk; + private final ConfigurationDistinguisher configurationDistinguisher; private final Label proguard; private final boolean useJackForDexing; private final boolean jackSanityChecks; @@ -183,6 +239,7 @@ public class AndroidConfiguration extends BuildConfiguration.Fragment { this.legacyNativeSupport = options.legacyNativeSupport; this.cpu = options.cpu; this.fatApk = !options.fatApkCpus.isEmpty(); + this.configurationDistinguisher = options.configurationDistinguisher; this.proguard = options.proguard; this.useJackForDexing = options.useJackForDexing; this.jackSanityChecks = options.jackSanityChecks; @@ -230,7 +287,7 @@ public class AndroidConfiguration extends BuildConfiguration.Fragment { @Override public String getOutputDirectoryName() { - return fatApk ? "fat-apk" : null; + return configurationDistinguisher.suffix; } public Label getProguardLabel() { |