@@ -78,7 +78,7 @@ def protoc_genrule(name,
7878
7979 invoke ("build_generated_filenames" , lang , self )
8080 invoke ("build_tools" , lang , self )
81- invoke ("build_imports " , lang , self )
81+ invoke ("build_paths " , lang , self )
8282 invoke ("build_protobuf_invocation" , lang , self )
8383 invoke ("build_protobuf_out" , lang , self )
8484 if with_grpc :
@@ -96,20 +96,11 @@ def protoc_genrule(name,
9696 return struct (** self )
9797
9898
99- def _get_path (ctx , path ):
100- if ctx .label .workspace_root :
101- return ctx .label .workspace_root + '/' + path
102- else :
103- return path
104-
105-
10699def _get_gendir (ctx ):
107100 if ctx .attr .output_to_genfiles :
108- outdir = ctx .var ["GENDIR" ]
101+ return ctx .var ["GENDIR" ]
109102 else :
110- outdir = ctx .var ["BINDIR" ]
111-
112- return outdir + "/" + ctx .label .package
103+ return ctx .var ["BINDIR" ]
113104
114105
115106def _execute_rule (self ):
@@ -118,13 +109,16 @@ def _execute_rule(self):
118109 fail ("Bazel context required for rule execution" )
119110
120111 srcfiles = []
121- for src in self ["srcs " ]:
122- srcfiles += [src . path ]
123-
112+ for src in self ["srcfilenames " ]:
113+ srcfiles += [src ]
114+ #srcfiles += [src.path]
124115
125116 #self["args"] += ["--descriptor_set_out=%s" % (descriptor_set_file.path)]
126117
127- arguments = list (set (self ["args" ] + ["-I" + i for i in self ["imports" ]] + srcfiles ))
118+ arglist = list (set (self ["args" ]))
119+ pathlist = ["--proto_path=" + i for i in set (self ["paths" ])]
120+
121+ arguments = arglist + pathlist + srcfiles
128122 inputs = list (set (self ["requires" ]))
129123 outputs = list (set (self ["provides" ] + ctx .outputs .outs ))
130124
@@ -166,22 +160,33 @@ def _build_source_files(ctx, self):
166160 arguments = [srcfile .path , protofile .path ],
167161 command = "cp $1 $2" )
168162 self ["srcs" ] += [protofile ]
169- self ["imports " ] += [protofile . dirname ]
163+ self ["srcfilenames " ] += [srcfile . short_path ]
170164 else :
171165 if self ["verbose" ]:
172166 print ("No Copy source files." )
173167 for srcfile in ctx .files .protos :
174168 self ["srcs" ] += [srcfile ]
175- self ["imports" ] += [srcfile .dirname ]
169+ self ["srcfilenames" ] += [srcfile .short_path ]
170+
171+ # This is the key to enable imports: protoc can see the entire
172+ # source tree from the workspace root.
173+ self ["paths" ] += ["." ]
176174
177175def _protoc_rule_impl (ctx ):
178176
177+ gendir = _get_gendir (ctx )
178+ outdir = gendir
179+ #outdir = gendir + "/" + ctx.label.package
180+
179181 self = {
180182 "ctx" : ctx ,
181- "gendir" : _get_gendir (ctx ),
183+ "gendir" : gendir ,
184+ "outdir" : outdir ,
182185 "imports" : [],
186+ "paths" : [],
183187 "args" : [],
184188 "srcs" : [],
189+ "srcfilenames" : [],
185190 "requires" : [],
186191 "copy_protos_to_genfiles" : getattr (ctx .attr , "copy_protos_to_genfiles" , False ),
187192 "provides" : [],
@@ -192,11 +197,12 @@ def _protoc_rule_impl(ctx):
192197
193198 # Propogate proto deps: TODO: this is completely untested.
194199 for dep in ctx .attr .deps :
195- self ["imports" ] += dep .proto .imports
196- self ["requires" ] += dep .proto .deps
197- self ["srcs" ] += dep .proto .srcs
200+ if hasattr (dep , "proto" ):
201+ self ["paths" ] += dep .proto .paths
202+ self ["requires" ] += dep .proto .deps
203+ self ["srcs" ] += dep .proto .srcs
198204
199- # Copy source files over to gendir
205+ # Copy source files over to outdir
200206 _build_source_files (ctx , self )
201207
202208 # Make a list of languages that were specified for this run
@@ -211,6 +217,7 @@ def _protoc_rule_impl(ctx):
211217
212218 invoke ("build_generated_files" , lang , self )
213219 invoke ("build_imports" , lang , self )
220+ invoke ("build_paths" , lang , self )
214221 invoke ("build_protobuf_invocation" , lang , self )
215222 invoke ("build_protobuf_out" , lang , self )
216223 if self ["with_grpc" ]:
@@ -230,6 +237,7 @@ def _protoc_rule_impl(ctx):
230237 proto = struct (
231238 srcs = set (self ["srcs" ]),
232239 imports = self ["imports" ],
240+ paths = self ["paths" ],
233241 deps = self ["requires" ],
234242 ),
235243 )
@@ -254,11 +262,21 @@ def implement(spec):
254262
255263 # ? How to deps interact here? Don't understand this. Provider
256264 # aspect is "proto".
257- attrs ["deps" ] = attr .label_list (providers = ["proto" ])
258-
259- # Additional include options to protoc. These should be
260- # directories. TODO(user): should this be typed as directory only?
261- attrs ["imports" ] = attr .string_list ()
265+ #attrs["deps"] = attr.label_list(providers = ["proto"])
266+ attrs ["deps" ] = attr .label_list ()
267+
268+ # Options to be passed to protoc as --proto_path. Differs from
269+ # imports in that these are raw strings rather than labels.
270+ attrs ["paths" ] = attr .string_list ()
271+
272+ # Protos that should be made available for proto imports. These are
273+ # not added as options but rather copied over to the sandbox where
274+ # protoc is run, making them available for import. TODO: is this
275+ # really needed? Test it by using the descriptor protos from
276+ # google/protobuf.
277+ attrs ["imports" ] = attr .label_list (
278+ allow_files = FileType ([".proto" ]),
279+ )
262280
263281 # The list of files the rule generates. How is this actually being
264282 # used?
@@ -281,10 +299,9 @@ def implement(spec):
281299 # Generate the descriptor? Shouldn't we just always generate this?
282300 #attrs["with_descriptor"] = attr.bool()
283301
284- # Implemntation detail that varies between output languages. JAVA:
285- # does not matter.
302+ # Implementation detail that varies between output languages.
286303 attrs ["copy_protos_to_genfiles" ] = attr .bool (
287- default = True ,
304+ default = False ,
288305 )
289306
290307 # Flag that sets gen_grpc_{lang} to true for all languages.
0 commit comments