Mill handles cross-building of all sorts via the Cross[T]
module.
You can use this as follows:
object foo extends mill.Cross[FooModule]("2.10", "2.11", "2.12")
class FooModule(crossVersion: String) extends Module {
def suffix = T { crossVersion }
def bigSuffix = T { suffix().toUpperCase() }
}
This defines three copies of FooModule
: "210"
, "211"
and "212"
, each of which has their own suffix
target. You can then run them via
mill show foo[2.10].suffix
mill show foo[2.10].bigSuffix
mill show foo[2.11].suffix
mill show foo[2.11].bigSuffix
mill show foo[2.12].suffix
mill show foo[2.12].bigSuffix
The modules each also have a millSourcePath
of
foo/2.10
foo/2.11
foo/2.12
And the suffix
targets will have the corresponding output paths for their metadata and files:
foo/2.10/suffix
foo/2.10/bigSuffix
foo/2.11/suffix
foo/2.11/bigSuffix
foo/2.12/suffix
foo/2.12/bigSuffix
You can also have a cross-build with multiple inputs:
val crossMatrix = for {
crossVersion <- Seq("210", "211", "212")
platform <- Seq("jvm", "js", "native")
if !(platform == "native" && crossVersion != "212")
} yield (crossVersion, platform)
object foo extends mill.Cross[FooModule](crossMatrix:_*)
class FooModule(crossVersion: String, platform: String) extends Module {
def suffix = T { crossVersion + "_" + platform }
}
Here, we define our cross-values programmatically using a for
-loop that spits out tuples instead of individual values. Our FooModule
template class then takes two parameters instead of one. This creates the following modules each with their own suffix
target:
mill show foo[210,jvm].suffix
mill show foo[211,jvm].suffix
mill show foo[212,jvm].suffix
mill show foo[210,js].suffix
mill show foo[211,js].suffix
mill show foo[212,js].suffix
mill show foo[212,native].suffix
You can refer to targets defined in cross-modules as follows:
object foo extends mill.Cross[FooModule]("2.10", "2.11", "2.12")
class FooModule(crossVersion: String) extends Module {
def suffix = T { crossVersion }
}
def bar = T { "hello " + foo("2.10").suffix }
Here, foo("2.10")
references the "2.10"
instance of FooModule
. You can refer to whatever versions of the cross-module you want, even using multiple versions of the cross-module in the same target:
object foo extends mill.Cross[FooModule]("2.10", "2.11", "2.12")
class FooModule(crossVersion: String) extends Module {
def suffix = T { crossVersion }
}
def bar = T { "hello " + foo("2.10").suffix + " world " + foo("2.12").suffix }
Targets in cross-modules can depend on one another the same way that external targets:
object foo extends mill.Cross[FooModule]("2.10", "2.11", "2.12")
class FooModule(crossVersion: String) extends Module {
def suffix = T { crossVersion }
}
object bar extends mill.Cross[BarModule]("2.10", "2.11", "2.12")
class BarModule(crossVersion: String) extends Module {
def bigSuffix = T { foo(crossVersion).suffix().toUpperCase() }
}
Here, you can run:
mill show foo[2.10].suffix
mill show foo[2.11].suffix
mill show foo[2.12].suffix
mill show bar[2.10].bigSuffix
mill show bar[2.11].bigSuffix
mill show bar[2.12].bigSuffix
You can define an implicit mill.define.Cross.Resolver
within your cross-modules, which would let you use a shorthand foo()
syntax when referring to other cross-modules with an identical set of cross values:
trait MyModule extends Module {
def crossVersion: String
implicit object resolver extends mill.define.Cross.Resolver[MyModule] {
def resolve[V <: MyModule](c: Cross[V]): V = c.itemMap(List(crossVersion))
}
}
object foo extends mill.Cross[FooModule]("2.10", "2.11", "2.12")
class FooModule(val crossVersion: String) extends MyModule {
def suffix = T { crossVersion }
}
object bar extends mill.Cross[BarModule]("2.10", "2.11", "2.12")
class BarModule(val crossVersion: String) extends MyModule {
def longSuffix = T { "_" + foo().suffix() }
}
While the example resolver
simply looks up the target Cross
value for the cross-module instance with the same crossVersion
, you can make the resolver arbitrarily complex. E.g. the resolver
for mill.scalalib.CrossSbtModule
looks for a cross-module instance whose scalaVersion
is binary compatible (e.g. 2.10.5 is compatible with 2.10.3) with the current cross-module.
This documentation was build from mill master branch.
About Mill: Mill is an Open Source Project created by Li Haoyi. It is actively maintained and the git repository has more that 100 individual contributors around the world.
About Mills Creator: Li Haoyi is a software engineer, an early contributor to Scala.js, and the author of many open-source Scala tools such as Mill, the Ammonite REPL and FastParse. If you've enjoyed using Mill, or enjoyed using Haoyi's other open source libraries, please chip in (or get your Company to chip in!) via Patreon so he can continue his open-source work.