diff options
author | 2018-05-07 14:13:06 -0700 | |
---|---|---|
committer | 2018-05-07 14:15:14 -0700 | |
commit | deda170f1d31bdb996055e2e9eaa0dfbadc0df3d (patch) | |
tree | ffcee9bd98215e8197db3f205a40dbcced08f4a2 /src/main/java/com/google/devtools | |
parent | 432577185b4c3098f08fc7c2ecd29c0859e5dc65 (diff) |
Expose Library Aar creation and provider to Skylark
RELNOTES: none
PiperOrigin-RevId: 195719735
Diffstat (limited to 'src/main/java/com/google/devtools')
5 files changed, 160 insertions, 9 deletions
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 49dd128c72..fe539531ea 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 @@ -783,6 +783,10 @@ public class AndroidCommon { return jarsProducedForRuntime; } + public Artifact getClassJar() { + return classJar; + } + public Artifact getInstrumentedJar() { return javaCommon.getJavaCompilationArtifacts().getInstrumentedJar(); } 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 bda835674c..ed83e0b222 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 @@ -205,7 +205,11 @@ public abstract class AndroidLibrary implements RuleConfiguredTargetFactory { } final Aar aar = - Aar.makeAar(ruleContext, resourceApk, proguardLibrary.collectLocalProguardSpecs()); + Aar.makeAar( + ruleContext, + resourceApk, + proguardLibrary.collectLocalProguardSpecs(), + androidCommon.getClassJar()); RuleConfiguredTargetBuilder builder = new RuleConfiguredTargetBuilder(ruleContext); androidCommon.addTransitiveInfoProviders( diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLibraryAarInfo.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLibraryAarInfo.java index 3f4fa051a9..f38b40786e 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLibraryAarInfo.java +++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLibraryAarInfo.java @@ -106,26 +106,44 @@ public class AndroidLibraryAarInfo extends NativeInfo { static Aar makeAar( RuleContext ruleContext, ResourceApk resourceApk, + ImmutableList<Artifact> localProguardSpecs, + Artifact libraryClassJar) + throws InterruptedException { + return makeAar( + ruleContext, + resourceApk.getPrimaryResources(), + resourceApk.getPrimaryAssets(), + resourceApk.getProcessedManifest(), + resourceApk.getRTxt(), + libraryClassJar, + localProguardSpecs); + } + + static Aar makeAar( + RuleContext ruleContext, + AndroidResources primaryResources, + AndroidAssets primaryAssets, + ProcessedAndroidManifest manifest, + Artifact rTxt, + Artifact libraryClassJar, ImmutableList<Artifact> localProguardSpecs) throws InterruptedException { - Artifact classesJar = - ruleContext.getImplicitOutputArtifact(AndroidRuleClasses.ANDROID_LIBRARY_CLASS_JAR); Artifact aarOut = ruleContext.getImplicitOutputArtifact(AndroidRuleClasses.ANDROID_LIBRARY_AAR); new AarGeneratorBuilder(ruleContext) - .withPrimaryResources(resourceApk.getPrimaryResources()) - .withPrimaryAssets(resourceApk.getPrimaryAssets()) - .withManifest(resourceApk.getManifest()) - .withRtxt(resourceApk.getRTxt()) - .withClasses(classesJar) + .withPrimaryResources(primaryResources) + .withPrimaryAssets(primaryAssets) + .withManifest(manifest.getManifest()) + .withRtxt(rTxt) + .withClasses(libraryClassJar) .setAAROut(aarOut) .setProguardSpecs(localProguardSpecs) .setThrowOnResourceConflict( AndroidCommon.getAndroidConfig(ruleContext).throwOnResourceConflict()) .build(ruleContext); - return Aar.create(aarOut, resourceApk.getManifest()); + return Aar.create(aarOut, manifest.getManifest()); } public abstract Artifact getAar(); 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 4b8574bda3..38238f836d 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 @@ -18,8 +18,11 @@ import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.analysis.ConfiguredTarget; import com.google.devtools.build.lib.analysis.FileProvider; import com.google.devtools.build.lib.analysis.skylark.SkylarkRuleContext; +import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; +import com.google.devtools.build.lib.collect.nestedset.Order; import com.google.devtools.build.lib.events.Location; import com.google.devtools.build.lib.packages.RuleClass.ConfiguredTargetFactory.RuleErrorException; +import com.google.devtools.build.lib.rules.android.AndroidLibraryAarInfo.Aar; import com.google.devtools.build.lib.skylarkinterface.Param; import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable; import com.google.devtools.build.lib.skylarkinterface.SkylarkModule; @@ -340,6 +343,124 @@ public class AndroidSkylarkData { } } + /** + * Skylark API for building an Aar for an android_library + * + * <p>TODO(b/79159379): Stop passing SkylarkRuleContext here + * + * @param ctx the SkylarkRuleContext. We will soon change to using an ActionConstructionContext + * instead. See b/79159379 + */ + @SkylarkCallable( + name = "make_aar", + mandatoryPositionals = 4, // context, resource info, asset info, and library class jar + parameters = { + @Param( + name = "proguard_specs", + type = SkylarkList.class, + generic1 = ConfiguredTarget.class, + defaultValue = "[]", + positional = false, + named = true, + doc = + "Files to be used as Proguard specification for this target, which will be" + + " inherited in the top-level target"), + @Param( + name = "deps", + type = SkylarkList.class, + generic1 = AndroidLibraryAarInfo.class, + defaultValue = "[]", + positional = false, + named = true, + doc = "Dependant AAR providers used to build this AAR."), + @Param( + name = "neverlink", + type = Boolean.class, + defaultValue = "False", + positional = false, + named = true, + doc = + "Defaults to False. If true, this target's Aar will not be generated or propagated" + + " to targets that depend upon it."), + }, + doc = + "Builds an AAR and corresponding provider for this target. The resource and asset" + + " providers from this same target must both be passed, as must the class JAR output" + + " of building the Android Java library.") + public AndroidLibraryAarInfo makeAar( + SkylarkRuleContext ctx, + AndroidResourcesInfo resourcesInfo, + AndroidAssetsInfo assetsInfo, + Artifact libraryClassJar, + SkylarkList<ConfiguredTarget> proguardSpecs, + SkylarkList<AndroidLibraryAarInfo> deps, + boolean neverlink) + throws EvalException, InterruptedException { + if (neverlink) { + return AndroidLibraryAarInfo.create( + null, + NestedSetBuilder.emptySet(Order.NAIVE_LINK_ORDER), + NestedSetBuilder.emptySet(Order.NAIVE_LINK_ORDER)); + } + + // Get the target's local resources, if defined, from the provider + boolean definesLocalResources = resourcesInfo.getDirectAndroidResources().isSingleton(); + AndroidResources resources = AndroidResources.empty(); + if (definesLocalResources) { + ValidatedAndroidData validatedAndroidData = + resourcesInfo.getDirectAndroidResources().toList().get(0); + if (validatedAndroidData.getLabel().equals(ctx.getLabel())) { + // TODO(b/77574966): Remove this cast once we get rid of ResourceContainer and can guarantee + // that only properly processed resources are passed into this object. + if (!(validatedAndroidData instanceof ValidatedAndroidResources)) { + throw new EvalException( + Location.BUILTIN, "Old data processing pipeline does not support the Skylark API"); + } + resources = (ValidatedAndroidResources) validatedAndroidData; + } else { + definesLocalResources = false; + } + } + + // Get the target's local assets, if defined, from the provider + boolean definesLocalAssets = assetsInfo.getDirectParsedAssets().isSingleton(); + AndroidAssets assets = AndroidAssets.empty(); + if (definesLocalAssets) { + ParsedAndroidAssets parsed = assetsInfo.getDirectParsedAssets().toList().get(0); + if (parsed.getLabel().equals(ctx.getLabel())) { + assets = parsed; + } else { + definesLocalAssets = false; + } + } + + if (definesLocalResources != definesLocalAssets) { + throw new EvalException( + Location.BUILTIN, + "Must define either both or none of assets and resources. Use the merge_assets and" + + " merge_resources methods to define them, or assets_from_deps and" + + " resources_from_deps to inherit without defining them."); + } + + ImmutableList.Builder<Artifact> proguardSpecBuilder = ImmutableList.builder(); + for (ConfiguredTarget target : proguardSpecs) { + FileProvider fileProvider = target.getProvider(FileProvider.class); + if (fileProvider != null) { + proguardSpecBuilder.addAll(fileProvider.getFilesToBuild()); + } + } + + return Aar.makeAar( + ctx.getRuleContext(), + resources, + assets, + resourcesInfo.getManifest(), + resourcesInfo.getRTxt(), + libraryClassJar, + proguardSpecBuilder.build()) + .toProvider(deps, definesLocalResources); + } + /** Checks if a "Noneable" object passed by Skylark is "None", which Java should treat as null. */ private static boolean isNone(Object object) { return object == Runtime.NONE; 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 d69254268b..ffef2d5d0e 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 @@ -155,6 +155,10 @@ public final class ResourceApk { return primaryAssets; } + public ProcessedAndroidManifest getProcessedManifest() { + return manifest; + } + public Artifact getManifest() { return manifest.getManifest(); } |