From 65e1fa81add2c40a5434d26c7a46a1ef9b249981 Mon Sep 17 00:00:00 2001 From: asteinb Date: Mon, 16 Apr 2018 12:58:00 -0700 Subject: Provider and dependency container for Android assets These classes will allow a reasonable asset-only merging action in the next change. The relationship between AndroidAssetsInfo and AssetDependencies is a bit messy; I based it on the existing resource provider and dependencies class rather than come up with something radically different. RELNOTES: none PiperOrigin-RevId: 193085304 --- .../build/lib/rules/android/AndroidAssetsInfo.java | 90 +++++++++++++ .../build/lib/rules/android/AndroidCommon.java | 2 +- .../build/lib/rules/android/AssetDependencies.java | 140 +++++++++++++++++++++ .../lib/rules/android/ResourceDependencies.java | 13 +- 4 files changed, 234 insertions(+), 11 deletions(-) create mode 100644 src/main/java/com/google/devtools/build/lib/rules/android/AndroidAssetsInfo.java create mode 100644 src/main/java/com/google/devtools/build/lib/rules/android/AssetDependencies.java (limited to 'src/main/java/com/google/devtools') 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 new file mode 100644 index 0000000000..5431c00006 --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidAssetsInfo.java @@ -0,0 +1,90 @@ +// Copyright 2018 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.devtools.build.lib.actions.Artifact; +import com.google.devtools.build.lib.cmdline.Label; +import com.google.devtools.build.lib.collect.nestedset.NestedSet; +import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; +import com.google.devtools.build.lib.collect.nestedset.Order; +import com.google.devtools.build.lib.packages.NativeInfo; +import com.google.devtools.build.lib.packages.NativeProvider; + +/** Provides information about transitive Android assets. */ +public class AndroidAssetsInfo extends NativeInfo { + + private static final String SKYLARK_NAME = "AndroidAssetsInfo"; + + public static final NativeProvider PROVIDER = + new NativeProvider(AndroidAssetsInfo.class, SKYLARK_NAME) {}; + + private final Label label; + private final NestedSet directParsedAssets; + private final NestedSet transitiveParsedAssets; + private final NestedSet transitiveAssets; + private final NestedSet transitiveSymbols; + + static AndroidAssetsInfo empty(Label label) { + return new AndroidAssetsInfo( + label, + NestedSetBuilder.emptySet(Order.NAIVE_LINK_ORDER), + NestedSetBuilder.emptySet(Order.NAIVE_LINK_ORDER), + NestedSetBuilder.emptySet(Order.NAIVE_LINK_ORDER), + NestedSetBuilder.emptySet(Order.NAIVE_LINK_ORDER)); + } + + public static AndroidAssetsInfo of( + Label label, + NestedSet directParsedAssets, + NestedSet transitiveParsedAssets, + NestedSet transitiveAssets, + NestedSet transitiveSymbols) { + return new AndroidAssetsInfo( + label, directParsedAssets, transitiveParsedAssets, transitiveAssets, transitiveSymbols); + } + + private AndroidAssetsInfo( + Label label, + NestedSet directParsedAssets, + NestedSet transitiveParsedAssets, + NestedSet transitiveAssets, + NestedSet transitiveSymbols) { + super(PROVIDER); + this.label = label; + this.directParsedAssets = directParsedAssets; + this.transitiveParsedAssets = transitiveParsedAssets; + this.transitiveAssets = transitiveAssets; + this.transitiveSymbols = transitiveSymbols; + } + + public Label getLabel() { + return label; + } + + public NestedSet getDirectParsedAssets() { + return directParsedAssets; + } + + public NestedSet getTransitiveParsedAssets() { + return transitiveParsedAssets; + } + + public NestedSet getAssets() { + return transitiveAssets; + } + + public NestedSet getSymbols() { + return transitiveSymbols; + } +} 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 2ab240f110..68e9b1748d 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 @@ -84,7 +84,7 @@ public class AndroidCommon { JavaCommon.JAVA_COLLECTION_SPEC.withDependencyAttributes( "deps", "data", "exports", "runtime_deps", "binary_under_test"); - public static final ImmutableSet TRANSITIVE_ATTRIBUTES = + private static final ImmutableSet TRANSITIVE_ATTRIBUTES = ImmutableSet.of("deps", "exports"); private static final ResourceSet DEX_RESOURCE_SET = ResourceSet.createWithRamCpuIo(4096.0, 5.0, 0.0); 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 new file mode 100644 index 0000000000..c2b68977ba --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/rules/android/AssetDependencies.java @@ -0,0 +1,140 @@ +// Copyright 2018 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.devtools.build.lib.actions.Artifact; +import com.google.devtools.build.lib.analysis.RuleContext; +import com.google.devtools.build.lib.analysis.configuredtargets.RuleConfiguredTarget.Mode; +import com.google.devtools.build.lib.cmdline.Label; +import com.google.devtools.build.lib.collect.nestedset.NestedSet; +import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; +import com.google.devtools.build.lib.collect.nestedset.Order; + +/** + * Contains transitive asset dependencies for a target. + * + *

In addition to NestedSets of transitive artifacts, we also keep transitive NestedSets of + * direct and transitive parsed assets. These NestedSets contain the same information (and it may + * appear in both the direct and transitive parsed asset NestedSets); we need to keep them both + * separately to record relationships between assets, asset directories, and symbol artifacts and to + * distinguish between direct and transitive assets. + */ +public class AssetDependencies { + private final boolean neverlink; + private final NestedSet directParsedAssets; + private final NestedSet transitiveParsedAssets; + private final NestedSet transitiveAssets; + private final NestedSet transitiveSymbols; + + static AssetDependencies fromRuleDeps(RuleContext ruleContext, boolean neverlink) { + NestedSetBuilder direct = NestedSetBuilder.naiveLinkOrder(); + NestedSetBuilder transitive = NestedSetBuilder.naiveLinkOrder(); + NestedSetBuilder assets = NestedSetBuilder.naiveLinkOrder(); + NestedSetBuilder symbols = NestedSetBuilder.naiveLinkOrder(); + + for (AndroidAssetsInfo info : + AndroidCommon.getTransitivePrerequisites( + ruleContext, Mode.TARGET, AndroidAssetsInfo.PROVIDER)) { + direct.addTransitive(info.getDirectParsedAssets()); + transitive.addTransitive(info.getTransitiveParsedAssets()); + assets.addTransitive(info.getAssets()); + symbols.addTransitive(info.getSymbols()); + } + + return of(neverlink, direct.build(), transitive.build(), assets.build(), symbols.build()); + } + + public static AssetDependencies empty() { + return of( + false, + NestedSetBuilder.emptySet(Order.NAIVE_LINK_ORDER), + NestedSetBuilder.emptySet(Order.NAIVE_LINK_ORDER), + NestedSetBuilder.emptySet(Order.NAIVE_LINK_ORDER), + NestedSetBuilder.emptySet(Order.NAIVE_LINK_ORDER)); + } + + @VisibleForTesting + static AssetDependencies of( + boolean neverlink, + NestedSet directParsedAssets, + NestedSet transitiveParsedAssets, + NestedSet transitiveAssets, + NestedSet transitiveSymbols) { + return new AssetDependencies( + neverlink, directParsedAssets, transitiveParsedAssets, transitiveAssets, transitiveSymbols); + } + + private AssetDependencies( + boolean neverlink, + NestedSet directParsedAssets, + NestedSet transitiveParsedAssets, + NestedSet transitiveAssets, + NestedSet transitiveSymbols) { + this.neverlink = neverlink; + this.directParsedAssets = directParsedAssets; + this.transitiveParsedAssets = transitiveParsedAssets; + this.transitiveAssets = transitiveAssets; + this.transitiveSymbols = transitiveSymbols; + } + + /** Creates a new AndroidAssetInfo using the passed assets as the direct dependency. */ + public AndroidAssetsInfo toInfo(ParsedAndroidAssets assets) { + if (neverlink) { + return AndroidAssetsInfo.empty(assets.getLabel()); + } + + return AndroidAssetsInfo.of( + assets.getLabel(), + NestedSetBuilder.create(Order.NAIVE_LINK_ORDER, assets), + NestedSetBuilder.naiveLinkOrder() + .addTransitive(transitiveParsedAssets) + .addTransitive(directParsedAssets) + .build(), + NestedSetBuilder.naiveLinkOrder() + .addTransitive(transitiveAssets) + .addAll(assets.getAssets()) + .build(), + NestedSetBuilder.naiveLinkOrder() + .addTransitive(transitiveSymbols) + .add(assets.getSymbols()) + .build()); + } + + /** Creates a new AndroidAssetsInfo from this target's dependencies, without any local assets. */ + public AndroidAssetsInfo toInfo(Label label) { + if (neverlink) { + return AndroidAssetsInfo.empty(label); + } + + return AndroidAssetsInfo.of( + label, directParsedAssets, transitiveParsedAssets, transitiveAssets, transitiveSymbols); + } + + public NestedSet getDirectParsedAssets() { + return directParsedAssets; + } + + public NestedSet getTransitiveParsedAssets() { + return transitiveParsedAssets; + } + + public NestedSet getTransitiveAssets() { + return transitiveAssets; + } + + public NestedSet getTransitiveSymbols() { + return transitiveSymbols; + } +} 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 cacae74343..27bba1bd4d 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 @@ -23,8 +23,6 @@ import com.google.devtools.build.lib.collect.nestedset.NestedSet; import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; import com.google.devtools.build.lib.collect.nestedset.Order; import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable; -import com.google.devtools.build.lib.packages.AttributeMap; -import com.google.devtools.build.lib.packages.BuildType; import com.google.devtools.build.lib.packages.RuleClass.ConfiguredTargetFactory.RuleErrorException; import com.google.devtools.build.lib.packages.RuleErrorConsumer; import java.util.Optional; @@ -105,13 +103,9 @@ public final class ResourceDependencies { NestedSetBuilder transitiveStaticLib = NestedSetBuilder.naiveLinkOrder(); NestedSetBuilder transitiveRTxt = NestedSetBuilder.naiveLinkOrder(); - AttributeMap attributes = ruleContext.attributes(); - for (String attr : AndroidCommon.TRANSITIVE_ATTRIBUTES) { - if (!attributes.has(attr, BuildType.LABEL_LIST) && !attributes.has(attr, BuildType.LABEL)) { - continue; - } - for (AndroidResourcesInfo resources : - ruleContext.getPrerequisites(attr, Mode.TARGET, AndroidResourcesInfo.PROVIDER)) { + for (AndroidResourcesInfo resources : + AndroidCommon.getTransitivePrerequisites( + ruleContext, Mode.TARGET, AndroidResourcesInfo.PROVIDER)) { transitiveDependencies.addTransitive(resources.getTransitiveAndroidResources()); directDependencies.addTransitive(resources.getDirectAndroidResources()); transitiveResources.addTransitive(resources.getTransitiveResources()); @@ -122,7 +116,6 @@ public final class ResourceDependencies { transitiveCompiledSymbols.addTransitive(resources.getTransitiveCompiledSymbols()); transitiveStaticLib.addTransitive(resources.getTransitiveStaticLib()); transitiveRTxt.addTransitive(resources.getTransitiveRTxt()); - } } return new ResourceDependencies( -- cgit v1.2.3