From e5a9f7646ec62f7d538e001d355a50d12d6af66e Mon Sep 17 00:00:00 2001 From: Googler Date: Fri, 22 Dec 2017 08:23:41 -0800 Subject: Remove dead android_resources code RELNOTES: none PiperOrigin-RevId: 179928735 --- .../build/lib/rules/android/AarImport.java | 2 +- .../lib/rules/android/AndroidAaptActionHelper.java | 312 --------------------- .../build/lib/rules/android/AndroidBinary.java | 110 ++------ .../rules/android/AndroidBinaryMobileInstall.java | 80 ++---- .../build/lib/rules/android/AndroidCommon.java | 47 +--- .../build/lib/rules/android/AndroidLibrary.java | 108 +------ .../lib/rules/android/AndroidLocalTestBase.java | 13 +- .../rules/android/AndroidResourcesProvider.java | 14 +- .../lib/rules/android/ApplicationManifest.java | 274 ++---------------- .../lib/rules/android/LocalResourceContainer.java | 17 +- .../build/lib/rules/android/ResourceApk.java | 9 +- .../build/lib/rules/android/ResourceContainer.java | 18 -- .../lib/rules/android/ResourceDependencies.java | 205 ++------------ .../lib/rules/android/ResourceFilterFactory.java | 4 - 14 files changed, 114 insertions(+), 1099 deletions(-) delete mode 100644 src/main/java/com/google/devtools/build/lib/rules/android/AndroidAaptActionHelper.java 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 822bb4fa57..2d696d28e4 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 @@ -165,7 +165,7 @@ public class AarImport implements RuleConfiguredTargetFactory { .addProvider(RunfilesProvider.class, RunfilesProvider.EMPTY) .addProvider( AndroidResourcesProvider.class, - resourceApk.toResourceProvider(ruleContext.getLabel(), /* isResourcesOnly = */ false)) + resourceApk.toResourceProvider(ruleContext.getLabel())) .addProvider( NativeLibsZipsProvider.class, new NativeLibsZipsProvider( diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidAaptActionHelper.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidAaptActionHelper.java deleted file mode 100644 index 5cfe931eae..0000000000 --- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidAaptActionHelper.java +++ /dev/null @@ -1,312 +0,0 @@ -// Copyright 2015 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.common.annotations.VisibleForTesting; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Iterables; -import com.google.devtools.build.lib.actions.Artifact; -import com.google.devtools.build.lib.actions.ParameterFile.ParameterFileType; -import com.google.devtools.build.lib.analysis.RuleContext; -import com.google.devtools.build.lib.analysis.actions.CommandLine; -import com.google.devtools.build.lib.analysis.actions.ParamFileInfo; -import com.google.devtools.build.lib.analysis.actions.SpawnAction; -import com.google.devtools.build.lib.analysis.actions.SpawnAction.Builder; -import com.google.devtools.build.lib.analysis.config.CompilationMode; -import com.google.devtools.build.lib.analysis.configuredtargets.RuleConfiguredTarget.Mode; -import com.google.devtools.build.lib.rules.android.ResourceContainer.ResourceType; -import com.google.devtools.build.lib.vfs.PathFragment; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.LinkedHashSet; -import java.util.List; -import javax.annotation.Nullable; - -/** Helper class to generate Android aapt actions. */ -public final class AndroidAaptActionHelper { - private final RuleContext ruleContext; - private final Artifact manifest; - private final Collection inputs = new LinkedHashSet<>(); - private final Iterable resourceContainers; - - /** - * Constructs an instance of AndroidAaptActionHelper. - * - * @param ruleContext RuleContext for which the aapt actions will be generated. - * @param manifest Artifact representing the AndroidManifest.xml that will be used to package - * resources. - * @param resourceContainers The transitive closure of the ResourceContainers. - */ - public AndroidAaptActionHelper( - RuleContext ruleContext, Artifact manifest, Iterable resourceContainers) { - this.ruleContext = ruleContext; - this.manifest = manifest; - this.resourceContainers = resourceContainers; - } - - /** Returns the artifacts needed as inputs to process the resources/assets. */ - private Iterable getInputs() { - if (inputs.isEmpty()) { - inputs.add(AndroidSdkProvider.fromRuleContext(ruleContext).getAndroidJar()); - inputs.add(manifest); - Iterables.addAll( - inputs, - Iterables.concat( - Iterables.transform(resourceContainers, ResourceContainer::getArtifacts))); - } - return inputs; - } - - /** - * Creates an Action that will invoke aapt to generate symbols java sources from the resources and - * pack them into a srcjar. - * - * @param javaSourcesJar Artifact to be generated by executing the action created by this method. - * @param rTxt R.txt artifact to be generated by the aapt invocation. - * @param javaPackage The package for which resources will be generated - * @param inlineConstants whether or not constants in Java generated sources should be inlined by - * the compiler. - */ - public void createGenerateResourceSymbolsAction( - Artifact javaSourcesJar, Artifact rTxt, String javaPackage, boolean inlineConstants) { - // java path from the provided package for the resources - PathFragment javaPath = PathFragment.create(javaPackage.replace('.', '/')); - - PathFragment javaResourcesRoot = - javaSourcesJar - .getRoot() - .getExecPath() - .getRelative(ruleContext.getUniqueDirectory("_java_resources")); - - String javaResources = javaResourcesRoot.getRelative(javaPath).getPathString(); - - List args = new ArrayList<>(); - args.add(javaSourcesJar.getExecPathString()); - args.add(javaResourcesRoot.getPathString()); - args.add(javaResources); - - args.addAll( - createAaptCommand( - "javasrcs", - javaSourcesJar, - rTxt, - inlineConstants, - "-J", - javaResources, - "--custom-package", - javaPackage, - "--rename-manifest-package", - javaPackage)); - final Builder builder = - new SpawnAction.Builder() - .addInputs(getInputs()) - .addTool(AndroidSdkProvider.fromRuleContext(ruleContext).getAapt()) - .setExecutable( - ruleContext.getExecutablePrerequisite("$android_aapt_java_generator", Mode.HOST)) - .addOutput(javaSourcesJar) - .addCommandLine( - CommandLine.of(args), ParamFileInfo.builder(ParameterFileType.UNQUOTED).build()) - .setProgressMessage("Generating Java resources") - .setMnemonic("AaptJavaGenerator"); - if (rTxt != null) { - builder.addOutput(rTxt); - } - ruleContext.registerAction(builder.build(ruleContext)); - } - - /** - * Creates an Action that will invoke aapt to package the android resources into an apk file. - * - * @param apk Packed resources artifact to be generated by the aapt invocation. - */ - public void createGenerateApkAction( - Artifact apk, String renameManifestPackage, List aaptOpts, List densities) { - List args; - - if (renameManifestPackage == null) { - args = createAaptCommand("apk", apk, null, true, "-F", apk.getExecPathString()); - } else { - args = - createAaptCommand( - "apk", - apk, - null, - true, - "-F", - apk.getExecPathString(), - "--rename-manifest-package", - renameManifestPackage); - } - - if (!densities.isEmpty()) { - args.add(0, "start_densities"); - args.add(1, "end_densities"); - args.addAll(1, densities); - } - - args.addAll(aaptOpts); - - ruleContext.registerAction( - new SpawnAction.Builder() - .addInputs(getInputs()) - .addTool(AndroidSdkProvider.fromRuleContext(ruleContext).getAapt()) - .addOutput(apk) - .setExecutable( - ruleContext.getExecutablePrerequisite("$android_aapt_apk_generator", Mode.HOST)) - .addCommandLine( - CommandLine.of(args), ParamFileInfo.builder(ParameterFileType.UNQUOTED).build()) - .setProgressMessage("Generating apk resources") - .setMnemonic("AaptResourceApk") - .build(ruleContext)); - } - - private List createAaptCommand( - String actionKind, - Artifact output, - Artifact rTxtOutput, - boolean inlineConstants, - String... outputArgs) { - return createAaptCommand( - actionKind, output, rTxtOutput, inlineConstants, Arrays.asList(outputArgs)); - } - - private List createAaptCommand( - String actionKind, - Artifact output, - Artifact rTxtOutput, - boolean inlineConstants, - Collection outputArgs) { - List args = new ArrayList<>(); - args.addAll(getArgs(output, actionKind, ResourceType.RESOURCES)); - args.addAll(getArgs(output, actionKind, ResourceType.ASSETS)); - args.add( - AndroidSdkProvider.fromRuleContext(ruleContext) - .getAapt() - .getExecutable() - .getExecPathString()); - args.add("package"); - args.addAll(outputArgs); - // Allow overlay in case the same resource appears in more than one target, - // giving precedence to the order in which they are found. This is needed - // in order to support android library projects. - args.add("--auto-add-overlay"); - if (rTxtOutput != null) { - args.add("--output-text-symbols"); - args.add(rTxtOutput.getExecPath().getParentDirectory().getPathString()); - } - if (!inlineConstants) { - args.add("--non-constant-id"); - } - if (ruleContext.getConfiguration().getCompilationMode() != CompilationMode.OPT) { - args.add("--debug-mode"); - } - args.add("-I"); - args.add(AndroidSdkProvider.fromRuleContext(ruleContext).getAndroidJar().getExecPathString()); - args.add("-M"); - args.add(manifest.getExecPathString()); - args.addAll(getResourcesDirArg(output, actionKind, "-S", ResourceType.RESOURCES)); - args.addAll(getResourcesDirArg(output, actionKind, "-A", ResourceType.ASSETS)); - return args; - } - - @VisibleForTesting - public List getArgs(Artifact output, String actionKind, ResourceType resourceType) { - PathFragment outputPath = outputPath(output, actionKind, resourceType); - List args = new ArrayList<>(); - args.add("start_" + resourceType.getAttribute()); - args.add(outputPath.getPathString()); - // First make sure path elements are unique - Collection paths = new LinkedHashSet<>(); - for (ResourceContainer container : resourceContainers) { - for (Artifact artifact : container.getArtifacts(resourceType)) { - paths.add(artifact.getExecPathString()); - } - } - // Than populate the command line - for (String path : paths) { - args.add(path); - args.add(path); - } - args.add("end_" + resourceType.getAttribute()); - - // if there is at least one artifact - if (args.size() > 3) { - return ImmutableList.copyOf(args); - } else { - return ImmutableList.of(); - } - } - - /** Returns optional part of the aapt command line: optionName output_path. */ - @VisibleForTesting - public List getResourcesDirArg( - Artifact output, String actionKind, String resourceArg, ResourceType resourceType) { - PathFragment outputPath = outputPath(output, actionKind, resourceType); - List dirArgs = new ArrayList<>(); - Collection paths = new LinkedHashSet<>(); - // First make sure roots are unique - for (ResourceContainer container : resourceContainers) { - for (PathFragment root : container.getRoots(resourceType)) { - paths.add(outputPath.getRelative(root).getPathString()); - } - } - // Than populate the command line - for (String path : paths) { - dirArgs.add(resourceArg); - dirArgs.add(path); - } - - return ImmutableList.copyOf(dirArgs); - } - - /** Returns a resourceType specific unique output location for the given action kind. */ - private PathFragment outputPath(Artifact output, String actionKind, ResourceType resourceType) { - return output - .getRoot() - .getExecPath() - .getRelative( - ruleContext.getUniqueDirectory("_" + resourceType.getAttribute() + "_" + actionKind)); - } - - public void createGenerateProguardAction( - Artifact outputSpec, @Nullable Artifact outputMainDexSpec) { - ImmutableList.Builder outputs = ImmutableList.builder(); - ImmutableList.Builder aaptArgs = ImmutableList.builder(); - - outputs.add(outputSpec); - aaptArgs.add("-G").add(outputSpec.getExecPathString()); - - if (outputMainDexSpec != null) { - aaptArgs.add("-D").add(outputMainDexSpec.getExecPathString()); - outputs.add(outputMainDexSpec); - } - - List aaptCommand = - createAaptCommand("proguard", outputSpec, null, true, aaptArgs.build()); - ruleContext.registerAction( - new SpawnAction.Builder() - .addInputs(getInputs()) - .addTool(AndroidSdkProvider.fromRuleContext(ruleContext).getAapt()) - .addOutputs(outputs.build()) - .setExecutable( - ruleContext.getExecutablePrerequisite("$android_aapt_apk_generator", Mode.HOST)) - .addCommandLine( - CommandLine.of(aaptCommand), - ParamFileInfo.builder(ParameterFileType.UNQUOTED).build()) - .setProgressMessage("Generating Proguard configuration for resources") - .setMnemonic("AaptProguardConfiguration") - .build(ruleContext)); - } -} 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 60b9ec2daa..4c3d74c914 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 @@ -107,9 +107,7 @@ public abstract class AndroidBinary implements RuleConfiguredTargetFactory { AndroidCommon androidCommon = new AndroidCommon(javaCommon, /* asNeverLink= */ true, /* exportDeps= */ true); ResourceDependencies resourceDeps = - LocalResourceContainer.definesAndroidResources(ruleContext.attributes()) - ? ResourceDependencies.fromRuleDeps(ruleContext, /* neverlink= */ false) - : ResourceDependencies.fromRuleResourceAndDeps(ruleContext, /* neverlink= */ false); + ResourceDependencies.fromRuleDeps(ruleContext, /* neverlink= */ false); RuleConfiguredTargetBuilder builder = init( ruleContext, @@ -151,7 +149,6 @@ public abstract class AndroidBinary implements RuleConfiguredTargetFactory { "proguard_apply_mapping", "'proguard_apply_dictionary' can only be used when 'proguard_specs' is also set"); } - AndroidCommon.validateResourcesAttribute(ruleContext); } private static RuleConfiguredTargetBuilder init( @@ -175,16 +172,11 @@ public abstract class AndroidBinary implements RuleConfiguredTargetFactory { boolean shrinkResources = shouldShrinkResources(ruleContext); - // TODO(bazel-team): Resolve all the different cases of resource handling so this conditional - // can go away: recompile from android_resources, and recompile from android_binary attributes. - ApplicationManifest applicationManifest; - ResourceApk resourceApk; - if (LocalResourceContainer.definesAndroidResources(ruleContext.attributes())) { - // Retrieve and compile the resources defined on the android_binary rule. - LocalResourceContainer.validateRuleContext(ruleContext); - ApplicationManifest ruleManifest = androidSemantics.getManifestForRule(ruleContext); + // Retrieve and compile the resources defined on the android_binary rule. + LocalResourceContainer.validateRuleContext(ruleContext); - applicationManifest = ruleManifest.mergeWith(ruleContext, resourceDeps); + ApplicationManifest applicationManifest = + androidSemantics.getManifestForRule(ruleContext).mergeWith(ruleContext, resourceDeps); Artifact featureOfArtifact = ruleContext.attributes().isAttributeValueExplicitlySpecified("feature_of") @@ -197,64 +189,25 @@ public abstract class AndroidBinary implements RuleConfiguredTargetFactory { .getApk() : null; - resourceApk = - applicationManifest.packBinaryWithDataAndResources( - ruleContext, - ruleContext.getImplicitOutputArtifact(AndroidRuleClasses.ANDROID_RESOURCES_APK), - resourceDeps, - ruleContext.getImplicitOutputArtifact(AndroidRuleClasses.ANDROID_R_TXT), - ResourceFilterFactory.fromRuleContext(ruleContext), - ruleContext.getExpander().withDataLocations().tokenized("nocompress_extensions"), - ruleContext.attributes().get("crunch_png", Type.BOOLEAN), - ProguardHelper.getProguardConfigArtifact(ruleContext, ""), - createMainDexProguardSpec(ruleContext), - shouldShrinkResourceCycles(ruleContext, shrinkResources), - ruleContext.getImplicitOutputArtifact(AndroidRuleClasses.ANDROID_PROCESSED_MANIFEST), - ruleContext.getImplicitOutputArtifact(AndroidRuleClasses.ANDROID_RESOURCES_ZIP), - DataBinding.isEnabled(ruleContext) - ? DataBinding.getLayoutInfoFile(ruleContext) - : null, - featureOfArtifact, - featureAfterArtifact); + ResourceApk resourceApk = + applicationManifest.packBinaryWithDataAndResources( + ruleContext, + ruleContext.getImplicitOutputArtifact(AndroidRuleClasses.ANDROID_RESOURCES_APK), + resourceDeps, + ruleContext.getImplicitOutputArtifact(AndroidRuleClasses.ANDROID_R_TXT), + ResourceFilterFactory.fromRuleContext(ruleContext), + ruleContext.getExpander().withDataLocations().tokenized("nocompress_extensions"), + ruleContext.attributes().get("crunch_png", Type.BOOLEAN), + ProguardHelper.getProguardConfigArtifact(ruleContext, ""), + createMainDexProguardSpec(ruleContext), + shouldShrinkResourceCycles(ruleContext, shrinkResources), + ruleContext.getImplicitOutputArtifact(AndroidRuleClasses.ANDROID_PROCESSED_MANIFEST), + ruleContext.getImplicitOutputArtifact(AndroidRuleClasses.ANDROID_RESOURCES_ZIP), + DataBinding.isEnabled(ruleContext) ? DataBinding.getLayoutInfoFile(ruleContext) : null, + featureOfArtifact, + featureAfterArtifact); ruleContext.assertNoErrors(); - } else { - - if (!ruleContext.attributes().get("crunch_png", Type.BOOLEAN)) { - ruleContext.throwWithRuleError( - "Setting crunch_png = 0 is not supported for android_binary" - + " rules which depend on android_resources rules."); - } - - // Retrieve the resources from the resources attribute on the android_binary rule - // and recompile them if necessary. - ApplicationManifest resourcesManifest = ApplicationManifest.fromResourcesRule(ruleContext); - if (resourcesManifest == null) { - throw new RuleErrorException(); - } - applicationManifest = resourcesManifest.mergeWith(ruleContext, resourceDeps); - - // Always recompiling resources causes AndroidTest to fail in certain circumstances. - if (shouldRegenerate(ruleContext, resourceDeps)) { - resourceApk = - applicationManifest.packWithResources( - ruleContext.getImplicitOutputArtifact(AndroidRuleClasses.ANDROID_RESOURCES_APK), - ruleContext, - resourceDeps, - true, /* createSource */ - ProguardHelper.getProguardConfigArtifact(ruleContext, ""), - createMainDexProguardSpec(ruleContext)); - ruleContext.assertNoErrors(); - } else { - resourceApk = - applicationManifest.useCurrentResources( - ruleContext, - ProguardHelper.getProguardConfigArtifact(ruleContext, ""), - createMainDexProguardSpec(ruleContext)); - ruleContext.assertNoErrors(); - } - } - // Remove the library resource JARs from the binary's runtime classpath. // Resource classes from android_library dependencies are replaced by the binary's resource // class. We remove them only at the top level so that resources included by a library that is @@ -521,7 +474,6 @@ public abstract class AndroidBinary implements RuleConfiguredTargetFactory { zipAlignedApk, apksUnderTest, nativeLibs, - /* isResourcesOnly = */ false, androidCommon.isNeverLink() ); @@ -1653,24 +1605,6 @@ public abstract class AndroidBinary implements RuleConfiguredTargetFactory { return ProguardHelper.getProguardConfigArtifact(ruleContext, "main_dex"); } - /** - * Tests if the resources need to be regenerated. - * - *

The resources should be regenerated (using aapt) if any of the following are true: - * - *

    - *
  • There is more than one resource container - *
  • There are resource filters. - *
  • There are extensions that should be compressed. - *
- */ - public static boolean shouldRegenerate( - RuleContext ruleContext, ResourceDependencies resourceDeps) { - return Iterables.size(resourceDeps.getResourceContainers()) > 1 - || ResourceFilterFactory.hasFilters(ruleContext) - || ruleContext.attributes().isAttributeValueExplicitlySpecified("nocompress_extensions"); - } - /** Returns the multidex mode to apply to this target. */ public static MultidexMode getMultidexMode(RuleContext ruleContext) { if (ruleContext.getRule().isAttrDefined("multidex", Type.STRING)) { diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinaryMobileInstall.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinaryMobileInstall.java index cd60236ef2..37ae94c644 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinaryMobileInstall.java +++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinaryMobileInstall.java @@ -63,62 +63,30 @@ public final class AndroidBinaryMobileInstall { ResourceDependencies resourceDeps) throws RuleErrorException, InterruptedException { - ResourceApk incrementalResourceApk; - ResourceApk splitResourceApk; - - if (LocalResourceContainer.definesAndroidResources(ruleContext.attributes())) { - incrementalResourceApk = - applicationManifest - .addMobileInstallStubApplication(ruleContext) - .packIncrementalBinaryWithDataAndResources( - ruleContext, - ruleContext.getImplicitOutputArtifact( - AndroidRuleClasses.ANDROID_INCREMENTAL_RESOURCES_APK), - resourceDeps, - ruleContext.getExpander().withDataLocations().tokenized("nocompress_extensions"), - ruleContext.attributes().get("crunch_png", Type.BOOLEAN), - ProguardHelper.getProguardConfigArtifact(ruleContext, "incremental")); - ruleContext.assertNoErrors(); - - splitResourceApk = - applicationManifest - .createSplitManifest(ruleContext, "android_resources", false) - .packIncrementalBinaryWithDataAndResources( - ruleContext, - getMobileInstallArtifact(ruleContext, "android_resources.ap_"), - resourceDeps, - ruleContext.getExpander().withDataLocations().tokenized("nocompress_extensions"), - ruleContext.attributes().get("crunch_png", Type.BOOLEAN), - ProguardHelper.getProguardConfigArtifact(ruleContext, "incremental_split")); - ruleContext.assertNoErrors(); - - } else { - - incrementalResourceApk = - applicationManifest - .addMobileInstallStubApplication(ruleContext) - .packWithResources( - ruleContext.getImplicitOutputArtifact( - AndroidRuleClasses.ANDROID_INCREMENTAL_RESOURCES_APK), - ruleContext, - resourceDeps, - false, /* createSource */ - ProguardHelper.getProguardConfigArtifact(ruleContext, "incremental"), - null /* mainDexProguardConfig */); - ruleContext.assertNoErrors(); - - splitResourceApk = - applicationManifest - .createSplitManifest(ruleContext, "android_resources", false) - .packWithResources( - getMobileInstallArtifact(ruleContext, "android_resources.ap_"), - ruleContext, - resourceDeps, - false, /* createSource */ - ProguardHelper.getProguardConfigArtifact(ruleContext, "incremental_split"), - null /* mainDexProguardConfig */); - ruleContext.assertNoErrors(); - } + ResourceApk incrementalResourceApk = + applicationManifest + .addMobileInstallStubApplication(ruleContext) + .packIncrementalBinaryWithDataAndResources( + ruleContext, + ruleContext.getImplicitOutputArtifact( + AndroidRuleClasses.ANDROID_INCREMENTAL_RESOURCES_APK), + resourceDeps, + ruleContext.getExpander().withDataLocations().tokenized("nocompress_extensions"), + ruleContext.attributes().get("crunch_png", Type.BOOLEAN), + ProguardHelper.getProguardConfigArtifact(ruleContext, "incremental")); + ruleContext.assertNoErrors(); + + ResourceApk splitResourceApk = + applicationManifest + .createSplitManifest(ruleContext, "android_resources", false) + .packIncrementalBinaryWithDataAndResources( + ruleContext, + getMobileInstallArtifact(ruleContext, "android_resources.ap_"), + resourceDeps, + ruleContext.getExpander().withDataLocations().tokenized("nocompress_extensions"), + ruleContext.attributes().get("crunch_png", Type.BOOLEAN), + ProguardHelper.getProguardConfigArtifact(ruleContext, "incremental_split")); + ruleContext.assertNoErrors(); return new MobileInstallResourceApks(incrementalResourceApk, splitResourceApk); } diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidCommon.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidCommon.java index 8470dffe18..1f1f26ff93 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidCommon.java +++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidCommon.java @@ -35,7 +35,6 @@ import com.google.devtools.build.lib.analysis.actions.SpawnAction; import com.google.devtools.build.lib.analysis.configuredtargets.RuleConfiguredTarget; import com.google.devtools.build.lib.analysis.configuredtargets.RuleConfiguredTarget.Mode; import com.google.devtools.build.lib.analysis.test.InstrumentedFilesCollector.InstrumentationSpec; -import com.google.devtools.build.lib.analysis.whitelisting.Whitelist; import com.google.devtools.build.lib.collect.IterablesChain; import com.google.devtools.build.lib.collect.nestedset.NestedSet; import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; @@ -118,8 +117,6 @@ public class AndroidCommon { return builder.build(); } - public static final String RESOURCES_WHITELIST_NAME = "android_resources"; - private final RuleContext ruleContext; private final JavaCommon javaCommon; private final boolean asNeverLink; @@ -272,8 +269,7 @@ public class AndroidCommon { ideInfoProviderBuilder.setApk(zipAlignedApk); } - // If the rule defines resources, put those in the IDE info. Otherwise, proxy the data coming - // from the android_resources rule in its direct dependencies, if such a thing exists. + // If the rule defines resources, put those in the IDE info. if (LocalResourceContainer.definesAndroidResources(ruleContext.attributes())) { ideInfoProviderBuilder .setDefinesAndroidResources(true) @@ -790,7 +786,6 @@ public class AndroidCommon { Artifact zipAlignedApk, Iterable apksUnderTest, NativeLibs nativeLibs, - boolean isResourcesOnly, boolean isNeverlink) { idlHelper.addTransitiveInfoProviders(builder, classJar, manifestProtoOutput); @@ -843,7 +838,7 @@ public class AndroidCommon { .addProvider(RunfilesProvider.class, RunfilesProvider.simple(getRunfiles())) .addProvider( AndroidResourcesProvider.class, - resourceApk.toResourceProvider(ruleContext.getLabel(), isResourcesOnly)) + resourceApk.toResourceProvider(ruleContext.getLabel())) .addProvider( AndroidIdeInfoProvider.class, createAndroidIdeInfoProvider( @@ -884,34 +879,6 @@ public class AndroidCommon { ruleContext.attributes().get(ResourceType.ASSETS.getAttribute() + "_dir", Type.STRING)); } - public static AndroidResourcesProvider getAndroidResources(RuleContext ruleContext) { - if (!ruleContext.attributes().has("resources", BuildType.LABEL)) { - return null; - } - TransitiveInfoCollection prerequisite = ruleContext.getPrerequisite("resources", Mode.TARGET); - if (prerequisite == null) { - return null; - } - - AndroidResourcesProvider provider = prerequisite.getProvider(AndroidResourcesProvider.class); - - if (!provider.getIsResourcesOnly()) { - ruleContext.attributeError( - "resources", - "android_library target " - + prerequisite.getLabel() - + " cannot be used in the 'resources' attribute as it specifies information (probably" - + " 'srcs' or 'deps') not directly related to android_resources. Consider moving this" - + " target from 'resources' to 'deps'."); - return null; - } - - ruleContext.ruleWarning( - "The use of the android_resources rule and the resources attribute is deprecated. " - + "Please use the resource_files, assets, and manifest attributes of android_library."); - return provider; - } - /** * Collects Java compilation arguments for this target. * @@ -1073,16 +1040,6 @@ public class AndroidCommon { return supportApks.build(); } - public static void validateResourcesAttribute(RuleContext ruleContext) throws RuleErrorException { - if (ruleContext.attributes().isAttributeValueExplicitlySpecified("resources") - && !ruleContext.getFragment(AndroidConfiguration.class).allowResourcesAttr() - && !Whitelist.isAvailable(ruleContext, RESOURCES_WHITELIST_NAME)) { - ruleContext.throwWithAttributeError( - "resources", - "The resources attribute has been removed. Please use resource_files instead."); - } - } - /** * Used for instrumentation tests. Filter out classes from the instrumentation JAR that are also * present in the target JAR. During an instrumentation test, ART will load jars from both APKs 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 e92828ead0..ca85bbb116 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 @@ -14,8 +14,6 @@ package com.google.devtools.build.lib.rules.android; import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Iterables; import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.analysis.ConfiguredTarget; import com.google.devtools.build.lib.analysis.OutputGroupInfo; @@ -30,7 +28,6 @@ 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.AndroidLibraryAarProvider.Aar; -import com.google.devtools.build.lib.rules.android.ResourceContainer.ResourceType; import com.google.devtools.build.lib.rules.java.JavaCommon; import com.google.devtools.build.lib.rules.java.JavaPluginInfoProvider; import com.google.devtools.build.lib.rules.java.JavaSemantics; @@ -50,14 +47,6 @@ public abstract class AndroidLibrary implements RuleConfiguredTargetFactory { /** Checks expected rule invariants, throws rule errors if anything is set wrong. */ private static void validateRuleContext(RuleContext ruleContext) throws InterruptedException, RuleErrorException { - if (ruleContext.attributes().isAttributeValueExplicitlySpecified("resources") - && DataBinding.isEnabled(ruleContext)) { - ruleContext.throwWithRuleError( - "Data binding doesn't work with the \"resources\" attribute. " - + "Use \"resource_files\" instead."); - } - - AndroidCommon.validateResourcesAttribute(ruleContext); /** * TODO(b/14473160): Remove when deps are no longer implicitly exported. @@ -119,52 +108,6 @@ public abstract class AndroidLibrary implements RuleConfiguredTargetFactory { return !(hasManifest || hasInlineConsts || hasAssetsDir || hasExportsManifest); } - /** - * Attributes provided by android_library targets that provide information also supported by - * android_resources targets. - * - *

As part of migrating away from android_resources, we are allowing android_library targets to - * be used in the 'resources' attribute of android_binary, android_library, and android_test - * targets. However, android_library targets can specify information that cannot be propagated by - * the 'resources' attribute. By enumerating those attributes which can be propagated by - * 'resources' and having the {@link AndroidResourcesProvider} specify whether any other - * attributes are used, we can error out if an android_library is specified in a resources - * attribute despite having information incompatible with that output. - * - *

TODO(b/30307842): Remove this support once the resources attribute is completely removed. - * - *

With the exception of 'resource_files' and the generator attributes, these attributes are - * simply those provided by both android_library and android_resources. android_resources does - * provide the 'resources' attribute, but its behavior is like the android_library - * 'resource_files' attribute, not the android_library 'resources' attribute (which indicates a - * dependency on an android_resources target). The generator_* attributes are included when the - * rule is created by a macro. - */ - private static final ImmutableSet ATTRS_COMPATIBLE_WITH_ANDROID_RESOURCES = - ImmutableSet.of( - "assets", - "assets_dir", - "compatible_with", - "custom_package", - "deprecation", - "distribs", - "exports_manifest", - "features", - "inline_constants", - "javacopts", - "licenses", - "manifest", - "name", - "plugins", - "resource_files", - "restricted_to", - "tags", - "testonly", - "visibility", - "generator_name", - "generator_function", - "generator_location"); - @Override public ConfiguredTarget create(RuleContext ruleContext) throws InterruptedException, RuleErrorException { @@ -172,7 +115,6 @@ public abstract class AndroidLibrary implements RuleConfiguredTargetFactory { JavaSemantics javaSemantics = createJavaSemantics(); AndroidSemantics androidSemantics = createAndroidSemantics(); AndroidSdkProvider.verifyPresence(ruleContext); - checkResourceInlining(ruleContext); NestedSetBuilder transitiveAars = NestedSetBuilder.naiveLinkOrder(); NestedSetBuilder transitiveAarArtifacts = NestedSetBuilder.stableOrder(); collectTransitiveAars(ruleContext, transitiveAars, transitiveAarArtifacts); @@ -193,6 +135,13 @@ public abstract class AndroidLibrary implements RuleConfiguredTargetFactory { LocalResourceContainer.validateRuleContext(ruleContext); } + // TODO(b/69668042): Always correctly apply neverlinking for resources + boolean isNeverLink = + JavaCommon.isNeverLink(ruleContext) + && (definesLocalResources + || ruleContext.getFragment(AndroidConfiguration.class).fixedResourceNeverlinking()); + ResourceDependencies resourceDeps = ResourceDependencies.fromRuleDeps(ruleContext, isNeverLink); + final ResourceApk resourceApk; if (definesLocalResources) { ApplicationManifest applicationManifest = @@ -202,7 +151,7 @@ public abstract class AndroidLibrary implements RuleConfiguredTargetFactory { resourceApk = applicationManifest.packLibraryWithDataAndResources( ruleContext, - ResourceDependencies.fromRuleDeps(ruleContext, JavaCommon.isNeverLink(ruleContext)), + resourceDeps, ruleContext.getImplicitOutputArtifact(AndroidRuleClasses.ANDROID_R_TXT), ruleContext.getImplicitOutputArtifact(AndroidRuleClasses.ANDROID_MERGED_SYMBOLS), ruleContext.getImplicitOutputArtifact(AndroidRuleClasses.ANDROID_PROCESSED_MANIFEST), @@ -214,12 +163,7 @@ public abstract class AndroidLibrary implements RuleConfiguredTargetFactory { return null; } } else { - resourceApk = - ResourceApk.fromTransitiveResources( - ResourceDependencies.fromRuleResourceAndDeps( - ruleContext, - ruleContext.getFragment(AndroidConfiguration.class).fixedResourceNeverlinking() - && JavaCommon.isNeverLink(ruleContext))); + resourceApk = ResourceApk.fromTransitiveResources(resourceDeps); } JavaTargetAttributes javaTargetAttributes = @@ -249,14 +193,7 @@ public abstract class AndroidLibrary implements RuleConfiguredTargetFactory { aar = Aar.create(aarOut, applicationManifest.getManifest()); addAarToProvider(aar, transitiveAars, transitiveAarArtifacts); - } else if (AndroidCommon.getAndroidResources(ruleContext) != null) { - primaryResources = - Iterables.getOnlyElement( - AndroidCommon.getAndroidResources(ruleContext).getDirectAndroidResources()); - aar = Aar.create(aarOut, primaryResources.getManifest()); - addAarToProvider(aar, transitiveAars, transitiveAarArtifacts); } else { - // there are no local resources and resources attribute was not specified either aar = null; ApplicationManifest applicationManifest = ApplicationManifest.generatedManifest(ruleContext) @@ -302,15 +239,6 @@ public abstract class AndroidLibrary implements RuleConfiguredTargetFactory { ruleContext.getFragment(AndroidConfiguration.class).throwOnResourceConflict()) .build(ruleContext); - boolean isResourcesOnly = true; - for (String attr : ruleContext.attributes().getAttributeNames()) { - if (ruleContext.attributes().isAttributeValueExplicitlySpecified(attr) - && !ATTRS_COMPATIBLE_WITH_ANDROID_RESOURCES.contains(attr)) { - isResourcesOnly = false; - break; - } - } - RuleConfiguredTargetBuilder builder = new RuleConfiguredTargetBuilder(ruleContext); androidCommon.addTransitiveInfoProviders( builder, @@ -320,7 +248,6 @@ public abstract class AndroidLibrary implements RuleConfiguredTargetFactory { null, ImmutableList.of(), NativeLibs.EMPTY, - isResourcesOnly, // TODO(elenairina): Use JavaCommon.isNeverlink(ruleContext) for consistency among rules. androidCommon.isNeverLink()); @@ -370,23 +297,6 @@ public abstract class AndroidLibrary implements RuleConfiguredTargetFactory { } } - private void checkResourceInlining(RuleContext ruleContext) { - AndroidResourcesProvider resources = AndroidCommon.getAndroidResources(ruleContext); - if (resources == null) { - return; - } - - ResourceContainer container = Iterables.getOnlyElement(resources.getDirectAndroidResources()); - - if (container.getConstantsInlined() - && !container.getArtifacts(ResourceType.RESOURCES).isEmpty()) { - ruleContext.ruleError( - "This android library has some resources assigned, so the target '" - + resources.getLabel() - + "' should have the attribute inline_constants set to 0"); - } - } - private void collectTransitiveAars( RuleContext ruleContext, NestedSetBuilder transitiveAars, diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLocalTestBase.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLocalTestBase.java index db26b18e65..ad084013fc 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLocalTestBase.java +++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLocalTestBase.java @@ -86,7 +86,8 @@ public abstract class AndroidLocalTestBase implements RuleConfiguredTargetFactor getJavaTargetAttributes(ruleContext, javaCommon); // Create the final merged manifest - ResourceDependencies resourceDependencies = getResourceDependencies(ruleContext); + ResourceDependencies resourceDependencies = + ResourceDependencies.fromRuleDeps(ruleContext, false /* neverlink */); ApplicationManifest applicationManifest = getApplicationManifest(ruleContext, androidSemantics, resourceDependencies); Artifact manifest = applicationManifest.getManifest(); @@ -390,16 +391,6 @@ public abstract class AndroidLocalTestBase implements RuleConfiguredTargetFactor return applicationManifest; } - /** - * Returns the transitive closure of resource dependencies, including those specified on the rule - * if present. - */ - private ResourceDependencies getResourceDependencies(RuleContext ruleContext) { - return LocalResourceContainer.definesAndroidResources(ruleContext.attributes()) - ? ResourceDependencies.fromRuleDeps(ruleContext, false /* neverlink */) - : ResourceDependencies.fromRuleResourceAndDeps(ruleContext, false /* neverlink */); - } - private static void setUpJavaCommon( JavaCommon common, JavaCompilationHelper helper, diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidResourcesProvider.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidResourcesProvider.java index 45539aef6a..09e48159a5 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidResourcesProvider.java +++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidResourcesProvider.java @@ -36,8 +36,7 @@ public abstract class AndroidResourcesProvider implements TransitiveInfoProvider NestedSet transitiveSymbolsBin, NestedSet transitiveCompiledSymbols, NestedSet transitiveStaticLib, - NestedSet transitiveRTxt, - boolean isResourcesOnly) { + NestedSet transitiveRTxt) { return new AutoValue_AndroidResourcesProvider( label, transitiveAndroidResources, @@ -49,8 +48,7 @@ public abstract class AndroidResourcesProvider implements TransitiveInfoProvider transitiveSymbolsBin, transitiveCompiledSymbols, transitiveStaticLib, - transitiveRTxt, - isResourcesOnly); + transitiveRTxt); } /** Returns the label that is associated with this piece of information. */ @@ -78,13 +76,5 @@ public abstract class AndroidResourcesProvider implements TransitiveInfoProvider public abstract NestedSet getTransitiveRTxt(); - /** - * Returns whether the targets contained within this provider only represent android resources or - * also contain other information. - * - *

TODO(b/30307842): Remove this once android_resources is fully removed. - */ - public abstract boolean getIsResourcesOnly(); - AndroidResourcesProvider() {} } diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/ApplicationManifest.java b/src/main/java/com/google/devtools/build/lib/rules/android/ApplicationManifest.java index 0cb02c5942..4594594220 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/android/ApplicationManifest.java +++ b/src/main/java/com/google/devtools/build/lib/rules/android/ApplicationManifest.java @@ -20,11 +20,8 @@ import com.google.common.base.Joiner; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSortedMap; -import com.google.common.collect.Iterables; -import com.google.common.collect.Lists; import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.analysis.RuleContext; -import com.google.devtools.build.lib.analysis.TransitiveInfoCollection; import com.google.devtools.build.lib.analysis.actions.CustomCommandLine; import com.google.devtools.build.lib.analysis.actions.FileWriteAction; import com.google.devtools.build.lib.analysis.actions.SpawnAction; @@ -35,7 +32,6 @@ import com.google.devtools.build.lib.packages.RuleClass.ConfiguredTargetFactory. import com.google.devtools.build.lib.rules.android.AndroidConfiguration.AndroidAaptVersion; import com.google.devtools.build.lib.rules.android.AndroidConfiguration.AndroidManifestMerger; import com.google.devtools.build.lib.rules.android.ResourceContainer.Builder.JavaPackageSource; -import com.google.devtools.build.lib.rules.android.ResourceContainer.ResourceType; import com.google.devtools.build.lib.syntax.Type; import com.google.devtools.build.lib.vfs.PathFragment; import java.util.List; @@ -46,17 +42,6 @@ import javax.annotation.Nullable; /** Represents a AndroidManifest, that may have been merged from dependencies. */ public final class ApplicationManifest { - public static ApplicationManifest fromResourcesRule(RuleContext ruleContext) - throws RuleErrorException { - final AndroidResourcesProvider resources = AndroidCommon.getAndroidResources(ruleContext); - if (resources == null) { - ruleContext.attributeError("manifest", "a resources or manifest attribute is mandatory."); - return null; - } - return fromExplicitManifest( - ruleContext, Iterables.getOnlyElement(resources.getDirectAndroidResources()).getManifest()); - } - public ApplicationManifest createSplitManifest( RuleContext ruleContext, String splitName, boolean hasCode) { // aapt insists that manifests be called AndroidManifest.xml, even though they have to be @@ -201,16 +186,6 @@ public final class ApplicationManifest { private static ImmutableMap getManifestValues(RuleContext context) { Map manifestValues = new TreeMap<>(); - // applicationId is set from manifest_values or android_resources.rename_manifest_package - // with descending priority. - AndroidResourcesProvider resourcesProvider = AndroidCommon.getAndroidResources(context); - if (resourcesProvider != null) { - ResourceContainer resourceContainer = - Iterables.getOnlyElement(resourcesProvider.getDirectAndroidResources()); - if (resourceContainer.getRenameManifestPackage() != null) { - manifestValues.put("applicationId", resourceContainer.getRenameManifestPackage()); - } - } if (context.attributes().isAttributeValueExplicitlySpecified("manifest_values")) { manifestValues.putAll(context.attributes().get("manifest_values", Type.STRING_DICT)); } @@ -349,19 +324,12 @@ public final class ApplicationManifest { ruleContext, "assets", AndroidCommon.getAssetDir(ruleContext), "local_resource_files"); ResourceContainer resourceContainer = - checkForInlinedResources( - ResourceContainer.builderFromRule(ruleContext) - .setAssetsAndResourcesFrom(data) - .setManifest(getManifest()) - .setApk(resourceApk) - .setRTxt(rTxt) - .build(), - resourceDeps - .getResourceContainers(), // TODO(bazel-team): Figure out if we really need to check - // the ENTIRE transitive closure, or just the direct dependencies. Given that each rule - // with resources would check for inline resources, we can rely on the previous rule to - // have checked its dependencies. - ruleContext); + ResourceContainer.builderFromRule(ruleContext) + .setAssetsAndResourcesFrom(data) + .setManifest(getManifest()) + .setApk(resourceApk) + .setRTxt(rTxt) + .build(); AndroidResourcesProcessorBuilder builder = new AndroidResourcesProcessorBuilder(ruleContext) @@ -426,21 +394,14 @@ public final class ApplicationManifest { // Now that the LocalResourceContainer has been filtered, we can build a filtered resource // container from it. ResourceContainer resourceContainer = - checkForInlinedResources( - ResourceContainer.builderFromRule(ruleContext) - .setRTxt(rTxt) - .setSymbols(symbols) - .setJavaPackageFrom(JavaPackageSource.MANIFEST) - .setManifestExported(true) - .setManifest(getManifest()) - .setAssetsAndResourcesFrom(data) - .build(), - resourceDeps - .getResourceContainers(), // TODO(bazel-team): Figure out if we really need to check - // the ENTIRE transitive closure, or just the direct dependencies. Given that each rule - // with resources would check for inline resources, we can rely on the previous rule to - // have checked its dependencies. - ruleContext); + ResourceContainer.builderFromRule(ruleContext) + .setRTxt(rTxt) + .setSymbols(symbols) + .setJavaPackageFrom(JavaPackageSource.MANIFEST) + .setManifestExported(true) + .setManifest(getManifest()) + .setAssetsAndResourcesFrom(data) + .build(); // android_library should only build the APK one way (!incremental). Artifact rJavaClassJar = @@ -526,18 +487,11 @@ public final class ApplicationManifest { // Now that the LocalResourceContainer has been filtered, we can build a filtered resource // container from it. ResourceContainer resourceContainer = - checkForInlinedResources( - ResourceContainer.builderFromRule(ruleContext) - .setApk(resourceApk) - .setManifest(getManifest()) - .setAssetsAndResourcesFrom(data) - .build(), - resourceDeps - .getResourceContainers(), // TODO(bazel-team): Figure out if we really need to check - // the ENTIRE transitive closure, or just the direct dependencies. Given that each rule - // with resources would check for inline resources, we can rely on the previous rule to - // have checked its dependencies. - ruleContext); + ResourceContainer.builderFromRule(ruleContext) + .setApk(resourceApk) + .setManifest(getManifest()) + .setAssetsAndResourcesFrom(data) + .build(); ResourceContainer processed = new AndroidResourcesProcessorBuilder(ruleContext) @@ -605,19 +559,12 @@ public final class ApplicationManifest { // Now that the LocalResourceContainer has been filtered, we can build a filtered resource // container from it. ResourceContainer resourceContainer = - checkForInlinedResources( - ResourceContainer.builderFromRule(ruleContext) - .setAssetsAndResourcesFrom(data) - .setManifest(getManifest()) - .setRTxt(rTxt) - .setApk(resourceApk) - .build(), - resourceDeps - .getResourceContainers(), // TODO(bazel-team): Figure out if we really need to check - // the ENTIRE transitive closure, or just the direct dependencies. Given that each rule - // with resources would check for inline resources, we can rely on the previous rule to - // have checked its dependencies. - ruleContext); + ResourceContainer.builderFromRule(ruleContext) + .setAssetsAndResourcesFrom(data) + .setManifest(getManifest()) + .setRTxt(rTxt) + .setApk(resourceApk) + .build(); AndroidConfiguration androidConfiguration = ruleContext.getConfiguration().getFragment(AndroidConfiguration.class); @@ -718,17 +665,7 @@ public final class ApplicationManifest { AndroidRuleClasses.ANDROID_RESOURCES_AAPT2_LIBRARY_APK)); } - // Now that the LocalResourceContainer has been filtered, we can build a filtered resource - // container from it. - ResourceContainer resourceContainer = - checkForInlinedResources( - builder.setManifest(getManifest()).setAssetsAndResourcesFrom(data).build(), - resourceDeps - .getResourceContainers(), // TODO(bazel-team): Figure out if we really need to check - // the ENTIRE transitive closure, or just the direct dependencies. Given that each rule - // with resources would check for inline resources, we can rely on the previous rule to - // have checked its dependencies. - ruleContext); + ResourceContainer resourceContainer = builder.build(); Artifact rJavaClassJar = ruleContext.getImplicitOutputArtifact(AndroidRuleClasses.ANDROID_RESOURCES_CLASS_JAR); @@ -803,165 +740,6 @@ public final class ApplicationManifest { false); } - private static ResourceContainer checkForInlinedResources( - ResourceContainer resourceContainer, - Iterable resourceContainers, - RuleContext ruleContext) - throws RuleErrorException { - // Dealing with Android library projects - if (Iterables.size(resourceContainers) > 1) { - if (resourceContainer.getConstantsInlined() - && !resourceContainer.getArtifacts(ResourceType.RESOURCES).isEmpty()) { - ruleContext.ruleError( - "This android binary depends on an android " - + "library project, so the resources '" - + AndroidCommon.getAndroidResources(ruleContext).getLabel() - + "' should have the attribute inline_constants set to 0"); - throw new RuleErrorException(); - } - } - return resourceContainer; - } - - /** Uses the resource apk from the resources attribute, as opposed to recompiling. */ - public ResourceApk useCurrentResources( - RuleContext ruleContext, Artifact proguardCfg, @Nullable Artifact mainDexProguardCfg) { - ResourceContainer resourceContainer = - Iterables.getOnlyElement( - AndroidCommon.getAndroidResources(ruleContext).getDirectAndroidResources()); - - new AndroidAaptActionHelper( - ruleContext, resourceContainer.getManifest(), Lists.newArrayList(resourceContainer)) - .createGenerateProguardAction(proguardCfg, mainDexProguardCfg); - - return new ResourceApk( - resourceContainer.getApk(), - null /* javaSrcJar */, - null /* javaClassJar */, - ResourceDependencies.empty(), - resourceContainer, - manifest, - proguardCfg, - mainDexProguardCfg, - false); - } - - /** - * Packages up the manifest with resources, and generates the R.java. - * - * @throws InterruptedException - * @deprecated in favor of {@link ApplicationManifest#packBinaryWithDataAndResources} and {@link - * ApplicationManifest#packLibraryWithDataAndResources}. - */ - @Deprecated - public ResourceApk packWithResources( - Artifact resourceApk, - RuleContext ruleContext, - ResourceDependencies resourceDeps, - boolean createSource, - Artifact proguardCfg, - @Nullable Artifact mainDexProguardCfg) - throws InterruptedException, RuleErrorException { - - TransitiveInfoCollection resourcesPrerequisite = - ruleContext.getPrerequisite("resources", Mode.TARGET); - ResourceContainer resourceContainer = - Iterables.getOnlyElement( - resourcesPrerequisite - .getProvider(AndroidResourcesProvider.class) - .getDirectAndroidResources()); - // It's ugly, but flattening now is more performant given the rest of the checks. - List resourceContainers = - ImmutableList.builder() - // .add(resourceContainer) - .addAll(resourceDeps.getResourceContainers()) - .build(); - - // Dealing with Android library projects - if (Iterables.size(resourceDeps.getResourceContainers()) > 1) { - if (resourceContainer.getConstantsInlined() - && !resourceContainer.getArtifacts(ResourceType.RESOURCES).isEmpty()) { - ruleContext.ruleError( - "This android_binary depends on an android_library, so the" - + " resources '" - + AndroidCommon.getAndroidResources(ruleContext).getLabel() - + "' should have the attribute inline_constants set to 0"); - return null; - } - } - - // This binary depends on a library project, so we need to regenerate the - // resources. The resulting sources and apk will combine all the resources - // contained in the transitive closure of the binary. - AndroidAaptActionHelper aaptActionHelper = - new AndroidAaptActionHelper( - ruleContext, getManifest(), Lists.newArrayList(resourceContainers)); - - ResourceFilterFactory resourceFilterFactory = - ResourceFilterFactory.fromRuleContext(ruleContext); - - List uncompressedExtensions; - if (ruleContext - .getRule() - .isAttrDefined(AndroidRuleClasses.NOCOMPRESS_EXTENSIONS_ATTR, Type.STRING_LIST)) { - uncompressedExtensions = - ruleContext - .getExpander() - .withDataLocations() - .tokenized(AndroidRuleClasses.NOCOMPRESS_EXTENSIONS_ATTR); - } else { - // This code is also used by android_test, which doesn't have this attribute. - uncompressedExtensions = ImmutableList.of(); - } - - ImmutableList.Builder additionalAaptOpts = ImmutableList.builder(); - - for (String extension : uncompressedExtensions) { - additionalAaptOpts.add("-0").add(extension); - } - if (resourceFilterFactory.hasConfigurationFilters()) { - additionalAaptOpts.add("-c").add(resourceFilterFactory.getConfigurationFilterString()); - } - - Artifact javaSourcesJar = null; - - if (createSource) { - javaSourcesJar = - ruleContext.getImplicitOutputArtifact(AndroidRuleClasses.ANDROID_JAVA_SOURCE_JAR); - aaptActionHelper.createGenerateResourceSymbolsAction( - javaSourcesJar, null, resourceContainer.getJavaPackage(), true); - } - - aaptActionHelper.createGenerateApkAction( - resourceApk, - resourceContainer.getRenameManifestPackage(), - additionalAaptOpts.build(), - resourceFilterFactory.getDensities()); - - ResourceContainer updatedResources = - resourceContainer - .toBuilder() - .setLabel(ruleContext.getLabel()) - .setJavaClassJar(null) // remove the resource class jar to force a regeneration. - .setApk(resourceApk) - .setManifest(getManifest()) - .setJavaSourceJar(javaSourcesJar) - .build(); - - aaptActionHelper.createGenerateProguardAction(proguardCfg, mainDexProguardCfg); - - return new ResourceApk( - resourceApk, - updatedResources.getJavaSourceJar(), - updatedResources.getJavaClassJar(), - resourceDeps, - updatedResources, - manifest, - proguardCfg, - mainDexProguardCfg, - true); - } - public Artifact getManifest() { return manifest; } diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/LocalResourceContainer.java b/src/main/java/com/google/devtools/build/lib/rules/android/LocalResourceContainer.java index 68c10576d4..d0da13d2bb 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/android/LocalResourceContainer.java +++ b/src/main/java/com/google/devtools/build/lib/rules/android/LocalResourceContainer.java @@ -84,7 +84,6 @@ public final class LocalResourceContainer { */ public static void validateRuleContext(RuleContext ruleContext) throws RuleErrorException { validateAssetsAndAssetsDir(ruleContext); - validateNoResourcesAttribute(ruleContext); validateNoAndroidResourcesInSources(ruleContext); validateManifest(ruleContext); } @@ -98,20 +97,8 @@ public final class LocalResourceContainer { } } - /** Validates that there are no resources defined if there are resource attributes defined. */ - private static void validateNoResourcesAttribute(RuleContext ruleContext) - throws RuleErrorException { - if (ruleContext.attributes().isAttributeValueExplicitlySpecified("resources")) { - ruleContext.throwWithAttributeError( - "resources", - String.format( - "resources cannot be set when any of %s are defined.", - Joiner.on(", ").join(RESOURCES_ATTRIBUTES))); - } - } - /** - * Validates that there are no android_resources srcjars in the srcs, as android_resource rules + * Validates that there are no targets with resources in the srcs, as they * should not be used with the Android data logic. */ private static void validateNoAndroidResourcesInSources(RuleContext ruleContext) @@ -121,7 +108,7 @@ public final class LocalResourceContainer { for (AndroidResourcesProvider provider : resources) { ruleContext.throwWithAttributeError( "srcs", - String.format("srcs should not contain android_resource label %s", provider.getLabel())); + String.format("srcs should not contain label with resources %s", provider.getLabel())); } } diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/ResourceApk.java b/src/main/java/com/google/devtools/build/lib/rules/android/ResourceApk.java index a4980cf040..01d19ab2be 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/android/ResourceApk.java +++ b/src/main/java/com/google/devtools/build/lib/rules/android/ResourceApk.java @@ -105,16 +105,13 @@ public final class ResourceApk { * contain the "forwarded" resources: The merged transitive and merged direct dependencies of this * library. * - *

If the ResourceApk was generated from a "resources" attribute, it will contain the - * "resources" container in the direct dependencies and the rest as transitive. - * *

If the ResourceApk was generated from local resources, that will be the direct dependencies * and the rest will be transitive. */ - public AndroidResourcesProvider toResourceProvider(Label label, boolean isResourcesOnly) { + public AndroidResourcesProvider toResourceProvider(Label label) { if (primaryResource == null) { - return resourceDeps.toProvider(label, isResourcesOnly); + return resourceDeps.toProvider(label); } - return resourceDeps.toProvider(label, primaryResource, isResourcesOnly); + return resourceDeps.toProvider(label, primaryResource); } } diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/ResourceContainer.java b/src/main/java/com/google/devtools/build/lib/rules/android/ResourceContainer.java index 89d110f4d4..845be8ba85 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/android/ResourceContainer.java +++ b/src/main/java/com/google/devtools/build/lib/rules/android/ResourceContainer.java @@ -55,11 +55,6 @@ public abstract class ResourceContainer { @Nullable public abstract String getJavaPackage(); - @Nullable - public abstract String getRenameManifestPackage(); - - public abstract boolean getConstantsInlined(); - @Nullable public abstract Artifact getApk(); @@ -207,7 +202,6 @@ public abstract class ResourceContainer { public static Builder builder() { return new AutoValue_ResourceContainer.Builder() .setJavaPackageFrom(Builder.JavaPackageSource.MANIFEST) - .setConstantsInlined(false) .setAssets(ImmutableList.of()) .setResources(ImmutableList.of()) .setAssetsRoots(ImmutableList.of()) @@ -248,7 +242,6 @@ public abstract class ResourceContainer { Preconditions.checkNotNull(ruleContext); this.ruleContext = ruleContext; return this.setLabel(ruleContext.getLabel()) - .setRenameManifestPackage(getRenameManifestPackage(ruleContext)) .setJavaSourceJar( ruleContext.getImplicitOutputArtifact(AndroidRuleClasses.ANDROID_JAVA_SOURCE_JAR)) .setJavaPackageFrom(JavaPackageSource.SOURCE_JAR_PATH) @@ -303,10 +296,6 @@ public abstract class ResourceContainer { abstract Builder setJavaPackage(@Nullable String javaPackage); - public abstract Builder setRenameManifestPackage(@Nullable String renameManifestPackage); - - public abstract Builder setConstantsInlined(boolean constantsInlined); - public abstract Builder setApk(@Nullable Artifact apk); public abstract Builder setManifest(Artifact manifest); @@ -389,12 +378,5 @@ public abstract class ResourceContainer { private static boolean hasCustomPackage(RuleContext ruleContext) { return ruleContext.attributes().isAttributeValueExplicitlySpecified("custom_package"); } - - @Nullable - private static String getRenameManifestPackage(RuleContext ruleContext) { - return ruleContext.attributes().isAttributeValueExplicitlySpecified("rename_manifest_package") - ? ruleContext.attributes().get("rename_manifest_package", Type.STRING) - : null; - } } } diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/ResourceDependencies.java b/src/main/java/com/google/devtools/build/lib/rules/android/ResourceDependencies.java index 80ff7c823a..ab9cefb844 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/android/ResourceDependencies.java +++ b/src/main/java/com/google/devtools/build/lib/rules/android/ResourceDependencies.java @@ -15,7 +15,6 @@ package com.google.devtools.build.lib.rules.android; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.MoreObjects; -import com.google.common.collect.ImmutableList; import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.analysis.RuleContext; import com.google.devtools.build.lib.analysis.configuredtargets.RuleConfiguredTarget.Mode; @@ -88,48 +87,6 @@ public final class ResourceDependencies { /** Whether the resources of the current rule should be treated as neverlink. */ private final boolean neverlink; - public static ResourceDependencies fromRuleResources(RuleContext ruleContext, boolean neverlink) { - if (!hasResourceAttribute(ruleContext)) { - return empty(); - } - - NestedSetBuilder transitiveDependencies = NestedSetBuilder.naiveLinkOrder(); - NestedSetBuilder directDependencies = NestedSetBuilder.naiveLinkOrder(); - NestedSetBuilder transitiveResources = NestedSetBuilder.naiveLinkOrder(); - NestedSetBuilder transitiveAssets = NestedSetBuilder.naiveLinkOrder(); - NestedSetBuilder transitiveManifests = NestedSetBuilder.naiveLinkOrder(); - NestedSetBuilder transitiveAapt2RTxt = NestedSetBuilder.naiveLinkOrder(); - NestedSetBuilder transitiveSymbolsBin = NestedSetBuilder.naiveLinkOrder(); - NestedSetBuilder transitiveCompiledSymbols = NestedSetBuilder.naiveLinkOrder(); - NestedSetBuilder transitiveStaticLib = NestedSetBuilder.naiveLinkOrder(); - NestedSetBuilder transitiveRTxt = NestedSetBuilder.naiveLinkOrder(); - extractFromAttributes( - ImmutableList.of("resources"), - ruleContext, - transitiveDependencies, - directDependencies, - transitiveResources, - transitiveAssets, - transitiveManifests, - transitiveAapt2RTxt, - transitiveSymbolsBin, - transitiveCompiledSymbols, - transitiveStaticLib, - transitiveRTxt); - return new ResourceDependencies( - neverlink, - transitiveDependencies.build(), - directDependencies.build(), - transitiveResources.build(), - transitiveAssets.build(), - transitiveManifests.build(), - transitiveAapt2RTxt.build(), - transitiveSymbolsBin.build(), - transitiveCompiledSymbols.build(), - transitiveStaticLib.build(), - transitiveRTxt.build()); - } - public static ResourceDependencies fromRuleDeps(RuleContext ruleContext, boolean neverlink) { NestedSetBuilder transitiveDependencies = NestedSetBuilder.naiveLinkOrder(); NestedSetBuilder directDependencies = NestedSetBuilder.naiveLinkOrder(); @@ -141,130 +98,16 @@ public final class ResourceDependencies { NestedSetBuilder transitiveCompiledSymbols = NestedSetBuilder.naiveLinkOrder(); NestedSetBuilder transitiveStaticLib = NestedSetBuilder.naiveLinkOrder(); NestedSetBuilder transitiveRTxt = NestedSetBuilder.naiveLinkOrder(); - extractFromAttributes( - AndroidCommon.TRANSITIVE_ATTRIBUTES, - ruleContext, - transitiveDependencies, - directDependencies, - transitiveResources, - transitiveAssets, - transitiveManifests, - transitiveAapt2RTxt, - transitiveSymbolsBin, - transitiveCompiledSymbols, - transitiveStaticLib, - transitiveRTxt); - return new ResourceDependencies( - neverlink, - transitiveDependencies.build(), - directDependencies.build(), - transitiveResources.build(), - transitiveAssets.build(), - transitiveManifests.build(), - transitiveAapt2RTxt.build(), - transitiveSymbolsBin.build(), - transitiveCompiledSymbols.build(), - transitiveStaticLib.build(), - transitiveRTxt.build()); - } - public static ResourceDependencies fromRuleResourceAndDeps( - RuleContext ruleContext, boolean neverlink) { - NestedSetBuilder transitiveDependencies = NestedSetBuilder.naiveLinkOrder(); - NestedSetBuilder directDependencies = NestedSetBuilder.naiveLinkOrder(); - NestedSetBuilder transitiveResources = NestedSetBuilder.naiveLinkOrder(); - NestedSetBuilder transitiveAssets = NestedSetBuilder.naiveLinkOrder(); - NestedSetBuilder transitiveManifests = NestedSetBuilder.naiveLinkOrder(); - NestedSetBuilder transitiveAapt2RTxt = NestedSetBuilder.naiveLinkOrder(); - NestedSetBuilder transitiveSymbolsBin = NestedSetBuilder.naiveLinkOrder(); - NestedSetBuilder transitiveCompiledSymbols = NestedSetBuilder.naiveLinkOrder(); - NestedSetBuilder transitiveStaticLib = NestedSetBuilder.naiveLinkOrder(); - NestedSetBuilder transitiveRTxt = NestedSetBuilder.naiveLinkOrder(); - if (hasResourceAttribute(ruleContext)) { - extractFromAttributes( - ImmutableList.of("resources"), - ruleContext, - transitiveDependencies, - directDependencies, - transitiveResources, - transitiveAssets, - transitiveManifests, - transitiveAapt2RTxt, - transitiveSymbolsBin, - transitiveCompiledSymbols, - transitiveStaticLib, - transitiveRTxt); - } - if (directDependencies.isEmpty()) { - // There are no resources, so this library will forward the direct and transitive dependencies - // without changes. - extractFromAttributes( - AndroidCommon.TRANSITIVE_ATTRIBUTES, - ruleContext, - transitiveDependencies, - directDependencies, - transitiveResources, - transitiveAssets, - transitiveManifests, - transitiveAapt2RTxt, - transitiveSymbolsBin, - transitiveCompiledSymbols, - transitiveStaticLib, - transitiveRTxt); - } else { - // There are resources, so the direct dependencies and the transitive will be merged into - // the transitive dependencies. This maintains the relationship of the resources being - // directly on the rule. - extractFromAttributes( - AndroidCommon.TRANSITIVE_ATTRIBUTES, - ruleContext, - transitiveDependencies, - transitiveDependencies, - transitiveResources, - transitiveAssets, - transitiveManifests, - transitiveAapt2RTxt, - transitiveSymbolsBin, - transitiveCompiledSymbols, - transitiveStaticLib, - transitiveRTxt); - } - return new ResourceDependencies( - neverlink, - transitiveDependencies.build(), - directDependencies.build(), - transitiveResources.build(), - transitiveAssets.build(), - transitiveManifests.build(), - transitiveAapt2RTxt.build(), - transitiveSymbolsBin.build(), - transitiveCompiledSymbols.build(), - transitiveStaticLib.build(), - transitiveRTxt.build()); - } - - private static void extractFromAttributes( - Iterable attributeNames, - RuleContext ruleContext, - NestedSetBuilder builderForTransitive, - NestedSetBuilder builderForDirect, - NestedSetBuilder transitiveResources, - NestedSetBuilder transitiveAssets, - NestedSetBuilder transitiveManifests, - NestedSetBuilder transitiveAapt2RTxt, - NestedSetBuilder transitiveSymbolsBin, - NestedSetBuilder transitiveCompiledSymbols, - NestedSetBuilder transitiveStaticLib, - NestedSetBuilder transitiveRTxt) { AttributeMap attributes = ruleContext.attributes(); - for (String attr : attributeNames) { + for (String attr : AndroidCommon.TRANSITIVE_ATTRIBUTES) { if (!attributes.has(attr, BuildType.LABEL_LIST) && !attributes.has(attr, BuildType.LABEL)) { continue; } for (AndroidResourcesProvider resources : ruleContext.getPrerequisites(attr, Mode.TARGET, AndroidResourcesProvider.class)) { - builderForTransitive.addTransitive(resources.getTransitiveAndroidResources()); - builderForDirect.addTransitive(resources.getDirectAndroidResources()); + transitiveDependencies.addTransitive(resources.getTransitiveAndroidResources()); + directDependencies.addTransitive(resources.getDirectAndroidResources()); transitiveResources.addTransitive(resources.getTransitiveResources()); transitiveAssets.addTransitive(resources.getTransitiveAssets()); transitiveManifests.addTransitive(resources.getTransitiveManifests()); @@ -275,19 +118,19 @@ public final class ResourceDependencies { transitiveRTxt.addTransitive(resources.getTransitiveRTxt()); } } - } - /** - * Check for the existence of a "resources" attribute. - * - *

The existence of the resources attribute is not guaranteed on for all android rules, so it - * is necessary to check for it. - * - * @param ruleContext The context to check. - * @return True if the ruleContext has resources, otherwise, false. - */ - private static boolean hasResourceAttribute(RuleContext ruleContext) { - return ruleContext.attributes().has("resources", BuildType.LABEL); + return new ResourceDependencies( + neverlink, + transitiveDependencies.build(), + directDependencies.build(), + transitiveResources.build(), + transitiveAssets.build(), + transitiveManifests.build(), + transitiveAapt2RTxt.build(), + transitiveSymbolsBin.build(), + transitiveCompiledSymbols.build(), + transitiveStaticLib.build(), + transitiveRTxt.build()); } @Override @@ -399,14 +242,12 @@ public final class ResourceDependencies { * * @param label The label of the library exporting this provider. * @param newDirectResource The new direct dependency for AndroidResourcesProvider - * @param isResourcesOnly if the direct dependency is either an android_resources target or an - * android_library target with no fields that android_resources targets do not provide. * @return A provider with the current resources and label. */ public AndroidResourcesProvider toProvider( - Label label, ResourceContainer newDirectResource, boolean isResourcesOnly) { + Label label, ResourceContainer newDirectResource) { if (neverlink) { - return ResourceDependencies.empty().toProvider(label, isResourcesOnly); + return ResourceDependencies.empty().toProvider(label); } return AndroidResourcesProvider.create( label, @@ -428,8 +269,7 @@ public final class ResourceDependencies { withDirectAndTransitive(newDirectResource.getSymbols(), transitiveSymbolsBin), withDirectAndTransitive(newDirectResource.getCompiledSymbols(), transitiveCompiledSymbols), withDirectAndTransitive(newDirectResource.getStaticLibrary(), transitiveStaticLib), - withDirectAndTransitive(newDirectResource.getRTxt(), transitiveRTxt), - isResourcesOnly); + withDirectAndTransitive(newDirectResource.getRTxt(), transitiveRTxt)); } private static NestedSet withDirectAndTransitive( @@ -451,13 +291,11 @@ public final class ResourceDependencies { * the resource merging as if this library didn't exist. * * @param label The label of the library exporting this provider. - * @param isResourcesOnly if the direct dependency is either an android_resources target or an - * android_library target with no fields that android_resources targets do not provide. * @return A provider with the current resources and label. */ - public AndroidResourcesProvider toProvider(Label label, boolean isResourcesOnly) { + public AndroidResourcesProvider toProvider(Label label) { if (neverlink) { - return ResourceDependencies.empty().toProvider(label, isResourcesOnly); + return ResourceDependencies.empty().toProvider(label); } return AndroidResourcesProvider.create( label, @@ -470,8 +308,7 @@ public final class ResourceDependencies { transitiveSymbolsBin, transitiveCompiledSymbols, transitiveStaticLib, - transitiveRTxt, - isResourcesOnly); + transitiveRTxt); } /** diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/ResourceFilterFactory.java b/src/main/java/com/google/devtools/build/lib/rules/android/ResourceFilterFactory.java index 189a14a765..b4af907ed4 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/android/ResourceFilterFactory.java +++ b/src/main/java/com/google/devtools/build/lib/rules/android/ResourceFilterFactory.java @@ -144,10 +144,6 @@ public class ResourceFilterFactory { return values != null && !values.isEmpty(); } - static boolean hasFilters(RuleContext ruleContext) { - return hasFilters(ruleContext.attributes()); - } - static boolean hasFilters(AttributeMap attrs) { return hasAttr(attrs, RESOURCE_CONFIGURATION_FILTERS_NAME) || hasAttr(attrs, DENSITIES_NAME); } -- cgit v1.2.3