diff --git a/scalanativelib/src/mill/scalanativelib/ScalaNativeModule.scala b/scalanativelib/src/mill/scalanativelib/ScalaNativeModule.scala index 44c18789178..a7ba57ffce4 100644 --- a/scalanativelib/src/mill/scalanativelib/ScalaNativeModule.scala +++ b/scalanativelib/src/mill/scalanativelib/ScalaNativeModule.scala @@ -220,6 +220,13 @@ trait ScalaNativeModule extends ScalaModule { outer => /** Build target for current compilation */ def nativeBuildTarget: T[BuildTarget] = Task { BuildTarget.Application } + /** + * Shall be compiled with multithreading support. If equal to `None` the + * toolchain would detect if program uses system threads - when not thrads + * are not used, the program would be linked without multihreading support. + */ + def nativeMultithreading: T[Option[Boolean]] = Task { None } + private def nativeConfig: Task[NativeConfig] = Task.Anon { val classpath = runClasspath().map(_.path).filter(_.toIO.exists).toList @@ -240,6 +247,7 @@ trait ScalaNativeModule extends ScalaModule { outer => nativeEmbedResources(), nativeIncrementalCompilation(), nativeDump(), + nativeMultithreading(), toWorkerApi(logLevel()), toWorkerApi(nativeBuildTarget()) ) match { diff --git a/scalanativelib/test/src/mill/scalanativelib/CompileRunTests.scala b/scalanativelib/test/src/mill/scalanativelib/CompileRunTests.scala index 121080cb301..e82a0712e92 100644 --- a/scalanativelib/test/src/mill/scalanativelib/CompileRunTests.scala +++ b/scalanativelib/test/src/mill/scalanativelib/CompileRunTests.scala @@ -2,7 +2,6 @@ package mill.scalanativelib import java.util.jar.JarFile import mill._ -import mill.api.Result import mill.define.Discover import mill.eval.EvaluatorPaths import mill.scalalib.api.ZincWorkerUtil diff --git a/scalanativelib/test/src/mill/scalanativelib/TestingTests.scala b/scalanativelib/test/src/mill/scalanativelib/TestingTests.scala index 2e8488ac1e2..68911ca184c 100644 --- a/scalanativelib/test/src/mill/scalanativelib/TestingTests.scala +++ b/scalanativelib/test/src/mill/scalanativelib/TestingTests.scala @@ -2,20 +2,11 @@ package mill.scalanativelib import mill._ import mill.api.Result -import mill.define.Discover -import mill.eval.EvaluatorPaths -import mill.scalalib.api.ZincWorkerUtil -import mill.scalalib.publish.{Developer, License, PomSettings, VersionControl} -import mill.scalalib.{DepSyntax, PublishModule, ScalaModule, TestModule} import mill.scalanativelib.api._ -import mill.testkit.{TestBaseModule, UnitTester} +import mill.testkit.UnitTester import mill.testrunner.TestResult -import mill.util.TestUtil import utest._ -import java.util.jar.JarFile -import scala.jdk.CollectionConverters._ - object TestingTests extends TestSuite { import CompileRunTests._ def tests: Tests = Tests { diff --git a/scalanativelib/worker-api/src/mill/scalanativelib/worker/api/ScalaNativeWorkerApi.scala b/scalanativelib/worker-api/src/mill/scalanativelib/worker/api/ScalaNativeWorkerApi.scala index 174592ee742..dd65f36801e 100644 --- a/scalanativelib/worker-api/src/mill/scalanativelib/worker/api/ScalaNativeWorkerApi.scala +++ b/scalanativelib/worker-api/src/mill/scalanativelib/worker/api/ScalaNativeWorkerApi.scala @@ -27,6 +27,7 @@ private[scalanativelib] trait ScalaNativeWorkerApi { nativeEmbedResources: Boolean, nativeIncrementalCompilation: Boolean, nativeDump: Boolean, + nativeMultithreading: Option[Boolean], logLevel: NativeLogLevel, buildTarget: BuildTarget ): Either[String, Object] diff --git a/scalanativelib/worker/0.4/src/mill/scalanativelib/worker/ScalaNativeWorkerImpl.scala b/scalanativelib/worker/0.4/src/mill/scalanativelib/worker/ScalaNativeWorkerImpl.scala deleted file mode 100644 index db356fd0c29..00000000000 --- a/scalanativelib/worker/0.4/src/mill/scalanativelib/worker/ScalaNativeWorkerImpl.scala +++ /dev/null @@ -1,173 +0,0 @@ -package mill.scalanativelib.worker - -import java.io.File -import java.lang.System.{err, out} - -import mill.scalanativelib.worker.api._ -import scala.scalanative.util.Scope -import scala.scalanative.build.{ - Build, - BuildTarget => ScalaNativeBuildTarget, - Config, - Discover, - GC, - Logger, - LTO, - Mode, - NativeConfig => ScalaNativeNativeConfig, - MillUtils -} -import scala.scalanative.nir.Versions -import scala.scalanative.testinterface.adapter.TestAdapter - -import scala.util.{Success, Try} - -class ScalaNativeWorkerImpl extends mill.scalanativelib.worker.api.ScalaNativeWorkerApi { - private def patchIsGreaterThanOrEqual(number: Int) = { - val patch = Versions.current.stripPrefix("0.4.") - Try(patch.toInt) match { - case Success(n) if n < number => false - case _ => true - } - } - - def logger(level: NativeLogLevel): Logger = - Logger( - traceFn = msg => if (level.value >= NativeLogLevel.Trace.value) err.println(s"[trace] $msg"), - debugFn = msg => if (level.value >= NativeLogLevel.Debug.value) out.println(s"[debug] $msg"), - infoFn = msg => if (level.value >= NativeLogLevel.Info.value) out.println(s"[info] $msg"), - warnFn = msg => if (level.value >= NativeLogLevel.Warn.value) out.println(s"[warn] $msg"), - errorFn = msg => if (level.value >= NativeLogLevel.Error.value) err.println(s"[error] $msg") - ) - - def discoverClang(): File = Discover.clang().toFile - def discoverClangPP(): File = Discover.clangpp().toFile - def discoverCompileOptions(): Seq[String] = Discover.compileOptions() - def discoverLinkingOptions(): Seq[String] = Discover.linkingOptions() - def defaultGarbageCollector(): String = GC.default.name - - def config( - mainClass: Either[String, String], - classpath: Seq[File], - nativeWorkdir: File, - nativeClang: File, - nativeClangPP: File, - nativeTarget: Option[String], - nativeCompileOptions: Seq[String], - nativeLinkingOptions: Seq[String], - nativeGC: String, - nativeLinkStubs: Boolean, - nativeLTO: String, - releaseMode: String, - nativeOptimize: Boolean, - nativeEmbedResources: Boolean, - nativeIncrementalCompilation: Boolean, - nativeDump: Boolean, - logLevel: NativeLogLevel, - buildTarget: BuildTarget - ): Either[String, Config] = { - var nativeConfig = - ScalaNativeNativeConfig.empty - .withClang(nativeClang.toPath) - .withClangPP(nativeClangPP.toPath) - .withTargetTriple(nativeTarget) - .withCompileOptions(nativeCompileOptions) - .withLinkingOptions(nativeLinkingOptions) - .withGC(GC(nativeGC)) - .withLinkStubs(nativeLinkStubs) - .withMode(Mode(releaseMode)) - .withOptimize(nativeOptimize) - .withLTO(LTO(nativeLTO)) - .withDump(nativeDump) - if (patchIsGreaterThanOrEqual(8)) { - val nativeBuildTarget = buildTarget match { - case BuildTarget.Application => ScalaNativeBuildTarget.application - case BuildTarget.LibraryDynamic => ScalaNativeBuildTarget.libraryDynamic - case BuildTarget.LibraryStatic => ScalaNativeBuildTarget.libraryStatic - } - nativeConfig = nativeConfig.withBuildTarget(nativeBuildTarget) - } else { - if (buildTarget != BuildTarget.Application) { - return Left("nativeBuildTarget not supported. Please update to Scala Native 0.4.8+") - } - } - if (patchIsGreaterThanOrEqual(4)) { - nativeConfig = nativeConfig.withEmbedResources(nativeEmbedResources) - } - if (patchIsGreaterThanOrEqual(9)) { - nativeConfig = nativeConfig.withIncrementalCompilation(nativeIncrementalCompilation) - } - var config = Config.empty - .withClassPath(classpath.map(_.toPath)) - .withWorkdir(nativeWorkdir.toPath) - .withCompilerConfig(nativeConfig) - .withLogger(logger(logLevel)) - - if (buildTarget == BuildTarget.Application) { - mainClass match { - case Left(error) => return Left(error) - case Right(mainClass) => - val entry = if (patchIsGreaterThanOrEqual(3)) mainClass else mainClass + "$" - config = config.withMainClass(entry) - } - } - - Right(config) - } - - def nativeLink(nativeConfig: Object, outDirectory: File): File = { - val config = nativeConfig.asInstanceOf[Config] - val compilerConfig = config.compilerConfig - - val name = if (patchIsGreaterThanOrEqual(8)) { - val isWindows = MillUtils.targetsWindows(config) - val isMac = MillUtils.targetsMac(config) - - val ext = if (compilerConfig.buildTarget == ScalaNativeBuildTarget.application) { - if (MillUtils.targetsWindows(config)) ".exe" else "" - } else if (compilerConfig.buildTarget == ScalaNativeBuildTarget.libraryDynamic) { - if (isWindows) ".dll" - else if (isMac) ".dylib" - else ".so" - } else if (compilerConfig.buildTarget == ScalaNativeBuildTarget.libraryStatic) { - if (isWindows) ".lib" - else ".a" - } else { - throw new RuntimeException(s"Unknown buildTarget ${compilerConfig.buildTarget}") - } - - val namePrefix = if (compilerConfig.buildTarget == ScalaNativeBuildTarget.application) "" - else { - if (isWindows) "" else "lib" - } - s"${namePrefix}out${ext}" - } else "out" - - val outPath = new File(outDirectory, name) - Build.build(config, outPath.toPath)(Scope.unsafe()) - outPath - } - - def getFramework( - testBinary: File, - envVars: Map[String, String], - logLevel: NativeLogLevel, - frameworkName: String - ): (() => Unit, sbt.testing.Framework) = { - val config = TestAdapter.Config() - .withBinaryFile(testBinary) - .withEnvVars(envVars) - .withLogger(logger(logLevel)) - - val adapter = new TestAdapter(config) - - ( - () => adapter.close(), - adapter - .loadFrameworks(List(List(frameworkName))) - .flatten - .headOption - .getOrElse(throw new RuntimeException("Failed to get framework")) - ) - } -} diff --git a/scalanativelib/worker/0.4/src/scala/scalanative/build/MillUtils.scala b/scalanativelib/worker/0.4/src/scala/scalanative/build/MillUtils.scala deleted file mode 100644 index 58c6009c3bf..00000000000 --- a/scalanativelib/worker/0.4/src/scala/scalanative/build/MillUtils.scala +++ /dev/null @@ -1,6 +0,0 @@ -package scala.scalanative.build - -object MillUtils { - def targetsWindows(config: Config): Boolean = config.targetsWindows - def targetsMac(config: Config): Boolean = config.targetsMac -} diff --git a/scalanativelib/worker/0.5/src/mill/scalanativelib/worker/ScalaNativeWorkerImpl.scala b/scalanativelib/worker/0.5/src/mill/scalanativelib/worker/ScalaNativeWorkerImpl.scala index 891c90bde69..29a1c008b5b 100644 --- a/scalanativelib/worker/0.5/src/mill/scalanativelib/worker/ScalaNativeWorkerImpl.scala +++ b/scalanativelib/worker/0.5/src/mill/scalanativelib/worker/ScalaNativeWorkerImpl.scala @@ -58,6 +58,7 @@ class ScalaNativeWorkerImpl extends mill.scalanativelib.worker.api.ScalaNativeWo nativeEmbedResources: Boolean, nativeIncrementalCompilation: Boolean, nativeDump: Boolean, + nativeMultithreading: Option[Boolean], logLevel: NativeLogLevel, buildTarget: BuildTarget ): Either[String, Config] = { @@ -81,6 +82,7 @@ class ScalaNativeWorkerImpl extends mill.scalanativelib.worker.api.ScalaNativeWo }) .withEmbedResources(nativeEmbedResources) .withIncrementalCompilation(nativeIncrementalCompilation) + .withMultithreading(nativeMultithreading) .withBaseName("out") val config = Config.empty