Skip to content

Commit a97ea52

Browse files
committed
Move Scala Native linking to runtime fetched scala-native-cli
This way we can freely change the SN version on scala-cli runtime. With this change logging was moved to the default scala native logger with certain log levels being filtered out (on scala-native-cli side) depending on verbosity. Scala Native caching was also adjusted to facilitate incorrect options being passed to scala-native-cli.
1 parent 7902303 commit a97ea52

File tree

12 files changed

+176
-104
lines changed

12 files changed

+176
-104
lines changed

build.sc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ class Build(val crossScalaVersion: String)
174174
Deps.dependency,
175175
Deps.guava, // for coursierJvm / scalaJsEnvNodeJs, see above
176176
Deps.nativeTestRunner,
177-
Deps.nativeTools,
177+
Deps.nativeTools, // Used only for discovery methods. For linking, look for scala-native-cli
178178
Deps.osLib,
179179
Deps.pprint,
180180
Deps.scalaJsEnvNodeJs,

modules/build/src/main/scala/scala/build/Logger.scala

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ trait Logger {
1919

2020
def coursierLogger: coursier.cache.CacheLogger
2121
def bloopRifleLogger: BloopRifleLogger
22-
def scalaNativeLogger: sn.Logger
22+
def scalaNativeTestLogger: sn.Logger
23+
def scalaNativeCliInternalLoggerOptions: List[String]
2324

2425
def compilerOutputStream: PrintStream
2526
}
@@ -40,8 +41,12 @@ object Logger {
4041
coursier.cache.CacheLogger.nop
4142
def bloopRifleLogger: BloopRifleLogger =
4243
BloopRifleLogger.nop
43-
def scalaNativeLogger: sn.Logger =
44+
def scalaNativeTestLogger: sn.Logger =
4445
sn.Logger.nullLogger
46+
def scalaNativeCliInternalLoggerOptions: List[String] = {
47+
import scala.build.options.ScalaNativeOptions.Logger._
48+
List(noError, noWarn, noInfo, noDebug)
49+
}
4550

4651
def compilerOutputStream: PrintStream =
4752
new PrintStream(
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package scala.build.errors
2+
3+
final class ScalaNativeBuildError(
4+
caughtError: String
5+
) extends BuildException(s"Error compiling with Scala Native:\n${caughtError}")

modules/build/src/main/scala/scala/build/internal/NativeBuilderHelper.scala

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@ import java.math.BigInteger
44
import java.security.MessageDigest
55

66
import scala.build.Build
7-
import scala.scalanative.{build => sn}
87

98
object NativeBuilderHelper {
109

10+
case class SNCacheData(val changed: Boolean, val projectSha: String)
11+
1112
private def resolveProjectShaPath(nativeWorkDir: os.Path) = nativeWorkDir / ".project_sha"
1213
private def resolveOutputShaPath(nativeWorkDir: os.Path) = nativeWorkDir / ".output_sha"
1314

@@ -20,10 +21,10 @@ object NativeBuilderHelper {
2021
String.format(s"%040x", calculatedSum)
2122
}
2223

23-
private def projectSha(build: Build.Successful, nativeConfig: sn.NativeConfig) = {
24+
private def projectSha(build: Build.Successful, config: List[String]) = {
2425
val md = MessageDigest.getInstance("SHA-1")
2526
md.update(build.inputs.sourceHash().getBytes)
26-
md.update(nativeConfig.toString.getBytes)
27+
md.update(config.toString.getBytes)
2728
md.update(Constants.version.getBytes)
2829
md.update(build.options.hash.getOrElse("").getBytes)
2930

@@ -32,22 +33,29 @@ object NativeBuilderHelper {
3233
String.format(s"%040x", calculatedSum)
3334
}
3435

35-
def updateOutputSha(dest: os.Path, nativeWorkDir: os.Path) = {
36+
def updateProjectAndOutputSha(
37+
dest: os.Path,
38+
nativeWorkDir: os.Path,
39+
currentProjectSha: String
40+
) = {
41+
val projectShaPath = resolveProjectShaPath(nativeWorkDir)
42+
os.write.over(projectShaPath, currentProjectSha, createFolders = true)
43+
3644
val outputShaPath = resolveOutputShaPath(nativeWorkDir)
3745
val sha = fileSha(dest)
3846
os.write.over(outputShaPath, sha)
3947
}
4048

41-
def shouldBuildIfChanged(
49+
def getCacheData(
4250
build: Build.Successful,
43-
nativeConfig: sn.NativeConfig,
51+
config: List[String],
4452
dest: os.Path,
4553
nativeWorkDir: os.Path
46-
): Boolean = {
54+
): SNCacheData = {
4755
val projectShaPath = resolveProjectShaPath(nativeWorkDir)
4856
val outputShaPath = resolveOutputShaPath(nativeWorkDir)
4957

50-
val currentProjectSha = projectSha(build, nativeConfig)
58+
val currentProjectSha = projectSha(build, config)
5159
val currentOutputSha = if (os.exists(dest)) Some(fileSha(dest)) else None
5260

5361
val previousProjectSha = if (os.exists(projectShaPath)) Some(os.read(projectShaPath)) else None
@@ -58,9 +66,6 @@ object NativeBuilderHelper {
5866
previousOutputSha != currentOutputSha ||
5967
!os.exists(dest)
6068

61-
// update sha in .projectShaPath
62-
if (changed) os.write.over(projectShaPath, currentProjectSha, createFolders = true)
63-
64-
changed
69+
SNCacheData(changed, currentProjectSha)
6570
}
6671
}

modules/build/src/main/scala/scala/build/internal/Runner.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,7 @@ object Runner {
306306
val config = TestAdapter.Config()
307307
.withBinaryFile(launcher)
308308
.withEnvVars(sys.env.toMap)
309-
.withLogger(logger.scalaNativeLogger)
309+
.withLogger(logger.scalaNativeTestLogger)
310310

311311
var adapter: TestAdapter = null
312312

modules/build/src/main/scala/scala/build/options/ScalaNativeOptions.scala

Lines changed: 38 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -27,28 +27,45 @@ final case class ScalaNativeOptions(
2727

2828
private def gc(): sn.GC =
2929
gcStr.map(_.trim).filter(_.nonEmpty) match {
30-
case Some("default") | None => sn.GC.default
30+
case Some("default") | None => sn.Discover.GC()
3131
case Some(other) => sn.GC(other)
3232
}
33+
private def gcCliOption(): List[String] =
34+
List("--gc", gc().name)
35+
3336
private def mode(): sn.Mode =
3437
modeStr.map(_.trim).filter(_.nonEmpty) match {
3538
case Some("default") | None => sn.Discover.mode()
3639
case Some(other) => sn.Mode(other)
3740
}
41+
private def modeCliOption(): List[String] =
42+
List("--release-mode", mode().name)
3843

3944
private def clangPath() = clang
4045
.filter(_.nonEmpty)
4146
.map(Paths.get(_))
4247
.getOrElse(sn.Discover.clang())
48+
private def clangCliOption(): List[String] = Nil
49+
// List("--clang", clangPath.toString())
50+
4351
private def clangppPath() = clangpp
4452
.filter(_.nonEmpty)
4553
.map(Paths.get(_))
4654
.getOrElse(sn.Discover.clangpp())
47-
private def finalLinkingOptions() =
55+
private def clangppCliOption(): List[String] = Nil
56+
// List("--clang-pp", clangppPath().toString())
57+
58+
private def finalLinkingOptions(): List[String] =
4859
linkingOptions ++ (if (linkingDefaults.getOrElse(true)) sn.Discover.linkingOptions() else Nil)
49-
private def finalCompileOptions() =
60+
private def finalCompileOptions(): List[String] =
5061
compileOptions ++ (if (compileDefaults.getOrElse(true)) sn.Discover.compileOptions() else Nil)
5162

63+
private def linkingCliOptions(): List[String] = Nil
64+
finalLinkingOptions.flatMap(option => List("--linking-option", option))
65+
66+
private def compileCliOptions(): List[String] = Nil
67+
finalCompileOptions.flatMap(option => List("--compile-option", option))
68+
5269
def platformSuffix: String =
5370
"native" + ScalaVersion.nativeBinary(finalVersion).getOrElse(finalVersion)
5471
def nativeDependencies: Seq[AnyDependency] =
@@ -62,12 +79,13 @@ final case class ScalaNativeOptions(
6279
version = finalVersion,
6380
// there are more modes than bloop allows, but that setting here shouldn't end up being used anyway
6481
mode =
65-
if (mode().name == "release") BloopConfig.LinkerMode.Release
82+
if (mode() == sn.Mode.releaseFast || mode() == sn.Mode.releaseFull)
83+
BloopConfig.LinkerMode.Release
6684
else BloopConfig.LinkerMode.Debug,
6785
gc = gc().name,
6886
targetTriple = None,
69-
clang = clangPath(),
70-
clangpp = clangppPath(),
87+
clang = Paths.get("."),
88+
clangpp = Paths.get("."),
7189
toolchain = Nil,
7290
options = BloopConfig.NativeOptions(
7391
linker = finalLinkingOptions(),
@@ -79,19 +97,24 @@ final case class ScalaNativeOptions(
7997
output = None
8098
)
8199

82-
def config(): sn.NativeConfig =
83-
sn.NativeConfig.empty
84-
.withGC(gc())
85-
.withMode(mode())
86-
.withLinkStubs(false)
87-
.withClang(clangPath())
88-
.withClangPP(clangppPath())
89-
.withLinkingOptions(linkingOptions)
90-
.withCompileOptions(compileOptions)
100+
def configCliOptions(): List[String] =
101+
gcCliOption()
102+
.++(modeCliOption())
103+
.++(clangCliOption())
104+
.++(clangppCliOption())
105+
.++(linkingCliOptions())
106+
.++(compileCliOptions())
91107

92108
}
93109

94110
object ScalaNativeOptions {
95111
implicit val hasHashData: HasHashData[ScalaNativeOptions] = HasHashData.derive
96112
implicit val monoid: ConfigMonoid[ScalaNativeOptions] = ConfigMonoid.derive
113+
114+
object Logger {
115+
val noError = "--disable-error"
116+
val noWarn = "--disable-warn"
117+
val noInfo = "--disable-info"
118+
val noDebug = "--disable-debug"
119+
}
97120
}

0 commit comments

Comments
 (0)