// Copyright 2014 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.ideinfo; import static com.google.common.collect.Iterables.transform; import static com.google.devtools.build.lib.packages.Attribute.ConfigurationTransition.HOST; import static com.google.devtools.build.lib.packages.Attribute.attr; import static com.google.devtools.build.lib.packages.BuildType.LABEL; import com.google.common.base.Function; import com.google.common.base.Joiner; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import com.google.common.io.ByteSource; import com.google.devtools.build.lib.Constants; import com.google.devtools.build.lib.actions.Action; import com.google.devtools.build.lib.actions.ActionOwner; import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.actions.ParameterFile.ParameterFileType; import com.google.devtools.build.lib.actions.Root; import com.google.devtools.build.lib.analysis.AnalysisUtils; import com.google.devtools.build.lib.analysis.ConfiguredAspect; import com.google.devtools.build.lib.analysis.ConfiguredAspect.Builder; import com.google.devtools.build.lib.analysis.ConfiguredNativeAspectFactory; import com.google.devtools.build.lib.analysis.ConfiguredTarget; import com.google.devtools.build.lib.analysis.RuleConfiguredTarget.Mode; import com.google.devtools.build.lib.analysis.RuleContext; import com.google.devtools.build.lib.analysis.TransitiveInfoCollection; import com.google.devtools.build.lib.analysis.actions.BinaryFileWriteAction; 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; import com.google.devtools.build.lib.analysis.config.BuildConfiguration; 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.ideinfo.androidstudio.AndroidStudioIdeInfo.AndroidRuleIdeInfo; import com.google.devtools.build.lib.ideinfo.androidstudio.AndroidStudioIdeInfo.ArtifactLocation; import com.google.devtools.build.lib.ideinfo.androidstudio.AndroidStudioIdeInfo.CRuleIdeInfo; import com.google.devtools.build.lib.ideinfo.androidstudio.AndroidStudioIdeInfo.CToolchainIdeInfo; import com.google.devtools.build.lib.ideinfo.androidstudio.AndroidStudioIdeInfo.JavaRuleIdeInfo; import com.google.devtools.build.lib.ideinfo.androidstudio.AndroidStudioIdeInfo.LibraryArtifact; import com.google.devtools.build.lib.ideinfo.androidstudio.AndroidStudioIdeInfo.RuleIdeInfo; import com.google.devtools.build.lib.ideinfo.androidstudio.AndroidStudioIdeInfo.RuleIdeInfo.Kind; import com.google.devtools.build.lib.packages.AspectDefinition; import com.google.devtools.build.lib.packages.AspectParameters; import com.google.devtools.build.lib.packages.BuildType; import com.google.devtools.build.lib.packages.Package; import com.google.devtools.build.lib.packages.Rule; import com.google.devtools.build.lib.rules.android.AndroidIdeInfoProvider; import com.google.devtools.build.lib.rules.android.AndroidIdeInfoProvider.SourceDirectory; import com.google.devtools.build.lib.rules.android.AndroidSdkProvider; import com.google.devtools.build.lib.rules.cpp.CppCompilationContext; import com.google.devtools.build.lib.rules.cpp.CppConfiguration; import com.google.devtools.build.lib.rules.java.JavaExportsProvider; import com.google.devtools.build.lib.rules.java.JavaGenJarsProvider; import com.google.devtools.build.lib.rules.java.JavaRuleOutputJarsProvider; import com.google.devtools.build.lib.rules.java.JavaRuleOutputJarsProvider.OutputJar; import com.google.devtools.build.lib.rules.java.JavaSourceInfoProvider; import com.google.devtools.build.lib.syntax.Type; import com.google.devtools.build.lib.vfs.PathFragment; import com.google.protobuf.MessageLite; import java.io.IOException; import java.io.InputStream; import java.util.Collection; import java.util.List; import javax.annotation.Nullable; /** * Generates ide-build information for Android Studio. */ public class AndroidStudioInfoAspect implements ConfiguredNativeAspectFactory { public static final String NAME = "AndroidStudioInfoAspect"; // Output groups. public static final String IDE_INFO = "ide-info"; public static final String IDE_INFO_TEXT = "ide-info-text"; public static final String IDE_RESOLVE = "ide-resolve"; private static class PrerequisiteAttr { public final String name; public final Type type; public PrerequisiteAttr(String name, Type type) { this.name = name; this.type = type; } } public static final PrerequisiteAttr[] PREREQUISITE_ATTRS = { new PrerequisiteAttr("deps", BuildType.LABEL_LIST), new PrerequisiteAttr("exports", BuildType.LABEL_LIST), new PrerequisiteAttr("$robolectric", BuildType.LABEL_LIST), // From android_robolectric_test new PrerequisiteAttr("$junit", BuildType.LABEL), // From android_robolectric_test new PrerequisiteAttr("binary_under_test", BuildType.LABEL), // From android_test new PrerequisiteAttr("java_lib", BuildType.LABEL), // From proto_library new PrerequisiteAttr("$proto1_java_lib", BuildType.LABEL), // From proto_library new PrerequisiteAttr(":cc_toolchain", BuildType.LABEL), // from cc_* rules new PrerequisiteAttr("module_target", BuildType.LABEL) }; // File suffixes. public static final String ASWB_BUILD_SUFFIX = ".aswb-build"; public static final String ASWB_BUILD_TEXT_SUFFIX = ".aswb-build.txt"; public static final Function LABEL_TO_STRING = new Function() { @Nullable @Override public String apply(Label label) { return label.toString(); } }; @Override public AspectDefinition getDefinition(AspectParameters aspectParameters) { AspectDefinition.Builder builder = new AspectDefinition.Builder(NAME) .attributeAspect("runtime_deps", AndroidStudioInfoAspect.class) .attributeAspect("resources", AndroidStudioInfoAspect.class) .add(attr("$packageParser", LABEL).cfg(HOST).exec() .value(Label.parseAbsoluteUnchecked( Constants.TOOLS_REPOSITORY + "//tools/android:PackageParser"))); for (PrerequisiteAttr prerequisiteAttr : PREREQUISITE_ATTRS) { builder.attributeAspect(prerequisiteAttr.name, AndroidStudioInfoAspect.class); } return builder.build(); } @Override public ConfiguredAspect create( ConfiguredTarget base, RuleContext ruleContext, AspectParameters parameters) { ConfiguredAspect.Builder builder = new Builder(NAME, ruleContext); AndroidStudioInfoFilesProvider.Builder providerBuilder = new AndroidStudioInfoFilesProvider.Builder(); RuleIdeInfo.Kind ruleKind = getRuleKind(ruleContext.getRule(), base); DependenciesResult dependenciesResult = processDependencies( base, ruleContext, providerBuilder); AndroidStudioInfoFilesProvider provider = createIdeBuildArtifact( base, ruleContext, ruleKind, dependenciesResult, providerBuilder); builder .addOutputGroup(IDE_INFO, provider.getIdeInfoFiles()) .addOutputGroup(IDE_INFO_TEXT, provider.getIdeInfoTextFiles()) .addOutputGroup(IDE_RESOLVE, provider.getIdeResolveFiles()) .addProvider( AndroidStudioInfoFilesProvider.class, provider); return builder.build(); } private static class DependenciesResult { private DependenciesResult(Iterable