Skip to content

Commit 6f2e418

Browse files
Allow to cross build with Scala 2.13 (#6)
* Allow for cross building with Scala 2.11 and 2.13 * Get rid of Scala 2.13 deprecations * Allow to compile with Scala 2.11 * Don't cross build for Scala 2.11 * Move scripted tests back to original location * Fix running scripted tests * Update CI to test cross building * Revert spourious change
1 parent 6c88ff7 commit 6f2e418

File tree

6 files changed

+135
-84
lines changed

6 files changed

+135
-84
lines changed

.github/workflows/CI.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,6 @@ jobs:
1818
- name: Test
1919
run: >
2020
sbt 'set cli/scalaNativeVersion := "${{matrix.SN}}"'
21-
cli/test
22-
cli/scripted
21+
+cli/test
22+
+cliScriptedTests/scripted
2323
shell: bash

build.sbt

Lines changed: 47 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,16 @@
1-
val crossScalaNative212 = Seq("2.12.13", "2.12.14", "2.12.15")
1+
val crossScalaVersions212 = (13 to 15).map(v => s"2.12.$v")
2+
val crossScalaVersions213 = (4 to 7).map(v => s"2.13.$v")
3+
val latestsScalaVersions =
4+
Seq(crossScalaVersions212.last, crossScalaVersions213.last)
5+
6+
def scalaReleasesForBinaryVersion(v: String): Seq[String] = v match {
7+
case "2.12" => crossScalaVersions212
8+
case "2.13" => crossScalaVersions213
9+
case ver =>
10+
throw new IllegalArgumentException(
11+
s"Unsupported binary scala version `${ver}`"
12+
)
13+
}
214

315
val scalaNativeVersion =
416
settingKey[String]("Version of Scala Native for which to build to CLI")
@@ -8,9 +20,10 @@ val cliAssemblyJarName = settingKey[String]("Name of created assembly jar")
820
inThisBuild(
921
Def.settings(
1022
organization := "org.scala-native",
11-
scalaVersion := crossScalaNative212.last,
12-
scalaNativeVersion := "0.4.0",
13-
version := scalaNativeVersion.value
23+
scalaNativeVersion := "0.4.2",
24+
version := scalaNativeVersion.value,
25+
scalaVersion := crossScalaVersions212.last,
26+
crossScalaVersions := latestsScalaVersions
1427
)
1528
)
1629
val cliPackLibJars =
@@ -19,9 +32,16 @@ val cliPack = taskKey[File]("Pack the CLI for the current configuration")
1932

2033
lazy val cli = project
2134
.in(file("cli"))
22-
.enablePlugins(BuildInfoPlugin, ScriptedPlugin)
35+
.enablePlugins(BuildInfoPlugin)
2336
.settings(
2437
name := "scala-native-cli",
38+
crossScalaVersions := {
39+
scalaNativeVersion.value match {
40+
// No Scala 2.13 artifacts until 0.4.2
41+
case "0.4.0" | "0.4.1" => Seq(crossScalaVersions212.last)
42+
case _ => latestsScalaVersions
43+
}
44+
},
2545
Compile / run / mainClass :=
2646
Some("scala.scalanative.cli.ScalaNativeCli"),
2747
scalacOptions += "-Ywarn-unused:imports",
@@ -38,35 +58,48 @@ lazy val cli = project
3858
cliAssemblyJarName := s"${normalizedName.value}-assembly_${scalaBinaryVersion.value}-${scalaNativeVersion.value}.jar",
3959
assembly / assemblyJarName := cliAssemblyJarName.value,
4060
assembly / mainClass := (Compile / run / mainClass).value,
61+
cliPackSettings
62+
)
63+
64+
lazy val cliScriptedTests = project
65+
.in(file("cliScriptedTests"))
66+
.enablePlugins(ScriptedPlugin)
67+
.settings(
68+
sbtTestDirectory := (cli / sourceDirectory).value / "sbt-test",
69+
scalaVersion := crossScalaVersions212.last,
4170
scriptedLaunchOpts ++= {
42-
val jarName = cliAssemblyJarName.value
43-
val cliPath = (Compile / crossTarget).value / jarName
71+
val jarName = (cli / cliAssemblyJarName).value
72+
val cliPath = (cli / Compile / crossTarget).value / jarName
73+
val packDir = (cli / cliPack / crossTarget).value
4474
Seq(
4575
"-Xmx1024M",
46-
"-Dplugin.version=" + scalaNativeVersion.value,
76+
"-Dplugin.version=" + (cli / scalaNativeVersion).value,
77+
"-Dscala.version=" + (cli / scalaVersion).value,
4778
"-Dscala-native-cli=" + cliPath,
48-
"-Dscala-native-cli-pack=" + (cliPack / crossTarget).value
79+
"-Dscala-native-cli-pack=" + packDir
4980
)
5081
},
5182
scriptedBufferLog := false,
5283
scriptedDependencies := {
5384
scriptedDependencies
54-
.dependsOn(assembly, cliPack)
85+
.dependsOn(
86+
cli / assembly,
87+
cli / cliPack
88+
)
5589
.value
56-
},
57-
cliPackSettings
90+
}
5891
)
5992

6093
lazy val cliPackSettings = Def.settings(
6194
cliPackLibJars := {
6295
val s = streams.value
6396
val log = s.log
6497

65-
val scalaNativeOrg = "org.scala-native"
98+
val scalaNativeOrg = organization.value
6699
val scalaBinVer = scalaBinaryVersion.value
67100
val snVer = scalaNativeVersion.value
68101

69-
val scalaFullVers = crossScalaNative212
102+
val scalaFullVers = scalaReleasesForBinaryVersion(scalaBinVer)
70103
val cliAssemblyJar = assembly.value
71104

72105
// Standard modules needed for linking of Scala Native

cli/src/patches/current/src/test/scala/scala/scalanative/cli/utils/LinktimePropertyParserTest.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ class LinktimePropertyParserTest extends AnyFlatSpec {
99
val expected =
1010
Map[String, Any]("isTesting" -> "true", "isNotTesting" -> "False")
1111
val obtained = LinktimePropertyParser.parseAll(input)
12-
assert(obtained.right.get == expected)
12+
assert(obtained.contains(expected))
1313
}
1414

1515
it should "return error on undefined string patterns" in {

cli/src/sbt-test/integration/cli/build.sbt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,17 @@ val runCli = inputKey[Unit](
1111
val runExec = inputKey[Unit](
1212
"Runs given executable (due to problems with exec on Windows)"
1313
)
14+
15+
scalaVersion := {
16+
val scalaVersion = System.getProperty("scala.version")
17+
if (scalaVersion == null)
18+
throw new RuntimeException(
19+
"""|The system property 'scala.version' is not defined.
20+
|Specify this property using the scriptedLaunchOpts -D.""".stripMargin
21+
)
22+
else scalaVersion
23+
}
24+
1425
runCli := {
1526
val args = spaceDelimited("<arg>").parsed
1627
val classpath = (Compile / fullClasspath).value.map(_.data.toString())

cli/src/sbt-test/integration/standalone/build.sbt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,16 @@ val runExec = inputKey[Unit](
1313
"Runs given executable (due to problems with exec on Windows)"
1414
)
1515

16+
scalaVersion := {
17+
val scalaVersion = System.getProperty("scala.version")
18+
if (scalaVersion == null)
19+
throw new RuntimeException(
20+
"""|The system property 'scala.version' is not defined.
21+
|Specify this property using the scriptedLaunchOpts -D.""".stripMargin
22+
)
23+
else scalaVersion
24+
}
25+
1626
runScript := {
1727
val scriptName +: rawArgs = spaceDelimited("<arg>").parsed.toSeq
1828
val cliPackDir = System.getProperty("scala-native-cli-pack")

cli/src/test/scala/scala/scalanative/cli/utils/ConfigConverterTest.scala

Lines changed: 64 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,7 @@ class ConfigConverterTest extends AnyFlatSpec {
4040
val noArgs = Seq()
4141
val mainOnlyResult =
4242
ConfigConverter.convert(dummyCliOptions, dummyMain, noArgs)
43-
assert(mainOnlyResult.isLeft)
44-
assert(mainOnlyResult.left.get.isInstanceOf[IllegalArgumentException])
43+
assert(mainOnlyResult.left.exists(_.isInstanceOf[IllegalArgumentException]))
4544
}
4645

4746
it should "parse classpath strings correctly" in {
@@ -59,27 +58,23 @@ class ConfigConverterTest extends AnyFlatSpec {
5958
val config =
6059
ConfigConverter.convert(dummyCliOptions, dummyMain, classPathStrings)
6160

62-
assert(config != None)
63-
assert(config.right.get.config.classPath.sameElements(expected))
61+
assert(config.exists(_.config.classPath.sameElements(expected)))
6462
}
6563

6664
it should "handle NativeConfig GC correctly" in {
6765
def gcAssertion(gcString: String, expectedGC: GC) = {
68-
val options = CliOptions(
69-
dummyConfigOptions,
70-
NativeConfigOptions(gc =
71-
NativeConfigParserImplicits.gcParser(None, gcString).right.get
72-
),
73-
dummyLoggerOptions,
74-
dummyMiscOptions
75-
)
76-
val config =
77-
ConfigConverter
66+
val parsed = for {
67+
gc <- NativeConfigParserImplicits.gcParser(None, gcString)
68+
options = CliOptions(
69+
dummyConfigOptions,
70+
NativeConfigOptions(gc = gc),
71+
dummyLoggerOptions,
72+
dummyMiscOptions
73+
)
74+
converted <- ConfigConverter
7875
.convert(options, dummyMain, dummyArguments)
79-
.right
80-
.get
81-
.config
82-
assert(config.compilerConfig.gc == expectedGC)
76+
} yield converted.config.gc
77+
assert(parsed.contains(expectedGC))
8378
}
8479
gcAssertion("immix", GC.immix)
8580
gcAssertion("commix", GC.commix)
@@ -89,21 +84,17 @@ class ConfigConverterTest extends AnyFlatSpec {
8984

9085
it should "handle NativeConfig Mode correctly" in {
9186
def modeAssertion(modeString: String, expectedMode: Mode) = {
92-
val options = CliOptions(
93-
dummyConfigOptions,
94-
NativeConfigOptions(mode =
95-
NativeConfigParserImplicits.modeParser(None, modeString).right.get
96-
),
97-
dummyLoggerOptions,
98-
dummyMiscOptions
99-
)
100-
val config =
101-
ConfigConverter
102-
.convert(options, dummyMain, dummyArguments)
103-
.right
104-
.get
105-
.config
106-
assert(config.compilerConfig.mode == expectedMode)
87+
val parsed = for {
88+
mode <- NativeConfigParserImplicits.modeParser(None, modeString)
89+
options = CliOptions(
90+
dummyConfigOptions,
91+
NativeConfigOptions(mode = mode),
92+
dummyLoggerOptions,
93+
dummyMiscOptions
94+
)
95+
converted <- ConfigConverter.convert(options, dummyMain, dummyArguments)
96+
} yield converted.config.compilerConfig.mode
97+
assert(parsed.contains(expectedMode))
10798
}
10899
modeAssertion("debug", Mode.debug)
109100
modeAssertion("release-fast", Mode.releaseFast)
@@ -112,21 +103,19 @@ class ConfigConverterTest extends AnyFlatSpec {
112103

113104
it should "handle NativeConfig LTO correctly" in {
114105
def ltoAssertion(ltoString: String, expectedLto: LTO) = {
115-
val options = CliOptions(
116-
dummyConfigOptions,
117-
NativeConfigOptions(lto =
118-
NativeConfigParserImplicits.ltoParser(None, ltoString).right.get
119-
),
120-
dummyLoggerOptions,
121-
dummyMiscOptions
122-
)
123-
val config =
124-
ConfigConverter
106+
val parsed = for {
107+
lto <- NativeConfigParserImplicits.ltoParser(None, ltoString)
108+
options = CliOptions(
109+
dummyConfigOptions,
110+
NativeConfigOptions(lto = lto),
111+
dummyLoggerOptions,
112+
dummyMiscOptions
113+
)
114+
opts <- ConfigConverter
125115
.convert(options, dummyMain, dummyArguments)
126-
.right
127-
.get
128-
.config
129-
assert(config.compilerConfig.lto == expectedLto)
116+
} yield opts.config.compilerConfig.lto
117+
118+
assert(parsed.contains(expectedLto))
130119
}
131120
ltoAssertion("none", LTO.none)
132121
ltoAssertion("thin", LTO.thin)
@@ -151,10 +140,17 @@ class ConfigConverterTest extends AnyFlatSpec {
151140
)
152141

153142
val nativeConfig =
154-
ConfigConverter.convert(options, dummyMain, dummyArguments).right.get
143+
ConfigConverter
144+
.convert(options, dummyMain, dummyArguments)
145+
.map(_.config.compilerConfig)
146+
.fold(
147+
fail(_),
148+
{ config =>
149+
assert(config.clang == expectedClangPath)
150+
assert(config.clangPP == expectedClangPPPath)
151+
}
152+
)
155153

156-
assert(nativeConfig.config.compilerConfig.clang == expectedClangPath)
157-
assert(nativeConfig.config.compilerConfig.clangPP == expectedClangPPPath)
158154
}
159155

160156
it should "parse boolean options as opposite of default" in {
@@ -169,22 +165,23 @@ class ConfigConverterTest extends AnyFlatSpec {
169165
dummyLoggerOptions,
170166
dummyMiscOptions
171167
)
172-
val default = ConfigConverter
173-
.convert(dummyCliOptions, dummyMain, dummyArguments)
174-
.right
175-
.get
176-
.config
177-
.compilerConfig
178-
val nonDefault = ConfigConverter
179-
.convert(options, dummyMain, dummyArguments)
180-
.right
181-
.get
182-
.config
183-
.compilerConfig
184-
185-
assert(nonDefault.check != default.check)
186-
assert(nonDefault.dump != default.dump)
187-
assert(nonDefault.optimize != default.optimize)
188-
assert(nonDefault.linkStubs != default.linkStubs)
168+
val parsed = for {
169+
default <- ConfigConverter
170+
.convert(dummyCliOptions, dummyMain, dummyArguments)
171+
.map(_.config.compilerConfig)
172+
nonDefault <- ConfigConverter
173+
.convert(options, dummyMain, dummyArguments)
174+
.map(_.config.compilerConfig)
175+
} yield (default, nonDefault)
176+
177+
parsed.fold(
178+
fail(_),
179+
{ case (default, nonDefault) =>
180+
assert(nonDefault.check != default.check)
181+
assert(nonDefault.dump != default.dump)
182+
assert(nonDefault.optimize != default.optimize)
183+
assert(nonDefault.linkStubs != default.linkStubs)
184+
}
185+
)
189186
}
190187
}

0 commit comments

Comments
 (0)