diff options
author | 2015-10-05 15:58:23 +0000 | |
---|---|---|
committer | 2015-10-06 07:03:20 +0000 | |
commit | 6817a6fcdd4275f9d3d4c3b9451a6c4144adcee1 (patch) | |
tree | 83a0a735ac0c48f777ed4a8ac06881262e2a2e50 /src/main/java/com | |
parent | 1c0543c626bf29eda95348c5c97391bc5d372fa3 (diff) |
Allow Java libraries to export and propagate proguard_specs.
It may be the case that a library used by Java clients is also used
by Android clients, but when used for the latter, it requires a particular
Proguard configuration. This change modifies Java library rules to accept
Proguard specs and pass them up to Android rules.
Note that this does not cause Proguard to be used on normal Java binaries.
RELNOTES[NEW]: java_library now supports the proguard_specs attribute for
passing Proguard configuration up to Android (not Java) binaries.
--
MOS_MIGRATED_REVID=104661799
Diffstat (limited to 'src/main/java/com')
11 files changed, 226 insertions, 73 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java index f85dbac1f1..c315c3cf3f 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java @@ -95,6 +95,7 @@ import com.google.devtools.build.lib.rules.java.JavaImportBaseRule; import com.google.devtools.build.lib.rules.java.JavaOptions; import com.google.devtools.build.lib.rules.java.JavaToolchainRule; import com.google.devtools.build.lib.rules.java.JvmConfigurationLoader; +import com.google.devtools.build.lib.rules.java.ProguardLibraryRule; import com.google.devtools.build.lib.rules.objc.ExperimentalIosTestRule; import com.google.devtools.build.lib.rules.objc.IosApplicationRule; import com.google.devtools.build.lib.rules.objc.IosDeviceRule; @@ -291,6 +292,7 @@ public class BazelRuleClassProvider { builder.addRuleDefinition(new BazelJavaRuleClasses.BaseJavaBinaryRule()); builder.addRuleDefinition(new BazelJavaRuleClasses.IjarBaseRule()); builder.addRuleDefinition(new BazelJavaRuleClasses.JavaBaseRule()); + builder.addRuleDefinition(new ProguardLibraryRule()); builder.addRuleDefinition(new JavaImportBaseRule()); builder.addRuleDefinition(new BazelJavaRuleClasses.JavaRule()); builder.addRuleDefinition(new BazelJavaBinaryRule()); diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/java/BazelJavaLibraryRule.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/java/BazelJavaLibraryRule.java index 8d48a68eca..4144d46f9f 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/rules/java/BazelJavaLibraryRule.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/java/BazelJavaLibraryRule.java @@ -30,6 +30,7 @@ import com.google.devtools.build.lib.rules.java.J2ObjcConfiguration; import com.google.devtools.build.lib.rules.java.JavaCompilationArgsProvider; import com.google.devtools.build.lib.rules.java.JavaConfiguration; import com.google.devtools.build.lib.rules.java.JavaSourceInfoProvider; +import com.google.devtools.build.lib.rules.java.ProguardLibraryRule; /** * Common attributes for Java rules. @@ -158,7 +159,7 @@ public final class BazelJavaLibraryRule implements RuleDefinition { public Metadata getMetadata() { return RuleDefinition.Metadata.builder() .name("java_library") - .ancestors(JavaRule.class) + .ancestors(JavaRule.class, ProguardLibraryRule.class) .factoryClass(BazelJavaLibrary.class) .build(); } 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 e5bac926f7..876d796fc8 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 @@ -59,6 +59,7 @@ import com.google.devtools.build.lib.rules.java.JavaCompilationArgsProvider; import com.google.devtools.build.lib.rules.java.JavaSemantics; import com.google.devtools.build.lib.rules.java.JavaSourceInfoProvider; import com.google.devtools.build.lib.rules.java.JavaTargetAttributes; +import com.google.devtools.build.lib.rules.java.ProguardSpecProvider; import com.google.devtools.build.lib.syntax.Type; import com.google.devtools.build.lib.vfs.PathFragment; 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 67156b0ba8..bb90189242 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 @@ -17,13 +17,11 @@ 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.analysis.ConfiguredTarget; -import com.google.devtools.build.lib.analysis.FilesToRunProvider; import com.google.devtools.build.lib.analysis.OutputGroupProvider; import com.google.devtools.build.lib.analysis.RuleConfiguredTarget.Mode; import com.google.devtools.build.lib.analysis.RuleConfiguredTargetBuilder; import com.google.devtools.build.lib.analysis.RuleContext; import com.google.devtools.build.lib.analysis.TransitiveInfoCollection; -import com.google.devtools.build.lib.analysis.actions.SpawnAction; import com.google.devtools.build.lib.analysis.config.CompilationMode; import com.google.devtools.build.lib.collect.nestedset.NestedSet; import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; @@ -39,10 +37,11 @@ import com.google.devtools.build.lib.rules.java.JavaSkylarkApiProvider; import com.google.devtools.build.lib.rules.java.JavaSourceInfoProvider; import com.google.devtools.build.lib.rules.java.JavaSourceJarsProvider; import com.google.devtools.build.lib.rules.java.JavaTargetAttributes; +import com.google.devtools.build.lib.rules.java.ProguardLibrary; +import com.google.devtools.build.lib.rules.java.ProguardSpecProvider; import com.google.devtools.build.lib.syntax.Type; import com.google.devtools.build.lib.vfs.PathFragment; -import java.util.Collection; import java.util.List; /** @@ -69,7 +68,7 @@ public abstract class AndroidLibrary implements RuleConfiguredTargetFactory { NestedSet<LinkerInput> transitiveNativeLibraries = AndroidCommon.collectTransitiveNativeLibraries(deps); NestedSet<Artifact> transitiveProguardConfigs = - collectTransitiveProguardConfigs(ruleContext); + new ProguardLibrary(ruleContext).collectProguardSpecs(); JavaCommon javaCommon = new JavaCommon(ruleContext, javaSemantics); AndroidCommon androidCommon = new AndroidCommon(ruleContext, javaCommon); @@ -238,46 +237,5 @@ public abstract class AndroidLibrary implements RuleConfiguredTargetFactory { } return builder; } - - private NestedSet<Artifact> collectTransitiveProguardConfigs(RuleContext ruleContext) { - NestedSetBuilder<Artifact> specsBuilder = NestedSetBuilder.naiveLinkOrder(); - - for (ProguardSpecProvider dep : ruleContext.getPrerequisites( - "deps", Mode.TARGET, ProguardSpecProvider.class)) { - specsBuilder.addTransitive(dep.getTransitiveProguardSpecs()); - } - - // Pass our local proguard configs through the validator, which checks a whitelist. - if (!getProguardConfigs(ruleContext).isEmpty()) { - FilesToRunProvider proguardWhitelister = ruleContext - .getExecutablePrerequisite("$proguard_whitelister", Mode.HOST); - for (Artifact specToValidate : getProguardConfigs(ruleContext)) { - //If we're validating j/a/b/testapp/proguard.cfg, the output will be: - //j/a/b/testapp/proguard.cfg_valid - Artifact output = ruleContext.getUniqueDirectoryArtifact( - "validated_proguard", - specToValidate.getRootRelativePath().replaceName( - specToValidate.getFilename() + "_valid"), - ruleContext.getBinOrGenfilesDirectory()); - ruleContext.registerAction(new SpawnAction.Builder() - .addInput(specToValidate) - .setExecutable(proguardWhitelister) - .setProgressMessage("Validating proguard configuration") - .setMnemonic("ValidateProguard") - .addArgument("--path") - .addArgument(specToValidate.getExecPathString()) - .addArgument("--output") - .addArgument(output.getExecPathString()) - .addOutput(output) - .build(ruleContext)); - specsBuilder.add(output); - } - } - return specsBuilder.build(); - } - - private Collection<Artifact> getProguardConfigs(RuleContext ruleContext) { - return ruleContext.getPrerequisiteArtifacts("proguard_specs", Mode.TARGET).list(); - } } diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLibraryBaseRule.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLibraryBaseRule.java index 381f684fc3..326a97ebb1 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLibraryBaseRule.java +++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLibraryBaseRule.java @@ -20,11 +20,8 @@ import static com.google.devtools.build.lib.packages.BuildType.LABEL_LIST; import static com.google.devtools.build.lib.syntax.Type.BOOLEAN; import static com.google.devtools.build.lib.syntax.Type.STRING; -import com.google.devtools.build.lib.Constants; import com.google.devtools.build.lib.analysis.RuleDefinition; import com.google.devtools.build.lib.analysis.RuleDefinitionEnvironment; -import com.google.devtools.build.lib.packages.Attribute; -import com.google.devtools.build.lib.packages.AttributeMap; import com.google.devtools.build.lib.packages.RuleClass; import com.google.devtools.build.lib.packages.RuleClass.Builder.RuleClassType; import com.google.devtools.build.lib.rules.android.AndroidRuleClasses.AndroidAaptBaseRule; @@ -32,6 +29,7 @@ import com.google.devtools.build.lib.rules.android.AndroidRuleClasses.AndroidBas import com.google.devtools.build.lib.rules.android.AndroidRuleClasses.AndroidResourceSupportRule; import com.google.devtools.build.lib.rules.java.JavaCompilationArgsProvider; import com.google.devtools.build.lib.rules.java.JavaSemantics; +import com.google.devtools.build.lib.rules.java.ProguardLibraryRule; /** * Rule definition for the android_library rule. @@ -125,26 +123,6 @@ public final class AndroidLibraryBaseRule implements RuleDefinition { <!-- #END_BLAZE_RULE.ATTRIBUTE --> */ .add(attr("idl_parcelables", LABEL_LIST).direct_compile_time_input() .allowedFileTypes(AndroidRuleClasses.ANDROID_IDL)) - /* <!-- #BLAZE_RULE(android_library).ATTRIBUTE(proguard_specs) --> - Files to be used as Proguard specification. - ${SYNOPSIS} - These will describe the set of specifications to be used by Proguard. If specified, - they will be added to any <code>android_binary</code> target depending on this library. - - The files included here must only have idempotent rules, namely -dontnote, -dontwarn, - assumenosideeffects, and rules that start with -keep. Other options can only appear in - <code>android_binary</code>'s proguard_specs, to ensure non-tautological merges. - <!-- #END_BLAZE_RULE.ATTRIBUTE --> */ - .add(attr("proguard_specs", LABEL_LIST).legacyAllowAnyFileType()) - .add(attr("$proguard_whitelister", LABEL).cfg(HOST).exec().value( - new Attribute.ComputedDefault() { - @Override - public Object getDefault(AttributeMap rule) { - return rule.isAttributeValueExplicitlySpecified("proguard_specs") - ? env.getLabel(Constants.ANDROID_DEP_PREFIX + "proguard_whitelister") - : null; - } - })) .add(attr("$android_manifest_merge_tool", LABEL).cfg(HOST).exec().value(env.getLabel( AndroidRuleClasses.MANIFEST_MERGE_TOOL_LABEL))) .advertiseProvider(JavaCompilationArgsProvider.class) @@ -159,7 +137,8 @@ public final class AndroidLibraryBaseRule implements RuleDefinition { .ancestors( AndroidBaseRule.class, AndroidAaptBaseRule.class, - AndroidResourceSupportRule.class) + AndroidResourceSupportRule.class, + ProguardLibraryRule.class) .build(); } } diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaImport.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaImport.java index e70e4d08f6..88fe0d108a 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaImport.java +++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaImport.java @@ -19,6 +19,7 @@ import com.google.common.collect.ImmutableMap; 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.OutputGroupProvider; import com.google.devtools.build.lib.analysis.RuleConfiguredTarget.Mode; import com.google.devtools.build.lib.analysis.RuleConfiguredTargetBuilder; import com.google.devtools.build.lib.analysis.RuleContext; @@ -133,6 +134,8 @@ public class JavaImport implements RuleConfiguredTargetFactory { .setSourceJarsForJarFiles(srcJars) .build(); + NestedSet<Artifact> proguardSpecs = new ProguardLibrary(ruleContext).collectProguardSpecs(); + common.addTransitiveInfoProviders(ruleBuilder, filesToBuild, null); return ruleBuilder .setFilesToBuild(filesToBuild) @@ -150,7 +153,9 @@ public class JavaImport implements RuleConfiguredTargetFactory { .add(JavaSourceInfoProvider.class, javaSourceInfoProvider) .add(JavaSourceJarsProvider.class, new JavaSourceJarsProvider( transitiveJavaSourceJars, srcJars)) + .add(ProguardSpecProvider.class, new ProguardSpecProvider(proguardSpecs)) .addOutputGroup(JavaSemantics.SOURCE_JARS_OUTPUT_GROUP, transitiveJavaSourceJars) + .addOutputGroup(OutputGroupProvider.HIDDEN_TOP_LEVEL, proguardSpecs) .build(); } diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaImportBaseRule.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaImportBaseRule.java index be6211e25a..eae756a8f7 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaImportBaseRule.java +++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaImportBaseRule.java @@ -84,7 +84,7 @@ public class JavaImportBaseRule implements RuleDefinition { return RuleDefinition.Metadata.builder() .name("$java_import_base") .type(RuleClassType.ABSTRACT) - .ancestors(BaseRuleClasses.RuleBase.class) + .ancestors(BaseRuleClasses.RuleBase.class, ProguardLibraryRule.class) .build(); } } diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaLibrary.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaLibrary.java index 51ca2fdeb3..38b3b697a3 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaLibrary.java +++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaLibrary.java @@ -18,6 +18,7 @@ import com.google.common.collect.ImmutableMap; 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.OutputGroupProvider; import com.google.devtools.build.lib.analysis.RuleConfiguredTarget.Mode; import com.google.devtools.build.lib.analysis.RuleConfiguredTargetBuilder; import com.google.devtools.build.lib.analysis.RuleContext; @@ -225,6 +226,8 @@ public class JavaLibrary implements RuleConfiguredTargetFactory { common.addTransitiveInfoProviders(builder, filesToBuild, classJar); common.addGenJarsProvider(builder, genClassJar, genSourceJar); + NestedSet<Artifact> proguardSpecs = new ProguardLibrary(ruleContext).collectProguardSpecs(); + builder .add(JavaRuleOutputJarsProvider.class, new JavaRuleOutputJarsProvider( classJar, iJar, srcJar)) @@ -248,7 +251,9 @@ public class JavaLibrary implements RuleConfiguredTargetFactory { // TODO(bazel-team): this should only happen for java_plugin .add(JavaPluginInfoProvider.class, new JavaPluginInfoProvider( exportedProcessorClasses, exportedProcessorClasspath)) - .addOutputGroup(JavaSemantics.SOURCE_JARS_OUTPUT_GROUP, transitiveSourceJars); + .add(ProguardSpecProvider.class, new ProguardSpecProvider(proguardSpecs)) + .addOutputGroup(JavaSemantics.SOURCE_JARS_OUTPUT_GROUP, transitiveSourceJars) + .addOutputGroup(OutputGroupProvider.HIDDEN_TOP_LEVEL, proguardSpecs); if (ruleContext.hasErrors()) { return null; diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/ProguardLibrary.java b/src/main/java/com/google/devtools/build/lib/rules/java/ProguardLibrary.java new file mode 100644 index 0000000000..f7e7f6cee7 --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/rules/java/ProguardLibrary.java @@ -0,0 +1,134 @@ +// 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.java; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMultimap; +import com.google.devtools.build.lib.actions.Artifact; +import com.google.devtools.build.lib.analysis.FilesToRunProvider; +import com.google.devtools.build.lib.analysis.RuleConfiguredTarget.Mode; +import com.google.devtools.build.lib.analysis.RuleContext; +import com.google.devtools.build.lib.analysis.actions.SpawnAction; +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.BuildType; + +import java.util.Collection; +import java.util.Map.Entry; + +/** + * Helpers for implementing rules which export Proguard specs. + * + * <p>This is not a ConfiguredTargetFactory; $proguard_library, which this class implements, is an + * abstract rule class, and simply contributes this functionality to other rules. + */ +public final class ProguardLibrary { + + private static final String LOCAL_SPEC_ATTRIBUTE = "proguard_specs"; + private static final ImmutableMultimap<Mode, String> DEPENDENCY_ATTRIBUTES = + ImmutableMultimap.<Mode, String>builder() + .putAll(Mode.TARGET, "deps", "exports", "runtime_deps") + .putAll(Mode.HOST, "plugins", "exported_plugins") + .build(); + + private final RuleContext ruleContext; + + /** + * Creates a new ProguardLibrary wrapping the given RuleContext. + */ + public ProguardLibrary(RuleContext ruleContext) { + this.ruleContext = ruleContext; + } + + /** + * Collects the validated proguard specs exported by this rule and its dependencies. + */ + public NestedSet<Artifact> collectProguardSpecs() { + NestedSetBuilder<Artifact> specsBuilder = NestedSetBuilder.naiveLinkOrder(); + + for (Entry<Mode, String> attribute : DEPENDENCY_ATTRIBUTES.entries()) { + specsBuilder.addTransitive( + collectProguardSpecsFromAttribute(attribute.getValue(), attribute.getKey())); + } + + Collection<Artifact> localSpecs = collectLocalProguardSpecs(); + if (!localSpecs.isEmpty()) { + // Pass our local proguard configs through the validator, which checks a whitelist. + FilesToRunProvider proguardWhitelister = + ruleContext.getExecutablePrerequisite("$proguard_whitelister", Mode.HOST); + for (Artifact specToValidate : localSpecs) { + specsBuilder.add(validateProguardSpec(proguardWhitelister, specToValidate)); + } + } + + return specsBuilder.build(); + } + + /** + * Collects the unvalidated proguard specs exported by this rule. + */ + private Collection<Artifact> collectLocalProguardSpecs() { + if (!ruleContext.getRule().isAttrDefined(LOCAL_SPEC_ATTRIBUTE, BuildType.LABEL_LIST)) { + return ImmutableList.of(); + } + return ruleContext.getPrerequisiteArtifacts(LOCAL_SPEC_ATTRIBUTE, Mode.TARGET).list(); + } + + /** + * Collects the proguard specs exported by dependencies on the given LABEL_LIST attribute. + */ + private NestedSet<Artifact> collectProguardSpecsFromAttribute(String attribute, Mode mode) { + if (!ruleContext.getRule().isAttrDefined(attribute, BuildType.LABEL_LIST)) { + return NestedSetBuilder.emptySet(Order.NAIVE_LINK_ORDER); + } + NestedSetBuilder<Artifact> dependencySpecsBuilder = NestedSetBuilder.naiveLinkOrder(); + for (ProguardSpecProvider provider : + ruleContext.getPrerequisites(attribute, mode, ProguardSpecProvider.class)) { + dependencySpecsBuilder.addTransitive(provider.getTransitiveProguardSpecs()); + } + return dependencySpecsBuilder.build(); + } + + /** + * Creates an action to run the Proguard whitelister over the given Proguard spec and returns the + * validated Proguard spec, ready to be exported. + */ + private Artifact validateProguardSpec( + FilesToRunProvider proguardWhitelister, Artifact specToValidate) { + // If we're validating j/a/b/testapp/proguard.cfg, the output will be: + // j/a/b/testapp/proguard.cfg_valid + Artifact output = + ruleContext.getUniqueDirectoryArtifact( + "validated_proguard", + specToValidate + .getRootRelativePath() + .replaceName(specToValidate.getFilename() + "_valid"), + ruleContext.getBinOrGenfilesDirectory()); + ruleContext.registerAction( + new SpawnAction.Builder() + .addInput(specToValidate) + .setExecutable(proguardWhitelister) + .setProgressMessage("Validating proguard configuration") + .setMnemonic("ValidateProguard") + .addArgument("--path") + .addArgument(specToValidate.getExecPathString()) + .addArgument("--output") + .addArgument(output.getExecPathString()) + .addOutput(output) + .build(ruleContext)); + return output; + } +} diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/ProguardLibraryRule.java b/src/main/java/com/google/devtools/build/lib/rules/java/ProguardLibraryRule.java new file mode 100644 index 0000000000..74d84eb198 --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/rules/java/ProguardLibraryRule.java @@ -0,0 +1,68 @@ +// 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.java; + +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 static com.google.devtools.build.lib.packages.BuildType.LABEL_LIST; + +import com.google.devtools.build.lib.analysis.RuleDefinition; +import com.google.devtools.build.lib.analysis.RuleDefinitionEnvironment; +import com.google.devtools.build.lib.packages.Attribute; +import com.google.devtools.build.lib.packages.AttributeMap; +import com.google.devtools.build.lib.packages.RuleClass; +import com.google.devtools.build.lib.packages.RuleClass.Builder; +import com.google.devtools.build.lib.packages.RuleClass.Builder.RuleClassType; + +/** + * A base rule for libraries which can provide proguard specs. + */ +public final class ProguardLibraryRule implements RuleDefinition { + + @Override + public RuleClass build(Builder builder, final RuleDefinitionEnvironment environment) { + return builder + /* <!-- #BLAZE_RULE($proguard_library).ATTRIBUTE(proguard_specs) --> + Files to be used as Proguard specification. + ${SYNOPSIS} + These will describe the set of specifications to be used by Proguard. If specified, + they will be added to any <code>android_binary</code> target depending on this library. + + The files included here must only have idempotent rules, namely -dontnote, -dontwarn, + assumenosideeffects, and rules that start with -keep. Other options can only appear in + <code>android_binary</code>'s proguard_specs, to ensure non-tautological merges. + <!-- #END_BLAZE_RULE.ATTRIBUTE --> */ + .add(attr("proguard_specs", LABEL_LIST).legacyAllowAnyFileType()) + .add(attr("$proguard_whitelister", LABEL).cfg(HOST).exec().value( + new Attribute.ComputedDefault() { + @Override + public Object getDefault(AttributeMap rule) { + return rule.isAttributeValueExplicitlySpecified("proguard_specs") + ? environment.getLabel("//tools/jdk:proguard_whitelister") + : null; + } + })) + .build(); + } + + @Override + public Metadata getMetadata() { + return RuleDefinition.Metadata.builder() + .name("$proguard_library") + .type(RuleClassType.ABSTRACT) + .build(); + } +} diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/ProguardSpecProvider.java b/src/main/java/com/google/devtools/build/lib/rules/java/ProguardSpecProvider.java index b815d1275c..afde15c724 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/android/ProguardSpecProvider.java +++ b/src/main/java/com/google/devtools/build/lib/rules/java/ProguardSpecProvider.java @@ -11,7 +11,7 @@ // 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; +package com.google.devtools.build.lib.rules.java; import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.analysis.TransitiveInfoProvider; |