From d3e277f813dd0ad96a4ddeac5cdf62546ebcec41 Mon Sep 17 00:00:00 2001 From: Olivier Mélois Date: Tue, 28 May 2019 09:40:58 +0200 Subject: Bloop config for Js/Native modules (#617) This generates correct bloop configuration for ScalaJs/ScalaNative module. --- build.sc | 3 +- .../bloop/src/mill.contrib.bloop/BloopImpl.scala | 81 +++++++++++++++++++--- .../test/src/mill/contrib/bloop/BloopTests.scala | 50 ++++++++++++- docs/pages/9 - Contrib Modules.md | 8 +-- 4 files changed, 127 insertions(+), 15 deletions(-) diff --git a/build.sc b/build.sc index c70aaf71..10d3d051 100755 --- a/build.sc +++ b/build.sc @@ -340,11 +340,12 @@ object contrib extends MillModule { } object bloop extends MillModule { - def moduleDeps = Seq(scalalib) + def moduleDeps = Seq(scalalib, scalajslib, scalanativelib) def ivyDeps = Agg( ivy"ch.epfl.scala::bloop-config:1.2.5", ivy"com.lihaoyi::ujson-circe:0.7.4" ) + def testArgs = T(scalanativelib.testArgs()) } } diff --git a/contrib/bloop/src/mill.contrib.bloop/BloopImpl.scala b/contrib/bloop/src/mill.contrib.bloop/BloopImpl.scala index 64f7b386..0db3b7dc 100644 --- a/contrib/bloop/src/mill.contrib.bloop/BloopImpl.scala +++ b/contrib/bloop/src/mill.contrib.bloop/BloopImpl.scala @@ -7,7 +7,11 @@ import mill._ import mill.api.Loose import mill.define.{Module => MillModule, _} import mill.eval.Evaluator +import mill.scalajslib.ScalaJSModule +import mill.scalajslib.api.ModuleKind import mill.scalalib._ +import mill.scalanativelib.ScalaNativeModule +import mill.scalanativelib.api.ReleaseMode import os.pwd /** @@ -46,6 +50,12 @@ class BloopImpl(ev: () => Evaluator, wd: Path) extends ExternalModule { outer => */ trait Module extends MillModule with CirceCompat { self: JavaModule => + /** + * Allows to tell Bloop whether it should use "fullOptJs" or + * "fastOptJs" when compiling. Used exclusively with ScalaJsModules. + */ + def linkerMode: T[Option[BloopConfig.LinkerMode]] = None + object bloop extends MillModule { def config = T { new BloopOps(self).bloop.config() @@ -82,6 +92,11 @@ class BloopImpl(ev: () => Evaluator, wd: Path) extends ExternalModule { outer => Task.traverse(jm.transitiveModuleDeps)(_.bloop.writeConfig) } } + + def asBloop: Option[Module] = jm match { + case m: Module => Some(m) + case _ => None + } } private def computeModules: Seq[JavaModule] = { @@ -193,14 +208,63 @@ class BloopImpl(ev: () => Evaluator, wd: Path) extends ExternalModule { outer => // Platform (Jvm/Js/Native) //////////////////////////////////////////////////////////////////////////// - val platform = T.task { - BloopConfig.Platform.Jvm( - BloopConfig.JvmConfig( - home = T.ctx().env.get("JAVA_HOME").map(s => Path(s).toNIO), - options = module.forkArgs().toList - ), - mainClass = module.mainClass() - ) + def jsLinkerMode(m: JavaModule): Task[Config.LinkerMode] = + (m.asBloop match { + case Some(bm) => T.task(bm.linkerMode()) + case None => T.task(None) + }).map(_.getOrElse(Config.LinkerMode.Debug)) + + val platform: Task[BloopConfig.Platform] = module match { + case m: ScalaJSModule => + T.task { + BloopConfig.Platform.Js( + BloopConfig.JsConfig.empty.copy( + version = m.scalaJSVersion(), + mode = jsLinkerMode(m)(), + kind = m.moduleKind() match { + case ModuleKind.NoModule => Config.ModuleKindJS.NoModule + case ModuleKind.CommonJSModule => + Config.ModuleKindJS.CommonJSModule + }, + emitSourceMaps = m.nodeJSConfig().sourceMap, + jsdom = Some(false), + ), + mainClass = module.mainClass() + ) + } + case m: ScalaNativeModule => + T.task { + BloopConfig.Platform.Native( + BloopConfig.NativeConfig.empty.copy( + version = m.scalaNativeVersion(), + mode = m.releaseMode() match { + case ReleaseMode.Debug => BloopConfig.LinkerMode.Debug + case ReleaseMode.Release => BloopConfig.LinkerMode.Release + }, + gc = m.nativeGC(), + targetTriple = m.nativeTarget(), + nativelib = m.nativeLibJar().path.toNIO, + clang = m.nativeClang().toNIO, + clangpp = m.nativeClangPP().toNIO, + options = Config.NativeOptions( + m.nativeLinkingOptions().toList, + m.nativeCompileOptions().toList + ), + linkStubs = m.nativeLinkStubs(), + ), + mainClass = module.mainClass() + ) + } + case _ => + T.task { + BloopConfig.Platform.Jvm( + BloopConfig.JvmConfig( + home = T.ctx().env.get("JAVA_HOME").map(s => Path(s).toNIO), + options = module.forkArgs().toList + ), + mainClass = module.mainClass() + ) + } } //////////////////////////////////////////////////////////////////////////// @@ -241,6 +305,7 @@ class BloopImpl(ev: () => Evaluator, wd: Path) extends ExternalModule { outer => */ def artifacts(repos: Seq[coursier.Repository], deps: Seq[coursier.Dependency]): List[BloopConfig.Module] = { + import coursier._ import coursier.util._ diff --git a/contrib/bloop/test/src/mill/contrib/bloop/BloopTests.scala b/contrib/bloop/test/src/mill/contrib/bloop/BloopTests.scala index cd3f9497..0af93c46 100644 --- a/contrib/bloop/test/src/mill/contrib/bloop/BloopTests.scala +++ b/contrib/bloop/test/src/mill/contrib/bloop/BloopTests.scala @@ -1,10 +1,13 @@ package mill.contrib.bloop +import bloop.config.{Config => BloopConfig} import bloop.config.Config.{File => BloopFile} import bloop.config.ConfigEncoderDecoders._ import mill._ import mill.contrib.bloop.CirceCompat._ +import mill.scalajslib.api.ModuleKind import mill.scalalib._ +import mill.scalanativelib.api.ReleaseMode import mill.util.{TestEvaluator, TestUtil} import os.Path import upickle.default._ @@ -41,6 +44,20 @@ object BloopTests extends TestSuite { def scalaVersion = "2.12.8" } + object scalajsModule extends scalajslib.ScalaJSModule with testBloop.Module { + override def scalaVersion = "2.12.8" + override def scalaJSVersion = "0.6.28" + override def linkerMode = T(Some(_root_.bloop.config.Config.LinkerMode.Release)) + override def moduleKind = T(ModuleKind.CommonJSModule) + } + + object scalanativeModule extends scalanativelib.ScalaNativeModule with testBloop.Module { + override def scalaVersion = "2.11.12" + override def scalaNativeVersion = "0.3.8" + override def releaseMode = T(ReleaseMode.Release) + } + + } def readBloopConf(jsonFile: String) = @@ -49,10 +66,12 @@ object BloopTests extends TestSuite { def tests: Tests = Tests { 'genBloopTests - { - testEvaluator(testBloop.install) + testEvaluator(testBloop.install()) val scalaModuleConfig = readBloopConf("scalaModule.json") val scalaModule2Config = readBloopConf("scalaModule2.json") val testModuleConfig = readBloopConf("scalaModule.test.json") + val scalajsModuleConfig = readBloopConf("scalajsModule.json") + val scalanativeModuleConfig = readBloopConf("scalanativeModule.json") 'scalaModule - { val p = scalaModuleConfig.project @@ -106,6 +125,35 @@ object BloopTests extends TestSuite { val cp = scalaModule2Config.project.classpath.map(_.toString) assert(cp.exists(_.contains("scala-library-2.12.8"))) } + 'scalajsModule - { + val p = scalajsModuleConfig.project + val name = p.name + val sources = p.sources.map(Path(_)) + val version = p.scala.get.version + val platform = p.platform.get.asInstanceOf[BloopConfig.Platform.Js] + + assert(name == "scalajsModule") + assert(sources == List(workdir / "scalajsModule" / "src")) + assert(version == "2.12.8") + assert(platform.config.emitSourceMaps) + assert(platform.config.kind == BloopConfig.ModuleKindJS.CommonJSModule) + assert(platform.config.mode == BloopConfig.LinkerMode.Release) + } + 'scalanativeModule - { + val p = scalanativeModuleConfig.project + val name = p.name + val sources = p.sources.map(Path(_)) + val version = p.scala.get.version + val platform = p.platform.get.asInstanceOf[BloopConfig.Platform.Native] + + val (clang, _) = testEvaluator(build.scalanativeModule.nativeClang).asSuccess.get.value.right.get + + assert(name == "scalanativeModule") + assert(sources == List(workdir / "scalanativeModule" / "src")) + assert(version == "2.11.12") + assert(platform.config.mode == BloopConfig.LinkerMode.Release) + assert(platform.config.clang == clang.toNIO) + } } } diff --git a/docs/pages/9 - Contrib Modules.md b/docs/pages/9 - Contrib Modules.md index 5f730181..a4b3b954 100644 --- a/docs/pages/9 - Contrib Modules.md +++ b/docs/pages/9 - Contrib Modules.md @@ -25,6 +25,9 @@ Then in your terminal : > mill mill.contrib.Bloop/install ``` +It generate correct bloop config for any `JavaModule`, `ScalaModule`, +`ScalaJsModule` or `ScalaNativeModule` under the `.bloop` folder + ### Mix-in You can mix-in the `Bloop.Module` trait with any JavaModule to quickly access @@ -57,11 +60,6 @@ extending `mill.contrib.bloop.BloopImpl` in your own space. The mill-bloop integration currently present in the [bloop codebase](https://github.com/scalacenter/bloop/blob/master/integrations/mill-bloop/src/main/scala/bloop/integrations/mill/MillBloop.scala#L10) will be deprecated in favour of this implementation. -### Caveats - -At this time, only Java/ScalaModule are processed correctly. ScalaJS/ScalaNative integration will -be added in a near future. - ## BuildInfo -- cgit v1.2.3