From f8c5520a20cdc31363ee7e37fce12f0e23adf39e Mon Sep 17 00:00:00 2001 From: kaipi Date: Wed, 4 Oct 2017 17:39:16 +0200 Subject: Remove support for ProtocolBuffers2. PiperOrigin-RevId: 171013687 --- .../build/lib/rules/objc/ObjcProtoAspect.java | 9 +- .../build/lib/rules/objc/ObjcProtoLibrary.java | 29 +-- .../build/lib/rules/objc/ObjcProtoLibraryRule.java | 81 ++------ .../build/lib/rules/objc/ProtoAttributes.java | 164 ++------------- .../build/lib/rules/objc/ProtobufSupport.java | 7 +- .../lib/rules/objc/ProtocolBuffers2Support.java | 228 --------------------- 6 files changed, 38 insertions(+), 480 deletions(-) delete mode 100644 src/main/java/com/google/devtools/build/lib/rules/objc/ProtocolBuffers2Support.java (limited to 'src/main/java/com/google/devtools/build/lib/rules') diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProtoAspect.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProtoAspect.java index 6a13ac18cc..5d74c1bf94 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProtoAspect.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProtoAspect.java @@ -62,11 +62,10 @@ public class ObjcProtoAspect extends NativeAspectClass implements ConfiguredAspe ProtoAttributes attributes = new ProtoAttributes(ruleContext); - // If the rule has the portable_proto_filters or uses_protobuf, it must be an objc_proto_library - // configured to use the third party protobuf library, in contrast with the PB2 internal - // library. Only the third party library is enabled to propagate the protos with this aspect. - // Validation for the correct target attributes is done in ProtoSupport.java. - if (attributes.requiresProtobuf()) { + // If this current target is an objc_proto_library, only then read the protos and portable + // filters it has configured in the attributes and add them to the ObjcProtoProvider.Builder + // instance. Validation for the correct target attributes is already done in ProtoSupport.java. + if (attributes.isObjcProtoLibrary()) { // Gather up all the dependency protos depended by this target. Iterable protoProviders = diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProtoLibrary.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProtoLibrary.java index 412968ece2..5a3f00553a 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProtoLibrary.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProtoLibrary.java @@ -31,18 +31,8 @@ public class ObjcProtoLibrary implements RuleConfiguredTargetFactory { @Override public ConfiguredTarget create(final RuleContext ruleContext) throws InterruptedException, RuleErrorException { - - ProtoAttributes attributes = new ProtoAttributes(ruleContext); - attributes.validate(); - - if (attributes.requiresProtobuf()) { - return createProtobufTarget(ruleContext); - } else { - ruleContext.ruleWarning("The usage of objc_proto_library without the portable_proto_filters " - + "attribute has been deprecated with a deadline to migrate set to June 30th. Please " - + "refer to b/37274743 for more information."); - return createProtocolBuffers2Target(ruleContext); - } + new ProtoAttributes(ruleContext).validate(); + return createProtobufTarget(ruleContext); } private ConfiguredTarget createProtobufTarget(RuleContext ruleContext) @@ -96,19 +86,4 @@ public class ObjcProtoLibrary implements RuleConfiguredTargetFactory { return portableProtoFilters.build(); } - - private ConfiguredTarget createProtocolBuffers2Target(RuleContext ruleContext) - throws InterruptedException, RuleErrorException { - NestedSetBuilder filesToBuild = NestedSetBuilder.stableOrder(); - - ProtocolBuffers2Support protoSupport = - new ProtocolBuffers2Support(ruleContext) - .registerGenerationActions() - .registerCompilationActions() - .addFilesToBuild(filesToBuild); - - return ObjcRuleClasses.ruleConfiguredTarget(ruleContext, filesToBuild.build()) - .addNativeDeclaredProvider(protoSupport.getObjcProvider()) - .build(); - } } diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProtoLibraryRule.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProtoLibraryRule.java index bddb0a9a85..5a209c878e 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProtoLibraryRule.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProtoLibraryRule.java @@ -28,8 +28,6 @@ import com.google.common.collect.ImmutableList; import com.google.devtools.build.lib.analysis.BaseRuleClasses; import com.google.devtools.build.lib.analysis.RuleDefinition; import com.google.devtools.build.lib.analysis.RuleDefinitionEnvironment; -import com.google.devtools.build.lib.packages.Attribute.ComputedDefault; -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.rules.apple.AppleConfiguration; @@ -40,12 +38,9 @@ import com.google.devtools.build.lib.util.FileType; /** * Rule definition for objc_proto_library. * - * This is a temporary rule until it is better known how to support proto_library rules. + *

This is a temporary rule until it is better known how to support proto_library rules. */ public class ObjcProtoLibraryRule implements RuleDefinition { - static final String OPTIONS_FILE_ATTR = "options_file"; - static final String USE_OBJC_HEADER_NAMES_ATTR = "use_objc_header_names"; - static final String PER_PROTO_INCLUDES_ATTR = "per_proto_includes"; static final String PORTABLE_PROTO_FILTERS_ATTR = "portable_proto_filters"; static final String USES_PROTOBUF_ATTR = "uses_protobuf"; @@ -54,9 +49,8 @@ public class ObjcProtoLibraryRule implements RuleDefinition { /** * Returns a newly built rule definition for objc_proto_library. * - * @param objcProtoAspect Aspect that traverses the dependency graph through the deps attribute - * to gather all proto files and portable filters depended by - * objc_proto_library targets using the new protobuf compiler/library. + * @param objcProtoAspect Aspect that traverses the dependency graph through the deps attribute to + * gather all proto files and portable filters depended by objc_proto_library targets. */ public ObjcProtoLibraryRule(ObjcProtoAspect objcProtoAspect) { this.objcProtoAspect = objcProtoAspect; @@ -68,33 +62,19 @@ public class ObjcProtoLibraryRule implements RuleDefinition { .requiresConfigurationFragments( CppConfiguration.class, ObjcConfiguration.class, AppleConfiguration.class) /* - The directly depended upon proto_library rules. + The directly depended upon proto_library and objc_proto_library rules. */ .override( attr("deps", LABEL_LIST) - // Support for files in deps is for backwards compatibility. - .allowedRuleClasses("proto_library", "filegroup", "objc_proto_library") + .allowedRuleClasses("proto_library", "objc_proto_library") .aspect(objcProtoAspect) .legacyAllowAnyFileType()) - /* - Optional options file to apply to protos which affects compilation (e.g. class - whitelist/blacklist settings). - */ - .add(attr(OPTIONS_FILE_ATTR, LABEL).legacyAllowAnyFileType().singleArtifact().cfg(HOST)) - /* - If true, output headers with .pbobjc.h, rather than .pb.h. - */ - .add(attr(USE_OBJC_HEADER_NAMES_ATTR, BOOLEAN).value(false)) - /* - If true, always add all directories to objc_library includes. - */ - .add(attr(PER_PROTO_INCLUDES_ATTR, BOOLEAN).value(false)) /* Whether to use the new protobuf compiler and runtime for this target. If you enable this option without passing portable_proto_filters, it will generate a filter file for all the protos that passed through proto_library targets as deps. */ - .add(attr(USES_PROTOBUF_ATTR, BOOLEAN).value(false)) + .add(attr(USES_PROTOBUF_ATTR, BOOLEAN).value(true)) /* List of portable proto filters to be passed on to the protobuf compiler. This attribute cannot be used together with the options_file, output_cpp, per_proto_includes and @@ -110,42 +90,16 @@ public class ObjcProtoLibraryRule implements RuleDefinition { .allowedFileTypes(FileType.of(".py"), FileType.of(".sh")) .cfg(HOST) .singleArtifact() - .value( - new ComputedDefault(PORTABLE_PROTO_FILTERS_ATTR, USES_PROTOBUF_ATTR) { - @Override - public Object getDefault(AttributeMap rule) { - return usesProtobuf(rule) - ? env.getToolsLabel("//tools/objc:protobuf_compiler_wrapper") - : env.getToolsLabel("//tools/objc:compile_protos"); - } - })) + .value(env.getToolsLabel("//tools/objc:protobuf_compiler_wrapper"))) .add( attr(PROTO_COMPILER_SUPPORT_ATTR, LABEL) .legacyAllowAnyFileType() .cfg(HOST) - .value( - new ComputedDefault(PORTABLE_PROTO_FILTERS_ATTR, USES_PROTOBUF_ATTR) { - @Override - public Object getDefault(AttributeMap rule) { - return usesProtobuf(rule) - ? env.getToolsLabel("//tools/objc:protobuf_compiler_support") - : env.getToolsLabel("//tools/objc:proto_support"); - } - })) + .value(env.getToolsLabel("//tools/objc:protobuf_compiler_support"))) .add( attr(PROTO_LIB_ATTR, LABEL) .allowedRuleClasses("objc_library") - .value( - new ComputedDefault(PORTABLE_PROTO_FILTERS_ATTR, USES_PROTOBUF_ATTR) { - @Override - public Object getDefault(AttributeMap rule) { - if (usesProtobuf(rule)) { - return env.getLabel("//external:objc_protobuf_lib"); - } else { - return env.getLabel("//external:objc_proto_lib"); - } - } - })) + .value(env.getToolsLabel("//tools/objc:protobuf_lib"))) .add( ProtoSourceFileBlacklist.blacklistFilegroupAttribute( PROTOBUF_WELL_KNOWN_TYPES, @@ -159,21 +113,18 @@ public class ObjcProtoLibraryRule implements RuleDefinition { return RuleDefinition.Metadata.builder() .name("objc_proto_library") .factoryClass(ObjcProtoLibrary.class) - .ancestors(BaseRuleClasses.RuleBase.class, ObjcRuleClasses.LibtoolRule.class, - ObjcRuleClasses.XcrunRule.class, ObjcRuleClasses.CrosstoolRule.class) + .ancestors( + BaseRuleClasses.RuleBase.class, + ObjcRuleClasses.LibtoolRule.class, + ObjcRuleClasses.XcrunRule.class, + ObjcRuleClasses.CrosstoolRule.class) .build(); } - - static boolean usesProtobuf(AttributeMap attributes) { - return attributes.isAttributeValueExplicitlySpecified( - ObjcProtoLibraryRule.PORTABLE_PROTO_FILTERS_ATTR) - || attributes.get(ObjcProtoLibraryRule.USES_PROTOBUF_ATTR, BOOLEAN); - } } /* -

This rule produces a static library from the given proto_library dependencies, after applying an -options file.

+

This rule generates ObjC headers for the proto files given through the proto_library and +objc_proto_library dependencies.

*/ diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ProtoAttributes.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ProtoAttributes.java index 890a37cb01..d525817d69 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/ProtoAttributes.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ProtoAttributes.java @@ -16,17 +16,13 @@ package com.google.devtools.build.lib.rules.objc; import static com.google.common.base.CaseFormat.LOWER_UNDERSCORE; import static com.google.common.base.CaseFormat.UPPER_CAMEL; -import static com.google.devtools.build.lib.packages.BuildType.LABEL; import static com.google.devtools.build.lib.packages.BuildType.LABEL_LIST; -import static com.google.devtools.build.lib.syntax.Type.BOOLEAN; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.CharMatcher; -import com.google.common.base.Optional; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import com.google.devtools.build.lib.actions.Artifact; -import com.google.devtools.build.lib.analysis.PrerequisiteArtifacts; import com.google.devtools.build.lib.analysis.RuleContext; import com.google.devtools.build.lib.analysis.TransitiveInfoCollection; import com.google.devtools.build.lib.analysis.configuredtargets.AbstractConfiguredTarget; @@ -36,8 +32,6 @@ import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; import com.google.devtools.build.lib.packages.RuleClass.ConfiguredTargetFactory.RuleErrorException; import com.google.devtools.build.lib.rules.proto.ProtoSourceFileBlacklist; import com.google.devtools.build.lib.rules.proto.ProtoSourcesProvider; -import com.google.devtools.build.lib.syntax.Type; -import com.google.devtools.build.lib.util.FileType; import java.util.ArrayList; /** Common rule attributes used by an objc_proto_library. */ @@ -50,44 +44,13 @@ final class ProtoAttributes { private static final ImmutableSet UPPERCASE_SEGMENTS = ImmutableSet.of("url", "http", "https"); - @VisibleForTesting - static final String FILES_NOT_ALLOWED_ERROR = - "Using files and filegroups in objc_proto_library with portable_proto_filters is not " - + "allowed. Please wrap the files inside a proto_library target."; - - @VisibleForTesting - static final String FILES_DEPRECATED_WARNING = - "Using files and filegroups in objc_proto_library is deprecated"; - - @VisibleForTesting - static final String NO_PROTOS_ERROR = - "no protos to compile - a non-empty deps attribute is required"; - - @VisibleForTesting - static final String PROTOBUF_ATTRIBUTES_NOT_EXCLUSIVE_ERROR = - "The portable_proto_filters and uses_protobuf attributes are incompatible with the " - + "options_file, output_cpp, per_proto_includes and use_objc_header_names attributes."; - @VisibleForTesting static final String PORTABLE_PROTO_FILTERS_EMPTY_ERROR = "The portable_proto_filters attribute can't be empty"; @VisibleForTesting - static final String OBJC_PROTO_LIB_DEP_IN_PROTOCOL_BUFFERS2_DEPS_ERROR = - "Protocol Buffers 2 objc_proto_library targets can't depend on other objc_proto_library " - + "targets. Please migrate your Protocol Buffers 2 objc_proto_library targets to use the " - + "portable_proto_filters attribute."; - - @VisibleForTesting - static final String PROTOCOL_BUFFERS2_IN_PROTOBUF_DEPS_ERROR = - "Protobuf objc_proto_library targets can't depend on Protocol Buffers 2 objc_proto_library " - + "targets. Please migrate your Protocol Buffers 2 objc_proto_library targets to use the " - + "portable_proto_filters attribute."; - - @VisibleForTesting - static final String USES_PROTOBUF_CANT_BE_SPECIFIED_AS_FALSE = - "objc_proto_library targets can't specify the uses_protobuf attribute to false when also " - + "specifying portable_proto_filters."; + static final String NO_PROTOS_ERROR = + "no protos to compile - a non-empty deps attribute is required"; private final RuleContext ruleContext; @@ -112,80 +75,21 @@ final class ProtoAttributes { * */ public void validate() throws RuleErrorException { - PrerequisiteArtifacts prerequisiteArtifacts = - ruleContext.getPrerequisiteArtifacts("deps", Mode.TARGET); - ImmutableList protoFiles = prerequisiteArtifacts.filter(FileType.of(".proto")).list(); - - if (hasPortableProtoFilters() - && ruleContext - .attributes() - .isAttributeValueExplicitlySpecified(ObjcProtoLibraryRule.USES_PROTOBUF_ATTR) - && !ruleContext.attributes().get(ObjcProtoLibraryRule.USES_PROTOBUF_ATTR, BOOLEAN)) { - ruleContext.throwWithAttributeError( - ObjcProtoLibraryRule.USES_PROTOBUF_ATTR, USES_PROTOBUF_CANT_BE_SPECIFIED_AS_FALSE); - } - - if (requiresProtobuf()) { - if (!protoFiles.isEmpty()) { - ruleContext.throwWithAttributeError("deps", FILES_NOT_ALLOWED_ERROR); - } - if (getProtoFiles().isEmpty() && !hasObjcProtoLibraryDependencies()) { - ruleContext.throwWithAttributeError("deps", NO_PROTOS_ERROR); - } - if (getPortableProtoFilters().isEmpty() && !usesProtobuf()) { - ruleContext.throwWithAttributeError( - ObjcProtoLibraryRule.PORTABLE_PROTO_FILTERS_ATTR, PORTABLE_PROTO_FILTERS_EMPTY_ERROR); - } - if (usesObjcHeaderNames() - || needsPerProtoIncludes() - || getOptionsFile().isPresent()) { - ruleContext.throwWithRuleError(PROTOBUF_ATTRIBUTES_NOT_EXCLUSIVE_ERROR); - } - if (hasPB2Dependencies()) { - ruleContext.throwWithAttributeError("deps", PROTOCOL_BUFFERS2_IN_PROTOBUF_DEPS_ERROR); - } - } else { - if (!protoFiles.isEmpty()) { - ruleContext.attributeWarning("deps", FILES_DEPRECATED_WARNING); - } - if (getProtoFiles().isEmpty()) { - ruleContext.throwWithAttributeError("deps", NO_PROTOS_ERROR); - } - if (hasObjcProtoLibraryDependencies()) { - ruleContext.throwWithAttributeError( - "deps", OBJC_PROTO_LIB_DEP_IN_PROTOCOL_BUFFERS2_DEPS_ERROR); - } - } - } - - /** Returns whether the generated header files should have be of type pb.h or pbobjc.h. */ - boolean usesObjcHeaderNames() { - if (ruleContext - .attributes() - .has(ObjcProtoLibraryRule.USE_OBJC_HEADER_NAMES_ATTR, Type.BOOLEAN)) { - return ruleContext - .attributes() - .get(ObjcProtoLibraryRule.USE_OBJC_HEADER_NAMES_ATTR, Type.BOOLEAN); + if (getProtoFiles().isEmpty() && !hasObjcProtoLibraryDependencies()) { + ruleContext.throwWithAttributeError("deps", NO_PROTOS_ERROR); } - return false; - } - - /** Returns whether the includes should include each of the proto generated headers. */ - boolean needsPerProtoIncludes() { - if (ruleContext.attributes().has(ObjcProtoLibraryRule.PER_PROTO_INCLUDES_ATTR, Type.BOOLEAN)) { - return ruleContext - .attributes() - .get(ObjcProtoLibraryRule.PER_PROTO_INCLUDES_ATTR, Type.BOOLEAN); + if (hasPortableProtoFilters() && getPortableProtoFilters().isEmpty()) { + ruleContext.throwWithAttributeError( + ObjcProtoLibraryRule.PORTABLE_PROTO_FILTERS_ATTR, PORTABLE_PROTO_FILTERS_EMPTY_ERROR); } - return false; } - /** Returns whether this target configures the uses_protobuf attribute. */ - boolean usesProtobuf() { - if (ruleContext.attributes().has(ObjcProtoLibraryRule.USES_PROTOBUF_ATTR, Type.BOOLEAN)) { - return ruleContext.attributes().get(ObjcProtoLibraryRule.USES_PROTOBUF_ATTR, Type.BOOLEAN); - } - return false; + /** + * Returns whether the target is an objc_proto_library. It does so by making sure that the + * portable_proto_filters attribute exists in this target's attributes (even if it's empty). + */ + boolean isObjcProtoLibrary() { + return ruleContext.attributes().has(ObjcProtoLibraryRule.PORTABLE_PROTO_FILTERS_ATTR); } /** Returns whether to use the protobuf library instead of the PB2 library. */ @@ -195,15 +99,6 @@ final class ProtoAttributes { .isAttributeValueExplicitlySpecified(ObjcProtoLibraryRule.PORTABLE_PROTO_FILTERS_ATTR); } - /** - * Returns whether the target requires the use of protobuf or not. This is a convenience method to - * check that either the {@code portable_proto_filters} or the {@code uses_protobuf} attributes - * were passed. - */ - boolean requiresProtobuf() { - return hasPortableProtoFilters() || usesProtobuf(); - } - /** Returns the list of portable proto filters. */ ImmutableList getPortableProtoFilters() { if (ruleContext @@ -223,19 +118,9 @@ final class ProtoAttributes { .list(); } - /** Returns the options file, or {@link Optional#absent} if it was not specified. */ - Optional getOptionsFile() { - if (ruleContext.attributes().has(ObjcProtoLibraryRule.OPTIONS_FILE_ATTR, LABEL)) { - return Optional.fromNullable( - ruleContext.getPrerequisiteArtifact(ObjcProtoLibraryRule.OPTIONS_FILE_ATTR, Mode.HOST)); - } - return Optional.absent(); - } - /** Returns the list of proto files to compile. */ NestedSet getProtoFiles() { return NestedSetBuilder.stableOrder() - .addAll(getProtoDepsFiles()) .addTransitive(getProtoDepsSources()) .build(); } @@ -353,25 +238,6 @@ final class ProtoAttributes { return artifacts.build(); } - /** - * Returns the list of proto files that were added directly into the deps attributes. This way of - * specifying the protos is deprecated, and displays a warning when the target does so. - */ - private ImmutableList getProtoDepsFiles() { - PrerequisiteArtifacts prerequisiteArtifacts = - ruleContext.getPrerequisiteArtifacts("deps", Mode.TARGET); - return prerequisiteArtifacts.filter(FileType.of(".proto")).list(); - } - - private boolean hasPB2Dependencies() { - for (TransitiveInfoCollection dep : ruleContext.getPrerequisites("deps", Mode.TARGET)) { - if (isObjcProtoLibrary(dep) && !hasProtobufProvider(dep)) { - return true; - } - } - return false; - } - private boolean hasObjcProtoLibraryDependencies() { for (TransitiveInfoCollection dep : ruleContext.getPrerequisites("deps", Mode.TARGET)) { if (isObjcProtoLibrary(dep)) { @@ -390,8 +256,4 @@ final class ProtoAttributes { return false; } } - - private boolean hasProtobufProvider(TransitiveInfoCollection dependency) { - return dependency.getProvider(ObjcProtoProvider.class) != null; - } } diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ProtobufSupport.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ProtobufSupport.java index 348890eda1..4c7bb87400 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/ProtobufSupport.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ProtobufSupport.java @@ -528,10 +528,9 @@ final class ProtobufSupport { } private boolean isLinkingTarget() { - // Since this is the ProtobufSupport helper class, check whether the current target has - // configured the protobuf attributes. If not, it's not an objc_proto_library rule, so it must - // be a linking rule (e.g. apple_binary). - return !attributes.requiresProtobuf(); + // Since this is the ProtobufSupport helper class, check whether the current target is + // an objc_proto_library. If not, it must be a linking rule (e.g. apple_binary). + return !attributes.isObjcProtoLibrary(); } /** diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ProtocolBuffers2Support.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ProtocolBuffers2Support.java deleted file mode 100644 index 1a4b2fbdb6..0000000000 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/ProtocolBuffers2Support.java +++ /dev/null @@ -1,228 +0,0 @@ -// Copyright 2016 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.objc; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Iterables; -import com.google.common.collect.Ordering; -import com.google.devtools.build.lib.actions.Artifact; -import com.google.devtools.build.lib.analysis.RuleContext; -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.configuredtargets.RuleConfiguredTarget.Mode; -import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; -import com.google.devtools.build.lib.packages.RuleClass.ConfiguredTargetFactory.RuleErrorException; -import com.google.devtools.build.lib.vfs.FileSystemUtils; -import com.google.devtools.build.lib.vfs.PathFragment; - -/** - * Support for generating Objective C proto static libraries that registers actions which generate - * and compile the Objective C protos by using the deprecated ProtocolBuffers2 library and compiler. - * - *

Methods on this class can be called in any order without impacting the result. - */ -final class ProtocolBuffers2Support { - - private static final String UNIQUE_DIRECTORY_NAME = "_generated_protos"; - - private final RuleContext ruleContext; - private final ProtoAttributes attributes; - - /** - * Creates a new proto support for the ProtocolBuffers2 library. - * - * @param ruleContext context this proto library is constructed in - */ - public ProtocolBuffers2Support(RuleContext ruleContext) { - this.ruleContext = ruleContext; - this.attributes = new ProtoAttributes(ruleContext); - } - - /** - * Register the proto generation actions. These actions generate the ObjC/CPP code to be compiled - * by this rule. - */ - public ProtocolBuffers2Support registerGenerationActions() throws InterruptedException { - ruleContext.registerAction( - FileWriteAction.create( - ruleContext, - getProtoInputsFile(), - getProtoInputsFileContents( - attributes.filterWellKnownProtos(attributes.getProtoFiles())), - false)); - - ruleContext.registerAction( - ObjcRuleClasses.spawnOnDarwinActionBuilder() - .setMnemonic("GenObjcPB2Protos") - .addInput(attributes.getProtoCompiler()) - .addInputs(attributes.getProtoCompilerSupport()) - .addInput(getProtoInputsFile()) - .addTransitiveInputs(attributes.getProtoFiles()) - .addInputs(attributes.getOptionsFile().asSet()) - .addOutputs(getGeneratedProtoOutputs(getHeaderExtension())) - .addOutputs(getGeneratedProtoOutputs(getSourceExtension())) - .setExecutable(PathFragment.create("/usr/bin/python")) - .addCommandLine(getGenerationCommandLine()) - .build(ruleContext)); - return this; - } - - /** - * Registers the actions that will compile the generated code. - */ - public ProtocolBuffers2Support registerCompilationActions() - throws RuleErrorException, InterruptedException { - CompilationSupport compilationSupport = - new CompilationSupport.Builder() - .setRuleContext(ruleContext) - .doNotUseDeps() - .doNotUsePch() - .build(); - - compilationSupport.registerCompileAndArchiveActions(getCommon()); - return this; - } - - /** Adds the generated files to the set of files to be output when this rule is built. */ - public ProtocolBuffers2Support addFilesToBuild(NestedSetBuilder filesToBuild) - throws InterruptedException { - filesToBuild - .addAll(getGeneratedProtoOutputs(getHeaderExtension())) - .addAll(getGeneratedProtoOutputs(getSourceExtension())) - .addAll(getCompilationArtifacts().getArchive().asSet()); - return this; - } - - /** Returns the ObjcProvider for this target. */ - public ObjcProvider getObjcProvider() { - return getCommon().getObjcProvider(); - } - - private String getHeaderExtension() { - return ".pb" + (attributes.usesObjcHeaderNames() ? "objc.h" : ".h"); - } - - private String getSourceExtension() { - return ".pb.m"; - } - - private ObjcCommon getCommon() { - return new ObjcCommon.Builder(ruleContext) - .setIntermediateArtifacts(new IntermediateArtifacts(ruleContext, "")) - .setHasModuleMap() - .setCompilationArtifacts(getCompilationArtifacts()) - .addIncludes(getIncludes()) - .addDepObjcProviders( - ruleContext.getPrerequisites( - ObjcRuleClasses.PROTO_LIB_ATTR, Mode.TARGET, ObjcProvider.SKYLARK_CONSTRUCTOR)) - .build(); - } - - private CompilationArtifacts getCompilationArtifacts() { - Iterable generatedSources = getGeneratedProtoOutputs(getSourceExtension()); - return new CompilationArtifacts.Builder() - .setIntermediateArtifacts(new IntermediateArtifacts(ruleContext, "")) - .addAdditionalHdrs(getGeneratedProtoOutputs(getHeaderExtension())) - .addAdditionalHdrs(generatedSources) - .addNonArcSrcs(generatedSources) - .build(); - } - - private Artifact getProtoInputsFile() { - return ruleContext.getUniqueDirectoryArtifact( - "_protos", "_proto_input_files", ruleContext.getConfiguration().getGenfilesDirectory()); - } - - private String getProtoInputsFileContents(Iterable outputProtos) { - // Sort the file names to make the remote action key independent of the precise deps structure. - // compile_protos.py will sort the input list anyway. - Iterable sorted = Ordering.natural().immutableSortedCopy(outputProtos); - return Artifact.joinExecPaths("\n", sorted); - } - - private CustomCommandLine getGenerationCommandLine() { - CustomCommandLine.Builder commandLineBuilder = - new CustomCommandLine.Builder() - .addExecPath(attributes.getProtoCompiler()) - .add("--input-file-list") - .addExecPath(getProtoInputsFile()) - .add("--output-dir") - .addDynamicString(getWorkspaceRelativeOutputDir().getSafePathString()) - .add("--working-dir") - .add("."); - - if (attributes.getOptionsFile().isPresent()) { - commandLineBuilder - .add("--compiler-options-path") - .addExecPath(attributes.getOptionsFile().get()); - } - - if (attributes.usesObjcHeaderNames()) { - commandLineBuilder.add("--use-objc-header-names"); - } - return commandLineBuilder.build(); - } - - public ImmutableSet getIncludes() { - ImmutableSet.Builder searchPathEntriesBuilder = - new ImmutableSet.Builder().add(getWorkspaceRelativeOutputDir()); - - if (attributes.needsPerProtoIncludes()) { - PathFragment generatedProtoDir = PathFragment.create( - getWorkspaceRelativeOutputDir(), ruleContext.getLabel().getPackageFragment()); - - searchPathEntriesBuilder - .add(generatedProtoDir) - .addAll( - Iterables.transform( - getGeneratedProtoOutputs(getHeaderExtension()), - input -> input.getExecPath().getParentDirectory())); - } - - return searchPathEntriesBuilder.build(); - } - - private PathFragment getWorkspaceRelativeOutputDir() { - // Generate sources in a package-and-rule-scoped directory; adds both the - // package-and-rule-scoped directory and the header-containing-directory to the include path - // of dependers. - PathFragment rootRelativeOutputDir = ruleContext.getUniqueDirectory(UNIQUE_DIRECTORY_NAME); - - return PathFragment.create( - ruleContext.getBinOrGenfilesDirectory().getExecPath(), rootRelativeOutputDir); - } - - private Iterable getGeneratedProtoOutputs(String extension) { - ImmutableList.Builder builder = new ImmutableList.Builder<>(); - for (Artifact protoFile : attributes.filterWellKnownProtos(attributes.getProtoFiles())) { - String protoFileName = FileSystemUtils.removeExtension(protoFile.getFilename()); - String generatedOutputName = attributes.getGeneratedProtoFilename(protoFileName, false); - - PathFragment generatedFilePath = PathFragment.create( - protoFile.getRootRelativePath().getParentDirectory(), - PathFragment.create(generatedOutputName)); - - PathFragment outputFile = FileSystemUtils.appendExtension(generatedFilePath, extension); - - if (outputFile != null) { - builder.add( - ruleContext.getUniqueDirectoryArtifact( - UNIQUE_DIRECTORY_NAME, outputFile, ruleContext.getBinOrGenfilesDirectory())); - } - } - return builder.build(); - } -} -- cgit v1.2.3