Skip to content

Commit c60a098

Browse files
authored
Simplify Mill cross-build to only include major version (#5098)
This simplifies commands from, e.g. `mill chisel[2.13.18].compile` to just `mill chisel[2.13].compile`. This makes it such that we no longer have to change CI and documentation whenever we add support for a new minor version of Scala.
1 parent 343277c commit c60a098

File tree

15 files changed

+63
-46
lines changed

15 files changed

+63
-46
lines changed

.github/workflows/ci-circt-nightly.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ jobs:
4949
matrix:
5050
system: ["ubuntu-24.04"]
5151
jvm: [21]
52-
scala: ["2.13.18"]
52+
scala: ["2.13"]
5353
espresso: ["2.4"]
5454
slang: ["7.0"]
5555
circt: ["nightly"]

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ jobs:
1919
matrix:
2020
system: ["ubuntu-24.04"]
2121
jvm: [21]
22-
scala: ["2.13.18"]
22+
scala: ["2.13"]
2323
espresso: ["2.4"]
2424
slang: ["7.0"]
2525
uses: ./.github/workflows/test.yml

.github/workflows/test.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ on:
1515
type: number
1616
scala:
1717
description: 'The Scala version to use'
18-
default: '2.13.18'
18+
default: '2.13'
1919
required: true
2020
type: string
2121
espresso:
@@ -265,7 +265,7 @@ jobs:
265265
runs-on: ubuntu-24.04
266266
strategy:
267267
matrix:
268-
scala: ["2.13.18"]
268+
scala: ["2.13"]
269269
steps:
270270
- name: Checkout
271271
uses: actions/checkout@v5

CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ Most testing can be done on just the Chisel build unit:
8181
```
8282

8383
The `[]` exists because we are cross-compiling between Scala 2.13 and Scala 3.
84-
You can pick a specific version, e.g. `./mill chisel[2.13.18]`.
84+
You can pick a specific version, e.g. `./mill chisel[2.13]`.
8585
Using `[]` will pick the first version in the list of supported versions which one can think about as the "default" version.
8686

8787
You can test everything with:

benchmark/package.mill

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ import mill.contrib.jmh.JmhModule
88
import build._
99

1010
object `package` extends ScalaModule with JmhModule with ScalafmtModule {
11-
def scalaVersion = v.scalaVersion
11+
def scalaVersion = v.defaultScalaVersion
1212
def jmhCoreVersion = v.jmhVersion
1313

14-
override def moduleDeps = Seq(chisel(v.scalaVersion))
14+
override def moduleDeps = Seq(chisel(v.scalaVersionToCross(v.defaultScalaVersion)))
1515
}

build.mill

Lines changed: 37 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,12 @@ import mill.scalalib.scalafmt._
1414

1515
object v extends Module {
1616

17+
// Add support for later Scala 2.13 by bumping this.
18+
val scala213MinorVersion: Int = 18
19+
20+
// Bump Scala 3 version by bumping this.
21+
val scala3MinorVersion: String = "3.4"
22+
1723
val javaVersion = {
1824
val rawVersion = sys.props("java.specification.version")
1925
// Older versions of Java started with 1., e.g. 1.8 == 8
@@ -32,20 +38,26 @@ object v extends Module {
3238
// Only publish plugin for 2.13.11+ when using Java > 11, but still
3339
// publish all versions when Java version <= 11.
3440
val pluginScalaCrossVersions = {
35-
val latest213 = 18
3641
val java21Min213 = 11
3742
val minVersion = if (javaVersion > 11) java21Min213 else 0
38-
val versions = minVersion to latest213
43+
val versions = minVersion to scala213MinorVersion
3944
val versionSeq = versions.map(v => s"2.13.$v").toSeq
40-
versionSeq ++ Seq("3.3.4")
45+
versionSeq :+ scalaCrossToVersion("3")
4146
}
4247

43-
val scalaCrossVersions = Seq(
44-
"2.13.18",
45-
"3.3.4"
46-
)
48+
val scalaCrossVersions = Seq("2.13", "3")
49+
50+
def scalaCrossToVersion(major: String): String = major match {
51+
case "2.13" => s"2.13.$scala213MinorVersion"
52+
case "3" => s"3.$scala3MinorVersion"
53+
}
54+
55+
def scalaVersionToCross(version: String): String =
56+
if (version.startsWith("2.13")) "2.13"
57+
else if (version.startsWith("3.")) "3"
58+
else throw new Exception(s"Unsupported version $version")
4759

48-
def isScala3(ver: String): Boolean = ver.startsWith("3.")
60+
def isScala3(ver: String): Boolean = ver.startsWith("3")
4961

5062
def buildUnits(): Seq[ScalaModule] = {
5163
scalaCrossVersions.flatMap { ver =>
@@ -65,7 +77,10 @@ object v extends Module {
6577
}
6678
}
6779

68-
val scalaVersion = scalaCrossVersions.head
80+
def defaultCrossVersion = scalaCrossVersions.head
81+
82+
def defaultScalaVersion = scalaCrossToVersion(defaultCrossVersion)
83+
6984
val jmhVersion = "1.37"
7085
val osLib = mvn"com.lihaoyi::os-lib:0.10.7" // 0.11 requires Java 11
7186
val upickle = mvn"com.lihaoyi::upickle:3.3.1" // upickle 4.0 requires Scala 3.4 (we target Scala 3.3 LTS)
@@ -181,6 +196,15 @@ def latestStableVersion() = Task.Command {
181196
docs.latestStableVersion()
182197
}
183198

199+
/** Our base trait that helps with our simplified cross versioning (2.13 instead of 2.13.18)
200+
*
201+
* Keep this lean, it's mixed in to firrtl and svsim as well.
202+
*/
203+
trait ChiselCrossModule extends CrossSbtModule {
204+
protected def _scalaVersion = v.scalaCrossToVersion(crossScalaVersion)
205+
def scalaVersion = _scalaVersion
206+
}
207+
184208
trait HasScala2MacroAnno extends CrossModuleBase {
185209
override def scalacOptions = Task {
186210
if (!v.isScala3(crossScalaVersion)) {
@@ -189,9 +213,10 @@ trait HasScala2MacroAnno extends CrossModuleBase {
189213
}
190214
}
191215

192-
trait HasScalaPlugin extends CrossModuleBase {
216+
trait HasScalaPlugin extends ChiselCrossModule {
193217
import build_.plugin.Plugin
194-
def pluginModule: Plugin
218+
219+
def pluginModule: Plugin = plugin.cross(_scalaVersion)
195220

196221
override def scalacOptions = Task {
197222
super.scalacOptions() ++ Seq(s"-Xplugin:${pluginModule.jar().path}")
@@ -271,10 +296,10 @@ object circt extends Module {
271296
object chisel extends Cross[Chisel](v.scalaCrossVersions)
272297

273298
trait Chisel extends CrossSbtModule with HasScala2MacroAnno with HasScalaPlugin with ScalafmtModule {
299+
274300
override def moduleDir = super.moduleDir / os.up
275301
def svsimModule = svsim.cross(crossScalaVersion)
276302
def coreModule = core.cross(crossScalaVersion)
277-
def pluginModule = plugin.cross()
278303

279304
override def scalacOptions = Task {
280305
if (v.isScala3(crossScalaVersion)) {

core/package.mill

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,7 @@ object `package` extends Module {
1212
object cross extends Cross[Core](v.scalaCrossVersions)
1313
}
1414

15-
trait Core extends CrossSbtModule with HasScala2MacroAnno with HasCommonOptions with ScalafmtModule {
16-
def scalaVersion = crossScalaVersion
15+
trait Core extends ChiselCrossModule with HasScala2MacroAnno with HasCommonOptions with ScalafmtModule {
1716

1817
def moduleDir = super.moduleDir / os.up
1918

docs/package.mill

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,21 +11,19 @@ import mill.util.Jvm
1111
import build._
1212

1313
/** MDoc project */
14-
object `package` extends SbtModule with HasScalaPlugin with HasCommonOptions {
14+
object `package` extends HasScalaPlugin with HasCommonOptions {
1515

16-
override def scalaVersion = v.scalaVersion
16+
override def scalaVersion = v.defaultScalaVersion
1717

1818
// This not really a CrossModule but HasScala2Plugin and HasCommonOptions require it
19-
override def crossValue = v.scalaVersion
20-
21-
def pluginModule = plugin.cross()
19+
override def crossValue = v.scalaCrossVersions.head
2220

2321
// Our scala sources to be used by mdoc live here
2422
override def moduleDir = super.moduleDir / os.up / "docs-target"
2523

2624
override def mvnDeps = Task { Seq(v.mdoc, v.scalatest) }
2725

28-
override def moduleDeps = Seq(chisel(v.scalaVersion))
26+
override def moduleDeps = Seq(chisel(crossValue))
2927

3028
// Suppress missing interpolator warnings because mdoc appears to introduce them.
3129
override def extraWarnConf = Seq("msg=possible missing interpolator:s")

firrtl/package.mill

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,7 @@ object `package` extends Module {
1212
object cross extends Cross[Firrtl](v.scalaCrossVersions)
1313
}
1414

15-
trait Firrtl
16-
extends CrossSbtModule
17-
with Cross.Module[String]
18-
with HasScala2MacroAnno
19-
with HasCommonOptions
20-
with ScalafmtModule {
21-
def scalaVersion = crossScalaVersion
15+
trait Firrtl extends ChiselCrossModule with HasScala2MacroAnno with HasCommonOptions with ScalafmtModule {
2216

2317
def moduleDir = super.moduleDir / os.up
2418

integration-tests/package.mill

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,15 @@ object `package` extends Module {
1212
object cross extends Cross[IntegrationTests](v.scalaCrossVersions)
1313
}
1414

15-
trait IntegrationTests extends CrossSbtModule with HasScalaPlugin with HasCommonOptions with ScalafmtModule {
16-
def pluginModule = plugin.cross()
15+
trait IntegrationTests extends HasScalaPlugin with HasCommonOptions with ScalafmtModule {
16+
1717
def moduleDir = super.moduleDir / os.up
1818

1919
// TODO enable
2020
override def xsource3 = false
2121

2222
object test extends CrossSbtTests with TestModule.ScalaTest with ScalafmtModule {
23-
override def moduleDeps = super.moduleDeps :+ chisel().test
23+
override def moduleDeps = super.moduleDeps :+ chisel(crossScalaVersion).test
2424
def mvnDeps = Seq(v.scalatest, v.scalacheck)
2525

2626
override def testForkGrouping = discoveredTestClasses().grouped(8).toSeq

0 commit comments

Comments
 (0)