diff options
16 files changed, 296 insertions, 72 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AarImport.java b/src/main/java/com/google/devtools/build/lib/rules/android/AarImport.java index 1e9f5c58d7..15276ed030 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/android/AarImport.java +++ b/src/main/java/com/google/devtools/build/lib/rules/android/AarImport.java @@ -31,6 +31,7 @@ import com.google.devtools.build.lib.analysis.actions.SpawnAction; import com.google.devtools.build.lib.analysis.configuredtargets.RuleConfiguredTarget.Mode; import com.google.devtools.build.lib.collect.nestedset.NestedSet; import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; +import com.google.devtools.build.lib.rules.android.AndroidConfiguration.AndroidAaptVersion; import com.google.devtools.build.lib.rules.java.ImportDepsCheckActionBuilder; import com.google.devtools.build.lib.rules.java.JavaCommon; import com.google.devtools.build.lib.rules.java.JavaCompilationArgs; @@ -108,7 +109,10 @@ public class AarImport implements RuleConfiguredTargetFactory { .process(ruleContext, dataContext, manifest, neverlink); MergedAndroidAssets mergedAssets = AndroidAssets.forAarImport(assets) - .process(dataContext, AssetDependencies.fromRuleDeps(ruleContext, neverlink)); + .process( + dataContext, + AssetDependencies.fromRuleDeps(ruleContext, neverlink), + AndroidAaptVersion.chooseTargetAaptVersion(ruleContext)); resourceApk = ResourceApk.of(validatedResources, mergedAssets, null, null); } else { diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidAssets.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidAssets.java index 423c380bf2..5978cc30e1 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidAssets.java +++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidAssets.java @@ -24,6 +24,7 @@ import com.google.devtools.build.lib.analysis.TransitiveInfoCollection; import com.google.devtools.build.lib.analysis.configuredtargets.RuleConfiguredTarget.Mode; import com.google.devtools.build.lib.packages.RuleClass.ConfiguredTargetFactory.RuleErrorException; import com.google.devtools.build.lib.packages.RuleErrorConsumer; +import com.google.devtools.build.lib.rules.android.AndroidConfiguration.AndroidAaptVersion; import com.google.devtools.build.lib.syntax.Type; import com.google.devtools.build.lib.vfs.PathFragment; import java.util.Objects; @@ -174,14 +175,16 @@ public class AndroidAssets { return assetDir; } - public ParsedAndroidAssets parse(AndroidDataContext dataContext) throws InterruptedException { - return ParsedAndroidAssets.parseFrom(dataContext, this); + public ParsedAndroidAssets parse(AndroidDataContext dataContext, AndroidAaptVersion aaptVersion) + throws InterruptedException { + return ParsedAndroidAssets.parseFrom(dataContext, aaptVersion, this); } /** Convenience method to do all of asset processing - parsing and merging. */ - public MergedAndroidAssets process(AndroidDataContext dataContext, AssetDependencies assetDeps) + public MergedAndroidAssets process( + AndroidDataContext dataContext, AssetDependencies assetDeps, AndroidAaptVersion aaptVersion) throws InterruptedException { - return parse(dataContext).merge(dataContext, assetDeps); + return parse(dataContext, aaptVersion).merge(dataContext, assetDeps); } @Override diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidAssetsInfo.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidAssetsInfo.java index 334dba204c..8920e57189 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidAssetsInfo.java +++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidAssetsInfo.java @@ -46,6 +46,7 @@ public class AndroidAssetsInfo extends NativeInfo implements AndroidAssetsInfoAp * contains assets form the target's dependencies. */ private final boolean hasLocalAssets; + private final NestedSet<Artifact> transitiveCompiledSymbols; static AndroidAssetsInfo empty(Label label) { return new AndroidAssetsInfo( @@ -54,6 +55,7 @@ public class AndroidAssetsInfo extends NativeInfo implements AndroidAssetsInfoAp NestedSetBuilder.emptySet(Order.NAIVE_LINK_ORDER), NestedSetBuilder.emptySet(Order.NAIVE_LINK_ORDER), NestedSetBuilder.emptySet(Order.NAIVE_LINK_ORDER), + NestedSetBuilder.emptySet(Order.NAIVE_LINK_ORDER), NestedSetBuilder.emptySet(Order.NAIVE_LINK_ORDER)); } @@ -63,14 +65,16 @@ public class AndroidAssetsInfo extends NativeInfo implements AndroidAssetsInfoAp NestedSet<ParsedAndroidAssets> directParsedAssets, NestedSet<ParsedAndroidAssets> transitiveParsedAssets, NestedSet<Artifact> transitiveAssets, - NestedSet<Artifact> transitiveSymbols) { + NestedSet<Artifact> transitiveSymbols, + NestedSet<Artifact> transitiveCompiledSymbols) { return new AndroidAssetsInfo( label, validationResult, directParsedAssets, transitiveParsedAssets, transitiveAssets, - transitiveSymbols); + transitiveSymbols, + transitiveCompiledSymbols); } private AndroidAssetsInfo( @@ -79,7 +83,8 @@ public class AndroidAssetsInfo extends NativeInfo implements AndroidAssetsInfoAp NestedSet<ParsedAndroidAssets> directParsedAssets, NestedSet<ParsedAndroidAssets> transitiveParsedAssets, NestedSet<Artifact> transitiveAssets, - NestedSet<Artifact> transitiveSymbols) { + NestedSet<Artifact> transitiveSymbols, + NestedSet<Artifact> transitiveCompiledSymbols) { super(PROVIDER); this.label = label; this.hasLocalAssets = validationResult != null; @@ -88,6 +93,7 @@ public class AndroidAssetsInfo extends NativeInfo implements AndroidAssetsInfoAp this.transitiveParsedAssets = transitiveParsedAssets; this.transitiveAssets = transitiveAssets; this.transitiveSymbols = transitiveSymbols; + this.transitiveCompiledSymbols = transitiveCompiledSymbols; } public Label getLabel() { @@ -132,4 +138,8 @@ public class AndroidAssetsInfo extends NativeInfo implements AndroidAssetsInfoAp ? Optional.of(Iterables.getOnlyElement(getDirectParsedAssets())) : Optional.empty(); } + + public NestedSet<Artifact> getCompiledSymbols() { + return transitiveCompiledSymbols; + } } diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLibrary.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLibrary.java index f4ed5d53eb..7c142a167e 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLibrary.java +++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLibrary.java @@ -27,6 +27,7 @@ import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; import com.google.devtools.build.lib.packages.AttributeMap; import com.google.devtools.build.lib.packages.BuildType; import com.google.devtools.build.lib.packages.TriState; +import com.google.devtools.build.lib.rules.android.AndroidConfiguration.AndroidAaptVersion; import com.google.devtools.build.lib.rules.android.AndroidLibraryAarInfo.Aar; import com.google.devtools.build.lib.rules.java.JavaCommon; import com.google.devtools.build.lib.rules.java.JavaSemantics; @@ -158,7 +159,11 @@ public abstract class AndroidLibrary implements RuleConfiguredTargetFactory { .process(ruleContext, dataContext, manifest, isNeverLink); MergedAndroidAssets assets = - AndroidAssets.from(ruleContext).process(dataContext, assetDeps); + AndroidAssets.from(ruleContext) + .process( + dataContext, + assetDeps, + AndroidAaptVersion.chooseTargetAaptVersion(ruleContext)); resourceApk = ResourceApk.of(resources, assets, null, null); } else { diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidResourceParsingActionBuilder.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidResourceParsingActionBuilder.java index 13976552ef..aff8128419 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidResourceParsingActionBuilder.java +++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidResourceParsingActionBuilder.java @@ -136,7 +136,7 @@ public class AndroidResourceParsingActionBuilder { setAssets(assets); build(dataContext); - return ParsedAndroidAssets.of(assets, output, dataContext.getLabel()); + return ParsedAndroidAssets.of(assets, output, compiledSymbols, dataContext.getLabel()); } /** diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidResourcesProcessorBuilder.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidResourcesProcessorBuilder.java index 58c0a6669a..af7189353d 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidResourcesProcessorBuilder.java +++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidResourcesProcessorBuilder.java @@ -24,6 +24,22 @@ import java.util.List; /** Builder for creating resource processing action. */ public class AndroidResourcesProcessorBuilder { + private static final AndroidDataConverter<ParsedAndroidAssets> AAPT2_ASSET_DEP_TO_ARG = + AndroidDataConverter.<ParsedAndroidAssets>builder(JoinerType.SEMICOLON_AMPERSAND) + .withRoots(ParsedAndroidAssets::getResourceRoots) + .withRoots(ParsedAndroidAssets::getAssetRoots) + .withLabel(ParsedAndroidAssets::getLabel) + .withArtifact(ParsedAndroidAssets::getSymbols) + .build(); + + private static final AndroidDataConverter<ParsedAndroidAssets> AAPT2_ASSET_DEP_TO_ARG_NO_PARSE = + AndroidDataConverter.<ParsedAndroidAssets>builder(JoinerType.SEMICOLON_AMPERSAND) + .withRoots(ParsedAndroidAssets::getResourceRoots) + .withRoots(ParsedAndroidAssets::getAssetRoots) + .withLabel(ParsedAndroidAssets::getLabel) + .withArtifact(ParsedAndroidAssets::getCompiledSymbols) + .build(); + private static final AndroidDataConverter<ValidatedAndroidData> AAPT2_RESOURCE_DEP_TO_ARG = AndroidDataConverter.<ValidatedAndroidData>builder(JoinerType.COLON_COMMA) .withRoots(ValidatedAndroidData::getResourceRoots) @@ -276,7 +292,8 @@ public class AndroidResourcesProcessorBuilder { // Wrap the parsed and merged assets ParsedAndroidAssets parsedAssets = - ParsedAndroidAssets.of(primaryAssets, symbols, dataContext.getLabel()); + ParsedAndroidAssets.of( + primaryAssets, symbols, /* compiledSymbols = */ null, dataContext.getLabel()); MergedAndroidAssets mergedAssets = MergedAndroidAssets.of(parsedAssets, mergedResourcesOut, assetDependencies); @@ -364,7 +381,28 @@ public class AndroidResourcesProcessorBuilder { } } - addAssetDeps(builder) + if (assetDependencies != null && !assetDependencies.getTransitiveAssets().isEmpty()) { + builder + .addTransitiveFlag( + "--directAssets", + assetDependencies.getDirectParsedAssets(), + useCompiledResourcesForMerge + ? AAPT2_ASSET_DEP_TO_ARG_NO_PARSE + : AAPT2_ASSET_DEP_TO_ARG) + .addTransitiveFlag( + "--assets", + assetDependencies.getTransitiveParsedAssets(), + useCompiledResourcesForMerge + ? AAPT2_ASSET_DEP_TO_ARG_NO_PARSE + : AAPT2_ASSET_DEP_TO_ARG) + .addTransitiveInputValues(assetDependencies.getTransitiveAssets()) + .addTransitiveInputValues( + useCompiledResourcesForMerge + ? assetDependencies.getTransitiveCompiledSymbols() + : assetDependencies.getTransitiveSymbols()); + } + + builder .maybeAddFlag("--useCompiledResourcesForMerge", useCompiledResourcesForMerge) .maybeAddFlag("--conditionalKeepRules", conditionalKeepRules); @@ -394,7 +432,21 @@ public class AndroidResourcesProcessorBuilder { .addTransitiveInputValues(resourceDependencies.getTransitiveSymbolsBin()); } - addAssetDeps(builder).addAapt(AndroidAaptVersion.AAPT); + if (assetDependencies != null && !assetDependencies.getTransitiveAssets().isEmpty()) { + builder + .addTransitiveFlag( + "--directAssets", + assetDependencies.getDirectParsedAssets(), + AndroidDataConverter.MERGABLE_DATA_CONVERTER) + .addTransitiveFlag( + "--assets", + assetDependencies.getTransitiveParsedAssets(), + AndroidDataConverter.MERGABLE_DATA_CONVERTER) + .addTransitiveInputValues(assetDependencies.getTransitiveAssets()) + .addTransitiveInputValues(assetDependencies.getTransitiveSymbols()); + } + + builder.addAapt(AndroidAaptVersion.AAPT); configureCommonFlags(dataContext, primaryResources, primaryAssets, primaryManifest, builder) .maybeAddVectoredFlag( @@ -402,24 +454,6 @@ public class AndroidResourcesProcessorBuilder { .buildAndRegister("Processing Android resources", "AaptPackage"); } - private BusyBoxActionBuilder addAssetDeps(BusyBoxActionBuilder builder) { - if (assetDependencies == null || assetDependencies.getTransitiveAssets().isEmpty()) { - return builder; - } - - return builder - .addTransitiveFlag( - "--directAssets", - assetDependencies.getDirectParsedAssets(), - AndroidDataConverter.MERGABLE_DATA_CONVERTER) - .addTransitiveFlag( - "--assets", - assetDependencies.getTransitiveParsedAssets(), - AndroidDataConverter.MERGABLE_DATA_CONVERTER) - .addTransitiveInputValues(assetDependencies.getTransitiveAssets()) - .addTransitiveInputValues(assetDependencies.getTransitiveSymbols()); - } - private BusyBoxActionBuilder configureCommonFlags( AndroidDataContext dataContext, AndroidResources primaryResources, 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 815616d236..629c000b66 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 @@ -141,6 +141,8 @@ public final class AndroidRuleClasses { fromTemplates("%{name}_symbols/assets.bin"); public static final SafeImplicitOutputsFunction ANDROID_COMPILED_SYMBOLS = fromTemplates("%{name}_symbols/symbols.zip"); + public static final SafeImplicitOutputsFunction ANDROID_ASSET_COMPILED_SYMBOLS = + fromTemplates("%{name}_symbols/assets.zip"); public static final SafeImplicitOutputsFunction ANDROID_SYMLINKED_MANIFEST = fromTemplates("%{name}_symlinked_manifest/AndroidManifest.xml"); public static final SafeImplicitOutputsFunction ANDROID_PROCESSED_MANIFEST = diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidSkylarkData.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidSkylarkData.java index 3d2bc56f2c..55fbbe574c 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidSkylarkData.java +++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidSkylarkData.java @@ -289,7 +289,10 @@ public abstract class AndroidSkylarkData { errorReporter, listFromNoneable(assets, ConfiguredTarget.class), isNone(assetsDir) ? null : PathFragment.create(fromNoneable(assetsDir, String.class))) - .process(ctx, AssetDependencies.fromProviders(deps.getImmutableList(), neverlink)) + .process( + ctx, + AssetDependencies.fromProviders(deps.getImmutableList(), neverlink), + ctx.getAndroidConfig().getAndroidAaptVersion()) .toProvider(); } catch (RuleErrorException e) { throw new EvalException(Location.BUILTIN, e); @@ -731,7 +734,8 @@ public abstract class AndroidSkylarkData { .process( ctx, AssetDependencies.fromProviders( - getProviders(deps, AndroidAssetsInfo.PROVIDER), /* neverlink = */ false)); + getProviders(deps, AndroidAssetsInfo.PROVIDER), /* neverlink = */ false), + aaptVersion); ResourceApk resourceApk = ResourceApk.of(validatedResources, mergedAssets, null, null); diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AssetDependencies.java b/src/main/java/com/google/devtools/build/lib/rules/android/AssetDependencies.java index 1cfe929fc6..531d2501cf 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/android/AssetDependencies.java +++ b/src/main/java/com/google/devtools/build/lib/rules/android/AssetDependencies.java @@ -37,6 +37,7 @@ public class AssetDependencies { private final NestedSet<ParsedAndroidAssets> transitiveParsedAssets; private final NestedSet<Artifact> transitiveAssets; private final NestedSet<Artifact> transitiveSymbols; + private final NestedSet<Artifact> transitiveCompiledSymbols; public static AssetDependencies fromRuleDeps(RuleContext ruleContext, boolean neverlink) { return fromProviders( @@ -51,15 +52,23 @@ public class AssetDependencies { NestedSetBuilder<ParsedAndroidAssets> transitive = NestedSetBuilder.naiveLinkOrder(); NestedSetBuilder<Artifact> assets = NestedSetBuilder.naiveLinkOrder(); NestedSetBuilder<Artifact> symbols = NestedSetBuilder.naiveLinkOrder(); + NestedSetBuilder<Artifact> compiledSymbols = NestedSetBuilder.naiveLinkOrder(); for (AndroidAssetsInfo info : providers) { direct.addTransitive(info.getDirectParsedAssets()); transitive.addTransitive(info.getTransitiveParsedAssets()); assets.addTransitive(info.getAssets()); symbols.addTransitive(info.getSymbols()); + compiledSymbols.addTransitive(info.getCompiledSymbols()); } - return of(neverlink, direct.build(), transitive.build(), assets.build(), symbols.build()); + return of( + neverlink, + direct.build(), + transitive.build(), + assets.build(), + symbols.build(), + compiledSymbols.build()); } public static AssetDependencies empty() { @@ -68,6 +77,7 @@ public class AssetDependencies { NestedSetBuilder.emptySet(Order.NAIVE_LINK_ORDER), NestedSetBuilder.emptySet(Order.NAIVE_LINK_ORDER), NestedSetBuilder.emptySet(Order.NAIVE_LINK_ORDER), + NestedSetBuilder.emptySet(Order.NAIVE_LINK_ORDER), NestedSetBuilder.emptySet(Order.NAIVE_LINK_ORDER)); } @@ -77,9 +87,15 @@ public class AssetDependencies { NestedSet<ParsedAndroidAssets> directParsedAssets, NestedSet<ParsedAndroidAssets> transitiveParsedAssets, NestedSet<Artifact> transitiveAssets, - NestedSet<Artifact> transitiveSymbols) { + NestedSet<Artifact> transitiveSymbols, + NestedSet<Artifact> transitiveCompiledSymbols) { return new AssetDependencies( - neverlink, directParsedAssets, transitiveParsedAssets, transitiveAssets, transitiveSymbols); + neverlink, + directParsedAssets, + transitiveParsedAssets, + transitiveAssets, + transitiveSymbols, + transitiveCompiledSymbols); } private AssetDependencies( @@ -87,12 +103,14 @@ public class AssetDependencies { NestedSet<ParsedAndroidAssets> directParsedAssets, NestedSet<ParsedAndroidAssets> transitiveParsedAssets, NestedSet<Artifact> transitiveAssets, - NestedSet<Artifact> transitiveSymbols) { + NestedSet<Artifact> transitiveSymbols, + NestedSet<Artifact> transitiveCompiledSymbols) { this.neverlink = neverlink; this.directParsedAssets = directParsedAssets; this.transitiveParsedAssets = transitiveParsedAssets; this.transitiveAssets = transitiveAssets; this.transitiveSymbols = transitiveSymbols; + this.transitiveCompiledSymbols = transitiveCompiledSymbols; } /** Creates a new AndroidAssetInfo using the passed assets as the direct dependency. */ @@ -104,6 +122,13 @@ public class AssetDependencies { // Create a new object to avoid passing around unwanted merge information to the provider ParsedAndroidAssets parsedAssets = new ParsedAndroidAssets(assets); + NestedSetBuilder<Artifact> transitiveCompiledSymbolsBuilder = + NestedSetBuilder.<Artifact>naiveLinkOrder().addTransitive(transitiveCompiledSymbols); + + if (assets.getCompiledSymbols() != null) { + transitiveCompiledSymbolsBuilder.add(assets.getCompiledSymbols()); + } + return AndroidAssetsInfo.of( assets.getLabel(), assets.getMergedAssets(), @@ -119,7 +144,8 @@ public class AssetDependencies { NestedSetBuilder.<Artifact>naiveLinkOrder() .addTransitive(transitiveSymbols) .add(assets.getSymbols()) - .build()); + .build(), + transitiveCompiledSymbolsBuilder.build()); } /** Creates a new AndroidAssetsInfo from this target's dependencies, without any local assets. */ @@ -134,7 +160,8 @@ public class AssetDependencies { directParsedAssets, transitiveParsedAssets, transitiveAssets, - transitiveSymbols); + transitiveSymbols, + transitiveCompiledSymbols); } public NestedSet<ParsedAndroidAssets> getDirectParsedAssets() { @@ -152,4 +179,8 @@ public class AssetDependencies { public NestedSet<Artifact> getTransitiveSymbols() { return transitiveSymbols; } + + public NestedSet<Artifact> getTransitiveCompiledSymbols() { + return transitiveCompiledSymbols; + } } diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/CompiledMergableAndroidData.java b/src/main/java/com/google/devtools/build/lib/rules/android/CompiledMergableAndroidData.java index 56c9f8085b..e931db4780 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/android/CompiledMergableAndroidData.java +++ b/src/main/java/com/google/devtools/build/lib/rules/android/CompiledMergableAndroidData.java @@ -14,7 +14,6 @@ package com.google.devtools.build.lib.rules.android; import com.google.devtools.build.lib.actions.Artifact; -import javax.annotation.Nullable; /** * A {@link MergableAndroidData} that may also contain a compiled symbols file. @@ -23,9 +22,6 @@ import javax.annotation.Nullable; * ResourceContainer} is removed, this interface can be replaced with {@link ParsedAndroidResources} */ public interface CompiledMergableAndroidData extends MergableAndroidData { - @Nullable - Artifact getCompiledSymbols(); - Iterable<Artifact> getArtifacts(); Artifact getManifest(); diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/MergableAndroidData.java b/src/main/java/com/google/devtools/build/lib/rules/android/MergableAndroidData.java index f79966d6c4..ecfd26cfdd 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/android/MergableAndroidData.java +++ b/src/main/java/com/google/devtools/build/lib/rules/android/MergableAndroidData.java @@ -17,6 +17,7 @@ import com.google.common.collect.ImmutableList; import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.cmdline.Label; import com.google.devtools.build.lib.vfs.PathFragment; +import javax.annotation.Nullable; /** * Interface used to indicate a container for resources, assets, or both can be merged. @@ -47,4 +48,7 @@ public interface MergableAndroidData { Label getLabel(); Artifact getSymbols(); + + @Nullable + Artifact getCompiledSymbols(); } diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/ParsedAndroidAssets.java b/src/main/java/com/google/devtools/build/lib/rules/android/ParsedAndroidAssets.java index b1b2971045..b30e95e871 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/android/ParsedAndroidAssets.java +++ b/src/main/java/com/google/devtools/build/lib/rules/android/ParsedAndroidAssets.java @@ -15,31 +15,45 @@ package com.google.devtools.build.lib.rules.android; import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.cmdline.Label; +import com.google.devtools.build.lib.rules.android.AndroidConfiguration.AndroidAaptVersion; import java.util.Objects; +import javax.annotation.Nullable; /** Parsed Android assets which can be merged together with assets from dependencies. */ public class ParsedAndroidAssets extends AndroidAssets implements MergableAndroidData { private final Artifact symbols; + @Nullable private final Artifact compiledSymbols; private final Label label; - public static ParsedAndroidAssets parseFrom(AndroidDataContext dataContext, AndroidAssets assets) + public static ParsedAndroidAssets parseFrom( + AndroidDataContext dataContext, AndroidAaptVersion aaptVersion, AndroidAssets assets) throws InterruptedException { - return new AndroidResourceParsingActionBuilder() - .setOutput(dataContext.createOutputArtifact(AndroidRuleClasses.ANDROID_ASSET_SYMBOLS)) - .build(dataContext, assets); + AndroidResourceParsingActionBuilder builder = + new AndroidResourceParsingActionBuilder() + .setOutput(dataContext.createOutputArtifact(AndroidRuleClasses.ANDROID_ASSET_SYMBOLS)); + + if (aaptVersion == AndroidAaptVersion.AAPT2) { + builder.setCompiledSymbolsOutput( + dataContext.createOutputArtifact(AndroidRuleClasses.ANDROID_ASSET_COMPILED_SYMBOLS)); + } + + return builder.build(dataContext, assets); } - public static ParsedAndroidAssets of(AndroidAssets assets, Artifact symbols, Label label) { - return new ParsedAndroidAssets(assets, symbols, label); + public static ParsedAndroidAssets of( + AndroidAssets assets, Artifact symbols, @Nullable Artifact compiledSymbols, Label label) { + return new ParsedAndroidAssets(assets, symbols, compiledSymbols, label); } ParsedAndroidAssets(ParsedAndroidAssets other) { - this(other, other.symbols, other.label); + this(other, other.symbols, other.compiledSymbols, other.label); } - private ParsedAndroidAssets(AndroidAssets other, Artifact symbols, Label label) { + private ParsedAndroidAssets( + AndroidAssets other, Artifact symbols, @Nullable Artifact compiledSymbols, Label label) { super(other); this.symbols = symbols; + this.compiledSymbols = compiledSymbols; this.label = label; } @@ -59,6 +73,12 @@ public class ParsedAndroidAssets extends AndroidAssets implements MergableAndroi } @Override + @Nullable + public Artifact getCompiledSymbols() { + return compiledSymbols; + } + + @Override public boolean equals(Object object) { if (!super.equals(object)) { return false; @@ -72,4 +92,5 @@ public class ParsedAndroidAssets extends AndroidAssets implements MergableAndroi public int hashCode() { return Objects.hash(super.hashCode(), symbols, label); } + } diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/ValidatedAndroidData.java b/src/main/java/com/google/devtools/build/lib/rules/android/ValidatedAndroidData.java index 2ab246c6b9..97bc3738f3 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/android/ValidatedAndroidData.java +++ b/src/main/java/com/google/devtools/build/lib/rules/android/ValidatedAndroidData.java @@ -62,4 +62,3 @@ public interface ValidatedAndroidData extends CompiledMergableAndroidData { ProcessedAndroidManifest getProcessedManifest(); } - diff --git a/src/test/java/com/google/devtools/build/lib/rules/android/AndroidAssetsTest.java b/src/test/java/com/google/devtools/build/lib/rules/android/AndroidAssetsTest.java index 1ee24231fa..3d47cb9b8e 100644 --- a/src/test/java/com/google/devtools/build/lib/rules/android/AndroidAssetsTest.java +++ b/src/test/java/com/google/devtools/build/lib/rules/android/AndroidAssetsTest.java @@ -22,6 +22,7 @@ import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.analysis.RuleContext; import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; import com.google.devtools.build.lib.collect.nestedset.Order; +import com.google.devtools.build.lib.rules.android.AndroidConfiguration.AndroidAaptVersion; import com.google.devtools.build.lib.vfs.PathFragment; import org.junit.Test; import org.junit.runner.RunWith; @@ -34,7 +35,8 @@ public class AndroidAssetsTest extends ResourceTestBase { public void testParse() throws Exception { RuleContext ruleContext = getRuleContext(); AndroidAssets assets = getLocalAssets(); - ParsedAndroidAssets parsed = assets.parse(AndroidDataContext.forNative(ruleContext)); + ParsedAndroidAssets parsed = + assets.parse(AndroidDataContext.forNative(ruleContext), AndroidAaptVersion.AAPT); // Assets should be unchanged assertThat(parsed.getAssets()).isEqualTo(assets.getAssets()); @@ -48,12 +50,48 @@ public class AndroidAssetsTest extends ResourceTestBase { ruleContext, /* inputs = */ assets.getAssets(), /* outputs = */ ImmutableList.of(parsed.getSymbols())); + + // There should be no compiled symbols + assertThat(parsed.getCompiledSymbols()).isNull(); + } + + @Test + public void testParseAapt2() throws Exception { + mockAndroidSdkWithAapt2(); + useConfiguration("--android_sdk=//sdk:sdk"); + + RuleContext ruleContext = getRuleContext(); + AndroidAssets assets = getLocalAssets(); + + ParsedAndroidAssets parsed = + assets.parse(AndroidDataContext.forNative(ruleContext), AndroidAaptVersion.AAPT2); + + // Assets should be unchanged + assertThat(parsed.getAssets()).isEqualTo(assets.getAssets()); + assertThat(parsed.getAssetRoots()).isEqualTo(assets.getAssetRoots()); + + // Label should be correct + assertThat(parsed.getLabel()).isEqualTo(ruleContext.getLabel()); + + // There should be compiled symbols + assertThat(parsed.getCompiledSymbols()).isNotNull(); + + // Symbols and compiled symbols files should be created from raw assets + assertActionArtifacts( + ruleContext, + /* inputs = */ assets.getAssets(), + /* outputs = */ ImmutableList.of(parsed.getSymbols())); + assertActionArtifacts( + ruleContext, + /* inputs = */ assets.getAssets(), + /* outputs = */ ImmutableList.of(parsed.getCompiledSymbols())); } @Test public void testMergeNoDeps() throws Exception { RuleContext ruleContext = getRuleContext(); - ParsedAndroidAssets parsed = getLocalAssets().parse(AndroidDataContext.forNative(ruleContext)); + ParsedAndroidAssets parsed = + getLocalAssets().parse(AndroidDataContext.forNative(ruleContext), AndroidAaptVersion.AAPT); MergedAndroidAssets merged = assertMerge(ruleContext, parsed, AssetDependencies.empty()); // The assets can be correctly built into a provider @@ -70,8 +108,9 @@ public class AndroidAssetsTest extends ResourceTestBase { @Test public void testMergeNeverlink() throws Exception { RuleContext ruleContext = getRuleContext(); - ParsedAndroidAssets parsed = getLocalAssets().parse(AndroidDataContext.forNative(ruleContext)); - AssetDependencies deps = makeDeps(ruleContext, /* neverlink = */ true); + ParsedAndroidAssets parsed = + getLocalAssets().parse(AndroidDataContext.forNative(ruleContext), AndroidAaptVersion.AAPT); + AssetDependencies deps = makeDeps(ruleContext, /* neverlink = */ true, AndroidAaptVersion.AAPT); MergedAndroidAssets merged = assertMerge(ruleContext, parsed, deps); @@ -83,13 +122,16 @@ public class AndroidAssetsTest extends ResourceTestBase { assertThat(info.getSymbols()).isEmpty(); assertThat(info.getDirectParsedAssets()).isEmpty(); assertThat(info.getTransitiveParsedAssets()).isEmpty(); + assertThat(info.getCompiledSymbols()).isEmpty(); } @Test public void testMerge() throws Exception { RuleContext ruleContext = getRuleContext(); - ParsedAndroidAssets parsed = getLocalAssets().parse(AndroidDataContext.forNative(ruleContext)); - AssetDependencies deps = makeDeps(ruleContext, /* neverlink = */ false); + ParsedAndroidAssets parsed = + getLocalAssets().parse(AndroidDataContext.forNative(ruleContext), AndroidAaptVersion.AAPT); + AssetDependencies deps = + makeDeps(ruleContext, /* neverlink = */ false, AndroidAaptVersion.AAPT); MergedAndroidAssets merged = assertMerge(ruleContext, parsed, deps); @@ -109,13 +151,56 @@ public class AndroidAssetsTest extends ResourceTestBase { .containsExactlyElementsIn( Iterables.concat(deps.getTransitiveParsedAssets(), deps.getDirectParsedAssets())) .inOrder(); + + // There should be no compiled symbols + assertThat(info.getCompiledSymbols()).isEmpty(); + } + + @Test + public void testMergeAapt2() throws Exception { + mockAndroidSdkWithAapt2(); + useConfiguration("--android_sdk=//sdk:sdk"); + + RuleContext ruleContext = getRuleContext(); + ParsedAndroidAssets parsed = + getLocalAssets().parse(AndroidDataContext.forNative(ruleContext), AndroidAaptVersion.AAPT2); + AssetDependencies deps = + makeDeps(ruleContext, /* neverlink = */ false, AndroidAaptVersion.AAPT2); + + MergedAndroidAssets merged = assertMerge(ruleContext, parsed, deps); + + AndroidAssetsInfo info = merged.toProvider(); + assertThat(info.getLabel()).isEqualTo(merged.getLabel()); + + // The provider should have transitive and direct deps + assertThat(info.getAssets()) + .containsExactlyElementsIn(Iterables.concat(parsed.getAssets(), deps.getTransitiveAssets())) + .inOrder(); + assertThat(info.getSymbols()) + .containsExactlyElementsIn( + Iterables.concat(ImmutableList.of(parsed.getSymbols()), deps.getTransitiveSymbols())) + .inOrder(); + assertThat(info.getCompiledSymbols()) + .containsExactlyElementsIn( + Iterables.concat( + ImmutableList.of(parsed.getCompiledSymbols()), + deps.getTransitiveCompiledSymbols())); + assertThat(info.getDirectParsedAssets()).containsExactly(parsed).inOrder(); + assertThat(info.getTransitiveParsedAssets()) + .containsExactlyElementsIn( + Iterables.concat(deps.getTransitiveParsedAssets(), deps.getDirectParsedAssets())) + .inOrder(); } - private AssetDependencies makeDeps(RuleContext ruleContext, boolean neverlink) { - ParsedAndroidAssets firstDirect = getDependencyAssets(ruleContext, "first_direct"); - ParsedAndroidAssets secondDirect = getDependencyAssets(ruleContext, "second_direct"); - ParsedAndroidAssets firstTransitive = getDependencyAssets(ruleContext, "first_transitive"); - ParsedAndroidAssets secondTransitive = getDependencyAssets(ruleContext, "second_transitive"); + private AssetDependencies makeDeps( + RuleContext ruleContext, boolean neverlink, AndroidAaptVersion aaptVersion) { + ParsedAndroidAssets firstDirect = getDependencyAssets(ruleContext, "first_direct", aaptVersion); + ParsedAndroidAssets secondDirect = + getDependencyAssets(ruleContext, "second_direct", aaptVersion); + ParsedAndroidAssets firstTransitive = + getDependencyAssets(ruleContext, "first_transitive", aaptVersion); + ParsedAndroidAssets secondTransitive = + getDependencyAssets(ruleContext, "second_transitive", aaptVersion); return AssetDependencies.of( neverlink, @@ -134,7 +219,16 @@ public class AndroidAssetsTest extends ResourceTestBase { firstDirect.getSymbols(), secondDirect.getSymbols(), firstTransitive.getSymbols(), - secondTransitive.getSymbols()))); + secondTransitive.getSymbols())), + aaptVersion == AndroidAaptVersion.AAPT2 + ? NestedSetBuilder.wrap( + Order.NAIVE_LINK_ORDER, + ImmutableList.of( + firstDirect.getCompiledSymbols(), + secondDirect.getCompiledSymbols(), + firstTransitive.getCompiledSymbols(), + secondTransitive.getCompiledSymbols())) + : NestedSetBuilder.emptySet(Order.NAIVE_LINK_ORDER)); } private MergedAndroidAssets assertMerge( @@ -167,13 +261,17 @@ public class AndroidAssetsTest extends ResourceTestBase { "asset_dir"); } - private ParsedAndroidAssets getDependencyAssets(RuleContext ruleContext, String depName) { + private ParsedAndroidAssets getDependencyAssets( + RuleContext ruleContext, String depName, AndroidAaptVersion aaptVersion) { return ParsedAndroidAssets.of( new AndroidAssets( ImmutableList.of(getResource(depName + "_asset_1"), getResource(depName + "_asset_2")), ImmutableList.of(PathFragment.create(depName)), depName), getResource("symbols_for_" + depName), + aaptVersion == AndroidAaptVersion.AAPT2 + ? getResource("compiled_symbols_for_" + depName) + : null, ruleContext.getLabel()); } diff --git a/src/test/java/com/google/devtools/build/lib/rules/android/AndroidResourcesTest.java b/src/test/java/com/google/devtools/build/lib/rules/android/AndroidResourcesTest.java index 6b9ecb256f..758eb194f1 100644 --- a/src/test/java/com/google/devtools/build/lib/rules/android/AndroidResourcesTest.java +++ b/src/test/java/com/google/devtools/build/lib/rules/android/AndroidResourcesTest.java @@ -447,7 +447,10 @@ public class AndroidResourcesTest extends ResourceTestBase { ProcessedAndroidData.of( makeParsedResources(ruleContext), AndroidAssets.from(ruleContext) - .process(AndroidDataContext.forNative(ruleContext), AssetDependencies.empty()), + .process( + AndroidDataContext.forNative(ruleContext), + AssetDependencies.empty(), + AndroidAaptVersion.chooseTargetAaptVersion(ruleContext)), manifest, rTxt, ruleContext.getImplicitOutputArtifact(AndroidRuleClasses.ANDROID_JAVA_SOURCE_JAR), diff --git a/src/tools/android/java/com/google/devtools/build/android/Aapt2ResourcePackagingAction.java b/src/tools/android/java/com/google/devtools/build/android/Aapt2ResourcePackagingAction.java index b903ebec66..9179a77fe9 100644 --- a/src/tools/android/java/com/google/devtools/build/android/Aapt2ResourcePackagingAction.java +++ b/src/tools/android/java/com/google/devtools/build/android/Aapt2ResourcePackagingAction.java @@ -97,8 +97,14 @@ public class Aapt2ResourcePackagingAction { AndroidResourceMerger.mergeData( ParsedAndroidData.from(options.primaryData), options.primaryData.getManifest(), - options.directData, - options.transitiveData, + ImmutableList.<SerializedAndroidData>builder() + .addAll(options.directData) + .addAll(options.directAssets) + .build(), + ImmutableList.<SerializedAndroidData>builder() + .addAll(options.transitiveData) + .addAll(options.transitiveAssets) + .build(), mergedResources, mergedAssets, null /* cruncher. Aapt2 automatically chooses to crunch or not. */, @@ -157,10 +163,14 @@ public class Aapt2ResourcePackagingAction { .map(DependencyAndroidData::getCompiledSymbols) .collect(toList()); - List<Path> assetDirs = - concat(options.transitiveData.stream(), options.directData.stream()) - .flatMap(dep -> dep.assetDirs.stream()) - .collect(toList()); + List<Path> assetDirs = + concat( + options.transitiveData.stream(), + options.transitiveAssets.stream(), + options.directData.stream(), + options.directAssets.stream()) + .flatMap(dep -> dep.assetDirs.stream()) + .collect(toList()); assetDirs.addAll(options.primaryData.assetDirs); final PackagedResources packagedResources = |