| // 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.rules.objc; |
| |
| 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 static com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.PROTOBUF_WELL_KNOWN_TYPES; |
| import static com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.PROTO_COMPILER_ATTR; |
| import static com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.PROTO_COMPILER_SUPPORT_ATTR; |
| import static com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.PROTO_LIB_ATTR; |
| import static com.google.devtools.build.lib.syntax.Type.BOOLEAN; |
| |
| 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; |
| import com.google.devtools.build.lib.rules.cpp.CppConfiguration; |
| import com.google.devtools.build.lib.rules.proto.ProtoSourceFileBlacklist; |
| 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. |
| */ |
| 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 XCODE_GEN_ATTR = "$xcodegen"; |
| |
| private final ObjcProtoAspect objcProtoAspect; |
| |
| /** |
| * 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. |
| */ |
| public ObjcProtoLibraryRule(ObjcProtoAspect objcProtoAspect) { |
| this.objcProtoAspect = objcProtoAspect; |
| } |
| |
| @Override |
| public RuleClass build(Builder builder, final RuleDefinitionEnvironment env) { |
| return builder |
| .requiresConfigurationFragments( |
| CppConfiguration.class, ObjcConfiguration.class, AppleConfiguration.class) |
| /* <!-- #BLAZE_RULE(objc_proto_library).ATTRIBUTE(deps) --> |
| The directly depended upon proto_library rules. |
| <!-- #END_BLAZE_RULE.ATTRIBUTE -->*/ |
| .override( |
| attr("deps", LABEL_LIST) |
| // Support for files in deps is for backwards compatibility. |
| .allowedRuleClasses("proto_library", "filegroup", "objc_proto_library") |
| .aspect(objcProtoAspect) |
| .legacyAllowAnyFileType()) |
| /* <!-- #BLAZE_RULE(objc_proto_library).ATTRIBUTE(options_file) --> |
| Optional options file to apply to protos which affects compilation (e.g. class |
| whitelist/blacklist settings). |
| <!-- #END_BLAZE_RULE.ATTRIBUTE -->*/ |
| .add(attr(OPTIONS_FILE_ATTR, LABEL).legacyAllowAnyFileType().singleArtifact().cfg(HOST)) |
| /* <!-- #BLAZE_RULE(objc_proto_library).ATTRIBUTE(use_objc_header_names) --> |
| If true, output headers with .pbobjc.h, rather than .pb.h. |
| <!-- #END_BLAZE_RULE.ATTRIBUTE -->*/ |
| .add(attr(USE_OBJC_HEADER_NAMES_ATTR, BOOLEAN).value(false)) |
| /* <!-- #BLAZE_RULE(objc_proto_library).ATTRIBUTE(per_proto_includes) --> |
| If true, always add all directories to objc_library includes. |
| <!-- #END_BLAZE_RULE.ATTRIBUTE -->*/ |
| .add(attr(PER_PROTO_INCLUDES_ATTR, BOOLEAN).value(false)) |
| /* <!-- #BLAZE_RULE(objc_proto_library).ATTRIBUTE(portable_proto_filters) --> |
| 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 |
| use_objc_header_names attributes. |
| <!-- #END_BLAZE_RULE.ATTRIBUTE -->*/ |
| .add( |
| attr(PORTABLE_PROTO_FILTERS_ATTR, LABEL_LIST) |
| .legacyAllowAnyFileType() |
| .allowedRuleClasses("filegroup") |
| .cfg(HOST)) |
| .add( |
| attr(PROTO_COMPILER_ATTR, LABEL) |
| .allowedFileTypes(FileType.of(".py"), FileType.of(".sh")) |
| .cfg(HOST) |
| .singleArtifact() |
| .value( |
| new ComputedDefault(PORTABLE_PROTO_FILTERS_ATTR) { |
| @Override |
| public Object getDefault(AttributeMap rule) { |
| return rule.isAttributeValueExplicitlySpecified(PORTABLE_PROTO_FILTERS_ATTR) |
| ? env.getToolsLabel("//tools/objc:protobuf_compiler_wrapper") |
| : env.getToolsLabel("//tools/objc:compile_protos"); |
| } |
| })) |
| .add( |
| attr(PROTO_COMPILER_SUPPORT_ATTR, LABEL) |
| .legacyAllowAnyFileType() |
| .cfg(HOST) |
| .value( |
| new ComputedDefault(PORTABLE_PROTO_FILTERS_ATTR) { |
| @Override |
| public Object getDefault(AttributeMap rule) { |
| return rule.isAttributeValueExplicitlySpecified(PORTABLE_PROTO_FILTERS_ATTR) |
| ? env.getToolsLabel("//tools/objc:protobuf_compiler_support") |
| : env.getToolsLabel("//tools/objc:proto_support"); |
| } |
| })) |
| .add( |
| attr(PROTO_LIB_ATTR, LABEL) |
| .allowedRuleClasses("objc_library") |
| .value( |
| new ComputedDefault(PORTABLE_PROTO_FILTERS_ATTR) { |
| @Override |
| public Object getDefault(AttributeMap rule) { |
| if (rule.isAttributeValueExplicitlySpecified(PORTABLE_PROTO_FILTERS_ATTR)) { |
| return env.getLabel("//external:objc_protobuf_lib"); |
| } else { |
| return env.getLabel("//external:objc_proto_lib"); |
| } |
| } |
| })) |
| .add( |
| ProtoSourceFileBlacklist.blacklistFilegroupAttribute( |
| PROTOBUF_WELL_KNOWN_TYPES, |
| ImmutableList.of(env.getToolsLabel("//tools/objc:protobuf_well_known_types")))) |
| .add( |
| attr(XCODE_GEN_ATTR, LABEL) |
| .cfg(HOST) |
| .exec() |
| .value(env.getToolsLabel("//tools/objc:xcodegen"))) |
| .build(); |
| } |
| |
| @Override |
| public Metadata getMetadata() { |
| return RuleDefinition.Metadata.builder() |
| .name("objc_proto_library") |
| .factoryClass(ObjcProtoLibrary.class) |
| .ancestors(BaseRuleClasses.RuleBase.class, ObjcRuleClasses.LibtoolRule.class, |
| ObjcRuleClasses.XcrunRule.class, ObjcRuleClasses.CrosstoolRule.class) |
| .build(); |
| } |
| } |
| |
| /*<!-- #BLAZE_RULE (NAME = objc_proto_library, TYPE = LIBRARY, FAMILY = Objective-C) --> |
| |
| <p>This rule produces a static library from the given proto_library dependencies, after applying an |
| options file.</p> |
| |
| <!-- #END_BLAZE_RULE -->*/ |