@@ -117,14 +117,17 @@ cd $0.runfiles
117117 output = ctx .outputs .executable ,
118118 content = content )
119119
120- def _collect_comp_run_jars (ctx ):
121- compile_jars = set () # not transitive
122- runtime_jars = set () # this is transitive
123- for target in ctx .attr .deps :
120+ def _collect_jars (targets ):
121+ """Compute the runtime and compile-time dependencies from the given targets"""
122+ compile_jars = set () # not transitive
123+ runtime_jars = set () # this is transitive
124+ for target in targets :
124125 found = False
125126 if hasattr (target , "scala" ):
126127 compile_jars += [target .scala .outputs .ijar ]
128+ compile_jars += target .scala .transitive_compile_exports
127129 runtime_jars += target .scala .transitive_runtime_deps
130+ runtime_jars += target .scala .transitive_runtime_exports
128131 found = True
129132 if hasattr (target , "java" ):
130133 # see JavaSkylarkApiProvider.java, this is just the compile-time deps
@@ -137,43 +140,47 @@ def _collect_comp_run_jars(ctx):
137140 # support http_file pointed at a jar. http_jar uses ijar, which breaks scala macros
138141 runtime_jars += target .files
139142 compile_jars += target .files
140- return ( compile_jars , runtime_jars )
143+ return struct ( compiletime = compile_jars , runtime = runtime_jars )
141144
142- def _scala_library_impl (ctx ):
143- (cjars , rjars ) = _collect_comp_run_jars (ctx )
145+ def _lib (ctx , use_ijar ):
146+ jars = _collect_jars (ctx .attr .deps )
147+ (cjars , rjars ) = (jars .compiletime , jars .runtime )
144148 _write_manifest (ctx )
145- _compile (ctx , cjars , True )
149+ _compile (ctx , cjars , use_ijar )
146150
147151 rjars += [ctx .outputs .jar ]
148- scalaattr = struct (outputs = struct (ijar = ctx .outputs .ijar , class_jar = ctx .outputs .jar ),
149- transitive_runtime_deps = rjars )
150- runfiles = ctx .runfiles (
151- files = list (rjars ),
152- collect_data = True )
153- return struct (
154- scala = scalaattr ,
155- runfiles = runfiles )
152+ rjars += _collect_jars (ctx .attr .runtime_deps ).runtime
156153
157- def _scala_macro_library_impl (ctx ):
158- (cjars , rjars ) = _collect_comp_run_jars (ctx )
159- _write_manifest (ctx )
160- _compile (ctx , cjars , False )
154+ ijar = None
155+ if use_ijar :
156+ ijar = ctx .outputs .ijar
157+ else :
158+ # macro code needs to be available at compile-time, so set ijar == jar
159+ ijar = ctx .outputs .jar
161160
162- rjars += [ctx .outputs .jar ]
163- # macro code needs to be available at compiletime, so set ijar == jar
164- scalaattr = struct (outputs = struct (ijar = ctx .outputs .jar , class_jar = ctx .outputs .jar ),
165- transitive_runtime_deps = rjars )
161+ texp = _collect_jars (ctx .attr .exports )
162+ scalaattr = struct (outputs = struct (ijar = ijar , class_jar = ctx .outputs .jar ),
163+ transitive_runtime_deps = rjars ,
164+ transitive_compile_exports = texp .compiletime ,
165+ transitive_runtime_exports = texp .runtime
166+ )
166167 runfiles = ctx .runfiles (
167168 files = list (rjars ),
168169 collect_data = True )
169170 return struct (
170171 scala = scalaattr ,
171172 runfiles = runfiles )
172173
174+ def _scala_library_impl (ctx ):
175+ return _lib (ctx , True )
176+
177+ def _scala_macro_library_impl (ctx ):
178+ return _lib (ctx , False ) # don't build the ijar for macros
179+
173180# Common code shared by all scala binary implementations.
174181def _scala_binary_common (ctx , cjars , rjars ):
175182 _write_manifest (ctx )
176- _compile (ctx , cjars , False )
183+ _compile (ctx , cjars , False ) # no need to build an ijar for an executable
177184
178185 runfiles = ctx .runfiles (
179186 files = list (rjars ) + [ctx .outputs .executable ] + [ctx .file ._java ] + ctx .files ._jdk ,
@@ -183,16 +190,20 @@ def _scala_binary_common(ctx, cjars, rjars):
183190 runfiles = runfiles )
184191
185192def _scala_binary_impl (ctx ):
186- (cjars , rjars ) = _collect_comp_run_jars (ctx )
193+ jars = _collect_jars (ctx .attr .deps )
194+ (cjars , rjars ) = (jars .compiletime , jars .runtime )
187195 cjars += [ctx .file ._scalareflect ]
188196 rjars += [ctx .outputs .jar , ctx .file ._scalalib , ctx .file ._scalareflect ]
197+ rjars += _collect_jars (ctx .attr .runtime_deps ).runtime
189198 _write_launcher (ctx , rjars )
190199 return _scala_binary_common (ctx , cjars , rjars )
191200
192201def _scala_test_impl (ctx ):
193- (cjars , rjars ) = _collect_comp_run_jars (ctx )
202+ jars = _collect_jars (ctx .attr .deps )
203+ (cjars , rjars ) = (jars .compiletime , jars .runtime )
194204 cjars += [ctx .file ._scalareflect , ctx .file ._scalatest , ctx .file ._scalaxml ]
195205 rjars += [ctx .outputs .jar , ctx .file ._scalalib , ctx .file ._scalareflect , ctx .file ._scalatest , ctx .file ._scalaxml ]
206+ rjars += _collect_jars (ctx .attr .runtime_deps ).runtime
196207 _write_test_launcher (ctx , rjars )
197208 return _scala_binary_common (ctx , cjars , rjars )
198209
@@ -213,6 +224,7 @@ _common_attrs = {
213224 allow_files = _scala_filetype ,
214225 non_empty = True ),
215226 "deps" : attr .label_list (),
227+ "runtime_deps" : attr .label_list (),
216228 "data" : attr .label_list (allow_files = True , cfg = DATA_CFG ),
217229 "resources" : attr .label_list (allow_files = True ),
218230 "scalacopts" :attr .string_list (),
@@ -223,6 +235,7 @@ scala_library = rule(
223235 implementation = _scala_library_impl ,
224236 attrs = {
225237 "main_class" : attr .string (),
238+ "exports" : attr .label_list (allow_files = False ),
226239 } + _implicit_deps + _common_attrs ,
227240 outputs = {
228241 "jar" : "%{name}_deploy.jar" ,
@@ -235,6 +248,7 @@ scala_macro_library = rule(
235248 implementation = _scala_macro_library_impl ,
236249 attrs = {
237250 "main_class" : attr .string (),
251+ "exports" : attr .label_list (allow_files = False ),
238252 "_scala-reflect" : attr .label (default = Label ("@scala//:lib/scala-reflect.jar" ), single_file = True , allow_files = True ),
239253 } + _implicit_deps + _common_attrs ,
240254 outputs = {
0 commit comments