diff --git a/build.sc b/build.sc index d8ee8d7d4b..b508b7f66b 100644 --- a/build.sc +++ b/build.sc @@ -337,8 +337,7 @@ trait Cli extends SbtModule with CliLaunchers with ScalaCliPublishModule with Fo ) def mainClass = Some("scala.cli.ScalaCli") - def localRepoJar = `local-repo`.localRepoJar() - def graalVmVersion = deps.graalVmVersion + def localRepoJar = `local-repo`.localRepoJar() object test extends Tests with ScalaCliScalafixModule } diff --git a/modules/integration/src/test/scala/scala/cli/integration/PackageTestDefinitions.scala b/modules/integration/src/test/scala/scala/cli/integration/PackageTestDefinitions.scala index dc95dc195b..7b71192cbc 100644 --- a/modules/integration/src/test/scala/scala/cli/integration/PackageTestDefinitions.scala +++ b/modules/integration/src/test/scala/scala/cli/integration/PackageTestDefinitions.scala @@ -12,6 +12,18 @@ abstract class PackageTestDefinitions(val scalaVersionOpt: Option[String]) private lazy val extraOptions = scalaVersionArgs ++ TestUtil.extraOptions + def maybeUseBash(cmd: os.Shellable*)(cwd: os.Path = null): os.CommandResult = { + val res = os.proc(cmd: _*).call(cwd = cwd, check = false) + if (Properties.isLinux && res.exitCode == 127) + // /bin/sh seems to have issues with '%' signs in PATH, that coursier can leave + // in the JVM path entry (https://unix.stackexchange.com/questions/126955/percent-in-path-environment-variable) + os.proc(("/bin/bash": os.Shellable) +: cmd: _*).call(cwd = cwd) + else { + expect(res.exitCode == 0) + res + } + } + test("simple script") { val fileName = "simple.sc" val message = "Hello" @@ -39,7 +51,7 @@ abstract class PackageTestDefinitions(val scalaVersionOpt: Option[String]) expect(os.isFile(launcher)) expect(Files.isExecutable(launcher.toNIO)) - val output = os.proc(launcher.toString).call(cwd = root).out.text().trim + val output = maybeUseBash(launcher)(cwd = root).out.text().trim expect(output == message) } } @@ -68,7 +80,7 @@ abstract class PackageTestDefinitions(val scalaVersionOpt: Option[String]) expect(os.isFile(launcher)) expect(Files.isExecutable(launcher.toNIO)) - val output = os.proc(launcher.toString).call(cwd = root).out.text().trim + val output = maybeUseBash(launcher.toString)(cwd = root).out.text().trim expect(output == message) } } @@ -192,7 +204,7 @@ abstract class PackageTestDefinitions(val scalaVersionOpt: Option[String]) launcher } - val output = os.proc(runnableLauncher.toString).call(cwd = root).out.text().trim + val output = maybeUseBash(runnableLauncher.toString)(cwd = root).out.text().trim expect(output == message) } } diff --git a/project/deps.sc b/project/deps.sc index f2a3504484..a4c1e7a161 100644 --- a/project/deps.sc +++ b/project/deps.sc @@ -1,5 +1,7 @@ import mill._, scalalib._ +import scala.util.Properties + object Scala { def scala212 = "2.12.15" def scala213 = "2.13.6" @@ -90,15 +92,21 @@ object Deps { def usingDirectives = ivy"org.virtuslab:using_directives:0.0.7-4f0dd5d-SNAPSHOT" } -def graalVmVersion = "21.2.0" +private def graalVmVersion = + if (Properties.isWin) "21.2.0" + else "21.3.0" +def graalVmJvmId = + if (Properties.isWin) s"graalvm-java16:$graalVmVersion" + else s"graalvm-java17:$graalVmVersion" def csDockerVersion = Deps.Versions.coursier def buildCsVersion = Deps.Versions.coursier object Docker { + def customMuslBuilderImageName = "scala-cli-base-musl" def muslBuilder = - "messense/rust-musl-cross@sha256:12d0dd535ef7364bf49cb2608ae7eaf60e40d07834eb4d9160c592422a08d3b3" + s"$customMuslBuilderImageName:latest" def testImage = "ubuntu:18.04" def alpineTestImage = diff --git a/project/musl-image/Dockerfile b/project/musl-image/Dockerfile new file mode 100644 index 0000000000..3c68d96f96 --- /dev/null +++ b/project/musl-image/Dockerfile @@ -0,0 +1,3 @@ +FROM messense/rust-musl-cross@sha256:47a3721b3e186abfd705feb1e03bf1d5212357ea26762cceef11530e0a2f2c7c +ADD setup.sh /setup.sh +RUN /setup.sh diff --git a/project/musl-image/setup.sh b/project/musl-image/setup.sh new file mode 100755 index 0000000000..fa46ac8d9e --- /dev/null +++ b/project/musl-image/setup.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash +set -e + +cd /usr/local/musl/bin + +for i in x86_64-unknown-linux-musl-*; do + dest="$(echo "$i" | sed 's/-unknown//')" + ln -s "$i" "$dest" +done diff --git a/project/settings.sc b/project/settings.sc index 351b31ea4f..e520ca5b61 100644 --- a/project/settings.sc +++ b/project/settings.sc @@ -202,7 +202,7 @@ trait CliLaunchers extends SbtModule { self => trait CliNativeImage extends NativeImage { def nativeImageCsCommand = Seq(cs()) def nativeImagePersist = System.getenv("CI") != null - def nativeImageGraalVmJvmId = s"graalvm-java11:${deps.graalVmVersion}" + def nativeImageGraalVmJvmId = deps.graalVmJvmId def nativeImageOptions = T { val usesDocker = nativeImageDockerParams().nonEmpty val cLibPath = @@ -312,6 +312,20 @@ trait CliLaunchers extends SbtModule { self => s"https://github.com/coursier/coursier/releases/download/v${deps.csDockerVersion}/cs-x86_64-pc-linux.gz" ) ) + def nativeImageOptions = T { + super.nativeImageOptions() ++ Seq( + "-H:-CheckToolchain" + ) + } + def buildHelperImage = T { + os.proc("docker", "build", "-t", Docker.customMuslBuilderImageName, ".") + .call(cwd = os.pwd / "project" / "musl-image", stdout = os.Inherit) + () + } + def nativeImage = T { + buildHelperImage() + super.nativeImage() + } } object `mostly-static-image` extends CliNativeImage { @@ -324,7 +338,6 @@ trait CliLaunchers extends SbtModule { self => } def localRepoJar: T[PathRef] - def graalVmVersion: String def nativeImageMainClass = T { mainClass().getOrElse(sys.error("Don't know what main class to use")) @@ -370,7 +383,7 @@ trait CliLaunchers extends SbtModule { self => // format: off Seq( cs(), "java-home", - "--jvm", s"graalvm-java11:$graalVmVersion", + "--jvm", deps.graalVmJvmId, "--jvm-index", jvmIndex ).!!.trim // format: on