From 15a4362cabd1699f488e42377bde9b27ad8943d0 Mon Sep 17 00:00:00 2001 From: elenairina Date: Fri, 16 Feb 2018 08:07:42 -0800 Subject: Add "proto_source_root" flag to proto_library. Fixes #4544. RELNOTES: Add "proto_source_root" flag to proto_library. PiperOrigin-RevId: 185997723 --- .../build/lib/rules/cpp/proto/CcProtoAspect.java | 1 + .../lib/rules/java/proto/JavaLiteProtoAspect.java | 1 + .../lib/rules/java/proto/JavaProtoAspect.java | 1 + .../rules/java/proto/JavaProtoSkylarkCommon.java | 1 + .../build/lib/rules/proto/BazelProtoLibrary.java | 8 +++-- .../lib/rules/proto/BazelProtoLibraryRule.java | 6 ++++ .../build/lib/rules/proto/ProtoCommon.java | 39 ++++++++++++++++++++++ .../lib/rules/proto/ProtoCompileActionBuilder.java | 11 +++++- .../lib/rules/proto/ProtoSourcesProvider.java | 12 +++++-- .../build/lib/rules/proto/SupportData.java | 10 +++++- 10 files changed, 84 insertions(+), 6 deletions(-) (limited to 'src/main/java/com') diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/proto/CcProtoAspect.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/proto/CcProtoAspect.java index bce029f360..99f8e90ad4 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/proto/CcProtoAspect.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/proto/CcProtoAspect.java @@ -341,6 +341,7 @@ public abstract class CcProtoAspect extends NativeAspectClass implements Configu supportData.getDirectProtoSources(), supportData.getTransitiveImports(), supportData.getProtosInDirectDeps(), + supportData.getTransitiveProtoPathFlags(), ruleContext.getLabel(), outputs, "C++", diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaLiteProtoAspect.java b/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaLiteProtoAspect.java index 82accda1b0..6a2417de70 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaLiteProtoAspect.java +++ b/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaLiteProtoAspect.java @@ -246,6 +246,7 @@ public class JavaLiteProtoAspect extends NativeAspectClass implements Configured supportData.getDirectProtoSources(), supportData.getTransitiveImports(), supportData.getProtosInDirectDeps(), + supportData.getTransitiveProtoPathFlags(), ruleContext.getLabel(), ImmutableList.of(sourceJar), "JavaLite", diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaProtoAspect.java b/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaProtoAspect.java index e910ed86eb..82030e0643 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaProtoAspect.java +++ b/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaProtoAspect.java @@ -279,6 +279,7 @@ public class JavaProtoAspect extends NativeAspectClass implements ConfiguredAspe supportData.getDirectProtoSources(), supportData.getTransitiveImports(), supportData.getProtosInDirectDeps(), + supportData.getTransitiveProtoPathFlags(), ruleContext.getLabel(), ImmutableList.of(sourceJar), "Java (Immutable)", diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaProtoSkylarkCommon.java b/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaProtoSkylarkCommon.java index ce97d65ee1..08482be9e2 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaProtoSkylarkCommon.java +++ b/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaProtoSkylarkCommon.java @@ -85,6 +85,7 @@ public class JavaProtoSkylarkCommon { supportData.getDirectProtoSources(), supportData.getTransitiveImports(), supportData.getProtosInDirectDeps(), + supportData.getTransitiveProtoPathFlags(), skylarkRuleContext.getLabel(), ImmutableList.of(sourceJar), "JavaLite", diff --git a/src/main/java/com/google/devtools/build/lib/rules/proto/BazelProtoLibrary.java b/src/main/java/com/google/devtools/build/lib/rules/proto/BazelProtoLibrary.java index 15e0e5f82b..d1cd914016 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/proto/BazelProtoLibrary.java +++ b/src/main/java/com/google/devtools/build/lib/rules/proto/BazelProtoLibrary.java @@ -44,6 +44,7 @@ public class BazelProtoLibrary implements RuleConfiguredTargetFactory { NestedSet transitiveImports = ProtoCommon.collectTransitiveImports(ruleContext, protoSources); + NestedSet protoPathFlags = ProtoCommon.collectTransitiveProtoPathFlags(ruleContext); NestedSet protosInDirectDeps = ProtoCommon.computeProtosInDirectDeps(ruleContext); @@ -53,6 +54,7 @@ public class BazelProtoLibrary implements RuleConfiguredTargetFactory { protoSources, protosInDirectDeps, transitiveImports, + protoPathFlags, !protoSources.isEmpty()); Artifact descriptorSetOutput = @@ -71,7 +73,8 @@ public class BazelProtoLibrary implements RuleConfiguredTargetFactory { protosInDirectDeps, descriptorSetOutput, true /* allowServices */, - dependenciesDescriptorSets); + dependenciesDescriptorSets, + protoPathFlags); Runfiles dataRunfiles = ProtoCommon.createDataRunfilesProvider(transitiveImports, ruleContext) @@ -86,7 +89,8 @@ public class BazelProtoLibrary implements RuleConfiguredTargetFactory { protoSources, checkDepsProtoSources, descriptorSetOutput, - transitiveDescriptorSetOutput); + transitiveDescriptorSetOutput, + protoPathFlags); return new RuleConfiguredTargetBuilder(ruleContext) .setFilesToBuild(NestedSetBuilder.create(STABLE_ORDER, descriptorSetOutput)) diff --git a/src/main/java/com/google/devtools/build/lib/rules/proto/BazelProtoLibraryRule.java b/src/main/java/com/google/devtools/build/lib/rules/proto/BazelProtoLibraryRule.java index 557cf5fa15..3eab22ee77 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/proto/BazelProtoLibraryRule.java +++ b/src/main/java/com/google/devtools/build/lib/rules/proto/BazelProtoLibraryRule.java @@ -17,6 +17,7 @@ package com.google.devtools.build.lib.rules.proto; 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.syntax.Type.STRING; import com.google.devtools.build.lib.analysis.BaseRuleClasses; import com.google.devtools.build.lib.analysis.RuleDefinition; @@ -72,6 +73,11 @@ public final class BazelProtoLibraryRule implements RuleDefinition { attr("srcs", LABEL_LIST) .direct_compile_time_input() .allowedFileTypes(FileType.of(".proto"), FileType.of(".protodevel"))) + /* + Directory containing .proto files. If set, it must be equal to the package name. If not set, + the source root will be the workspace directory (default). + */ + .add(attr("proto_source_root", STRING)) .advertiseProvider(ProtoSourcesProvider.class, ProtoSupportDataProvider.class) .build(); } diff --git a/src/main/java/com/google/devtools/build/lib/rules/proto/ProtoCommon.java b/src/main/java/com/google/devtools/build/lib/rules/proto/ProtoCommon.java index a09a9afa62..374b534cd9 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/proto/ProtoCommon.java +++ b/src/main/java/com/google/devtools/build/lib/rules/proto/ProtoCommon.java @@ -30,6 +30,7 @@ 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.packages.BuildType; +import com.google.devtools.build.lib.syntax.Type; import com.google.devtools.build.lib.vfs.FileSystemUtils; import com.google.devtools.build.lib.vfs.PathFragment; import javax.annotation.Nullable; @@ -98,6 +99,44 @@ public class ProtoCommon { return result.build(); } + /** + * Returns all proto source roots in this lib and in its transitive dependencies, each prefixed + * by {@code --proto_path}. + * + * Build will fail if the {@code proto_source_root} of the current lib is different than the + * package name. + */ + public static NestedSet collectTransitiveProtoPathFlags(RuleContext ruleContext) { + NestedSetBuilder protoPathFlags = NestedSetBuilder.stableOrder(); + + // first add the protoSourceRoot of the current target, if any + String protoSourceRoot = + ruleContext.attributes().get("proto_source_root", Type.STRING); + if (protoSourceRoot != null && !protoSourceRoot.isEmpty()) { + checkProtoSourceRootIsTheSameAsPackage(protoSourceRoot, ruleContext); + protoPathFlags.add("--proto_path=" + protoSourceRoot); + } + + for (ProtoSourcesProvider provider : ruleContext.getPrerequisites( + "deps", Mode.TARGET, ProtoSourcesProvider.class)) { + protoPathFlags.addTransitive(provider.getTransitiveProtoPathFlags()); + } + + return protoPathFlags.build(); + } + + private static void checkProtoSourceRootIsTheSameAsPackage( + String protoSourceRoot, RuleContext ruleContext) { + if (!ruleContext.getLabel().getPackageName().equals(protoSourceRoot)) { + ruleContext.attributeError( + "proto_source_root", + "proto_source_root must be the same as the package name (" + + ruleContext.getLabel().getPackageName() + ")." + + " not '" + protoSourceRoot + "'." + ); + } + } + /** * Check that .proto files in sources are from the same package. This is done to avoid clashes * with the generated sources. diff --git a/src/main/java/com/google/devtools/build/lib/rules/proto/ProtoCompileActionBuilder.java b/src/main/java/com/google/devtools/build/lib/rules/proto/ProtoCompileActionBuilder.java index 639b07a032..a78fcd3e3f 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/proto/ProtoCompileActionBuilder.java +++ b/src/main/java/com/google/devtools/build/lib/rules/proto/ProtoCompileActionBuilder.java @@ -359,7 +359,8 @@ public class ProtoCompileActionBuilder { NestedSet protosInDirectDeps, Artifact output, boolean allowServices, - NestedSet transitiveDescriptorSets) { + NestedSet transitiveDescriptorSets, + NestedSet protoSourceRoots) { if (protosToCompile.isEmpty()) { ruleContext.registerAction( FileWriteAction.createEmptyWithInputs( @@ -374,6 +375,7 @@ public class ProtoCompileActionBuilder { protosToCompile, transitiveSources, protosInDirectDeps, + protoSourceRoots, ruleContext.getLabel(), ImmutableList.of(output), "Descriptor Set", @@ -420,6 +422,7 @@ public class ProtoCompileActionBuilder { Iterable protosToCompile, NestedSet transitiveSources, NestedSet protosInDirectDeps, + NestedSet protoSourceRoots, Label ruleLabel, Iterable outputs, String flavorName, @@ -431,6 +434,7 @@ public class ProtoCompileActionBuilder { protosToCompile, transitiveSources, protosInDirectDeps, + protoSourceRoots, ruleLabel, outputs, flavorName, @@ -447,6 +451,7 @@ public class ProtoCompileActionBuilder { Iterable protosToCompile, NestedSet transitiveSources, @Nullable NestedSet protosInDirectDeps, + NestedSet protoSourceRoots, Label ruleLabel, Iterable outputs, String flavorName, @@ -481,6 +486,7 @@ public class ProtoCompileActionBuilder { toolchainInvocations, protosToCompile, transitiveSources, + protoSourceRoots, areDepsStrict(ruleContext) ? protosInDirectDeps : null, ruleLabel, allowServices, @@ -517,6 +523,7 @@ public class ProtoCompileActionBuilder { List toolchainInvocations, Iterable protosToCompile, NestedSet transitiveSources, + NestedSet transitiveProtoPathFlags, @Nullable NestedSet protosInDirectDeps, Label ruleLabel, boolean allowServices, @@ -570,6 +577,8 @@ public class ProtoCompileActionBuilder { cmdLine.add("--disallow_services"); } + cmdLine.addAll(transitiveProtoPathFlags); + return cmdLine.build(); } diff --git a/src/main/java/com/google/devtools/build/lib/rules/proto/ProtoSourcesProvider.java b/src/main/java/com/google/devtools/build/lib/rules/proto/ProtoSourcesProvider.java index 1207ae0231..bf2ed12b3b 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/proto/ProtoSourcesProvider.java +++ b/src/main/java/com/google/devtools/build/lib/rules/proto/ProtoSourcesProvider.java @@ -41,14 +41,16 @@ public abstract class ProtoSourcesProvider implements TransitiveInfoProvider { ImmutableList protoSources, NestedSet checkDepsProtoSources, Artifact directDescriptorSet, - NestedSet transitiveDescriptorSets) { + NestedSet transitiveDescriptorSets, + NestedSet protoPathFlags) { return new AutoValue_ProtoSourcesProvider( transitiveImports, transitiveProtoSources, protoSources, checkDepsProtoSources, directDescriptorSet, - transitiveDescriptorSets); + transitiveDescriptorSets, + protoPathFlags); } /** @@ -127,5 +129,11 @@ public abstract class ProtoSourcesProvider implements TransitiveInfoProvider { ) public abstract NestedSet transitiveDescriptorSets(); + /** + * Directories of .proto sources collected from the transitive closure, each prefixed with + * {@code --proto_path}. These flags will be passed to {@code protoc} in the specified oreder. + */ + public abstract NestedSet getTransitiveProtoPathFlags(); + ProtoSourcesProvider() {} } diff --git a/src/main/java/com/google/devtools/build/lib/rules/proto/SupportData.java b/src/main/java/com/google/devtools/build/lib/rules/proto/SupportData.java index da35d13c34..9e02d190d5 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/proto/SupportData.java +++ b/src/main/java/com/google/devtools/build/lib/rules/proto/SupportData.java @@ -33,9 +33,11 @@ public abstract class SupportData { ImmutableList protoSources, NestedSet protosInDirectDeps, NestedSet transitiveImports, + NestedSet transitiveProtoPathFlags, boolean hasProtoSources) { return new AutoValue_SupportData( - nonWeakDepsPredicate, protoSources, transitiveImports, protosInDirectDeps, hasProtoSources); + nonWeakDepsPredicate, protoSources, transitiveImports, protosInDirectDeps, + transitiveProtoPathFlags, hasProtoSources); } public abstract Predicate getNonWeakDepsPredicate(); @@ -49,6 +51,12 @@ public abstract class SupportData { */ public abstract NestedSet getProtosInDirectDeps(); + /** + * Directories of .proto sources collected from the transitive closure, each prefixed with + * {@code --proto_path}. These flags will be passed to {@code protoc} in the specified oreder. + */ + public abstract NestedSet getTransitiveProtoPathFlags(); + public abstract boolean hasProtoSources(); SupportData() {} -- cgit v1.2.3