Skip to content

Commit 562ed30

Browse files
authored
Generate native launcher of scala-cli for M1 (#1396)
1 parent 7013b86 commit 562ed30

File tree

11 files changed

+103
-16
lines changed

11 files changed

+103
-16
lines changed

.github/workflows/ci.yml

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,57 @@ jobs:
285285
SCALA_CLI_IT_GROUP: 3
286286
SCALA_CLI_SODIUM_JNI_ALLOW: false
287287

288+
generate-macos-m1-launcher:
289+
timeout-minutes: 120
290+
runs-on: "macOS-m1"
291+
steps:
292+
- uses: actions/checkout@v3
293+
with:
294+
fetch-depth: 0
295+
submodules: true
296+
- uses: coursier/setup-action@f883d08305acbc28e5e5363bf5ec086397627021
297+
with:
298+
apps: ""
299+
jvm: "https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-22.2.0/graalvm-ce-java17-darwin-aarch64-22.2.0.tar.gz"
300+
- name: Generate native launcher
301+
run: .github/scripts/generate-native-image.sh
302+
# - run: ./mill -i ci.setShouldPublish
303+
# - name: Build OS packages TODO generate os packages for M1
304+
# if: env.SHOULD_PUBLISH == 'true'
305+
# run: .github/scripts/generate-os-packages.sh
306+
- name: Copy artifacts
307+
run: ./mill -i copyDefaultLauncher artifacts/
308+
- uses: actions/upload-artifact@v3
309+
with:
310+
name: macos-m1-launchers
311+
path: artifacts/
312+
if-no-files-found: error
313+
retention-days: 2
314+
315+
native-macos-m1-tests:
316+
needs: generate-macos-m1-launcher
317+
timeout-minutes: 120
318+
runs-on: "macOS-m1"
319+
steps:
320+
- uses: actions/checkout@v3
321+
with:
322+
fetch-depth: 0
323+
submodules: true
324+
- uses: coursier/setup-action@f883d08305acbc28e5e5363bf5ec086397627021
325+
with:
326+
apps: ""
327+
jvm: "https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-22.2.0/graalvm-ce-java17-darwin-aarch64-22.2.0.tar.gz"
328+
- uses: actions/download-artifact@v3
329+
with:
330+
name: macos-m1-launchers
331+
path: artifacts/
332+
- name: Native integration tests
333+
run: ./mill -i nativeIntegrationTests
334+
env:
335+
UPDATE_GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
336+
SCALA_CLI_IT_FORCED_LAUNCHER_DIRECTORY: artifacts/
337+
SCALA_CLI_SODIUM_JNI_ALLOW: false
338+
288339
generate-windows-launcher:
289340
timeout-minutes: 120
290341
runs-on: "windows-latest"
@@ -809,6 +860,7 @@ jobs:
809860
- native-macos-tests-1
810861
- native-macos-tests-2
811862
- native-macos-tests-3
863+
- native-macos-m1-tests
812864
- native-windows-tests-1
813865
- native-windows-tests-2
814866
- native-windows-tests-3
@@ -843,6 +895,11 @@ jobs:
843895
with:
844896
name: macos-launchers
845897
path: artifacts/
898+
- uses: actions/download-artifact@v3
899+
if: env.SHOULD_PUBLISH == 'true'
900+
with:
901+
name: macos-m1-launchers
902+
path: artifacts/
846903
- uses: actions/download-artifact@v3
847904
if: env.SHOULD_PUBLISH == 'true'
848905
with:

modules/cli/src/main/scala/scala/cli/commands/github/LibSodiumJni.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ object LibSodiumJni {
8787
else sys.error(s"Unrecognized operating system: ${sys.props("os.name")}")
8888

8989
val dep =
90-
dep"io.github.alexarchambault.tmp.libsodiumjni:libsodiumjni:$libsodiumjniVersion,intransitive,classifier=$classifier,ext=$ext,type=$ext"
90+
dep"org.virtuslab.scala-cli:libsodiumjni:$libsodiumjniVersion,intransitive,classifier=$classifier,ext=$ext,type=$ext"
9191
val fetch = coursier.Fetch()
9292
.addDependencies(dep.toCs)
9393
.addArtifactTypes(Type(ext))

modules/core/src/main/scala/scala/build/Os.scala

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package scala.build
22

3+
import java.util.Locale
4+
35
import scala.util.Properties
46

57
object Os {
@@ -8,4 +10,6 @@ object Os {
810
os.Path(os.pwd.toIO.getCanonicalFile)
911
else
1012
os.pwd
13+
lazy val isArmArchitecture: Boolean =
14+
sys.props.getOrElse("os.arch", "").toLowerCase(Locale.ROOT) == "aarch64"
1115
}

modules/core/src/main/scala/scala/build/internals/OsLibc.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import coursier.jvm.{JavaHome, JvmIndex}
55
import java.io.IOException
66
import java.nio.charset.Charset
77

8+
import scala.build.Os
89
import scala.build.blooprifle.VersionUtil.parseJavaVersion
910
import scala.util.{Properties, Try}
1011

@@ -68,7 +69,8 @@ object OsLibc {
6869
.forall(_ >= 17)
6970
if (os == "linux-musl") s"liberica:$jvmVersion" // zulu could work too
7071
else if (java17OrHigher) s"temurin:$jvmVersion"
71-
else s"adopt:$jvmVersion"
72+
else if (Os.isArmArchitecture) s"zulu:$jvmVersion" // adopt doesn't support Java 8 on macOS arm
73+
else s"temurin:$jvmVersion"
7274
}
7375

7476
def defaultJvm(os: String): String = {

modules/integration/src/test/scala/scala/cli/integration/NativePackagerTests.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ class NativePackagerTests extends ScalaCliSuite {
4848
val pkgAppPath = root / pkgAppFile
4949
expect(os.isFile(pkgAppPath))
5050

51-
if (TestUtil.isCI) {
51+
if (TestUtil.isCI && !TestUtil.isArmArchitecture) {
5252
os.proc("installer", "-pkg", pkgAppFile, "-target", "CurrentUserHomeDirectory").call(
5353
cwd = root,
5454
stdin = os.Inherit,

modules/integration/src/test/scala/scala/cli/integration/SparkTests212.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ class SparkTests212 extends SparkTestDefinitions {
105105
.call(cwd = root)
106106

107107
val java8Home =
108-
os.Path(os.proc(TestUtil.cs, "java-home", "--jvm", "8").call().out.trim(), os.pwd)
108+
os.Path(os.proc(TestUtil.cs, "java-home", "--jvm", "zulu:8").call().out.trim(), os.pwd)
109109

110110
val ext = if (Properties.isWin) ".cmd" else ""
111111
val res =

modules/integration/src/test/scala/scala/cli/integration/TestUtil.scala

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package scala.cli.integration
33
import os.{CommandResult, Path}
44

55
import java.io.File
6+
import java.util.Locale
67
import java.util.concurrent.atomic.AtomicInteger
78
import java.util.concurrent.{ExecutorService, Executors, ScheduledExecutorService, ThreadFactory}
89

@@ -20,6 +21,9 @@ object TestUtil {
2021
val detectCliPath = if (TestUtil.isNativeCli) TestUtil.cliPath else "scala-cli"
2122
val cli: Seq[String] = cliCommand(cliPath)
2223

24+
lazy val isArmArchitecture: Boolean =
25+
sys.props.getOrElse("os.arch", "").toLowerCase(Locale.ROOT) == "aarch64"
26+
2327
def cliCommand(cliPath: String): Seq[String] =
2428
if (isNativeCli)
2529
Seq(cliPath)

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import dependency.AnyDependency
88
import scala.build.internal.CsLoggerUtil._
99
import scala.build.internal.OsLibc
1010
import scala.build.options.BuildOptions.JavaHomeInfo
11-
import scala.build.{Position, Positioned}
11+
import scala.build.{Os, Position, Positioned}
1212
import scala.concurrent.ExecutionContextExecutorService
1313
import scala.util.control.NonFatal
1414

@@ -75,9 +75,14 @@ final case class JavaOptions(
7575
val enforceLiberica =
7676
finalJvmIndexOs == "linux-musl" &&
7777
jvmId.forall(c => c.isDigit || c == '.' || c == '-')
78+
val enforceZulu =
79+
Os.isArmArchitecture &&
80+
jvmId.forall(c => c.isDigit || c == '.' || c == '-')
7881
val jvmId0 =
7982
if (enforceLiberica)
8083
s"liberica:$jvmId" // FIXME Workaround, until this is automatically handled by coursier-jvm
84+
else if (enforceZulu) // default jvmId adoptium doesn't support java 8 for M1
85+
s"zulu:$jvmId"
8186
else
8287
jvmId
8388
val javaHomeManager0 = javaHomeManager(archiveCache, cache, verbosity)

project/deps.sc

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import coursier.mavenRepositoryString
22
import mill._, scalalib._
33

44
import scala.util.Properties
5+
import $file.utils, utils.isArmArchitecture
56

67
object Scala {
78
def scala212 = "2.12.16"
@@ -60,6 +61,7 @@ object Deps {
6061
// jni-utils version may need to be sync-ed when bumping the coursier version
6162
def coursier = "2.1.0-M6-53-gb4f448130"
6263
def coursierCli = "2.1.0-M5-18-gfebf9838c"
64+
def coursierM1Cli = "2.1.0-M6-53-gb4f448130"
6365
def jsoniterScala = "2.17.3"
6466
def jsoniterScalaJava8 = "2.13.5"
6567
def scalaMeta = "4.5.13"
@@ -103,7 +105,7 @@ object Deps {
103105
def jsoniterMacrosJava8 =
104106
ivy"com.github.plokhotnyuk.jsoniter-scala::jsoniter-scala-macros:${Versions.jsoniterScalaJava8}"
105107
def libdaemonjvm = ivy"io.github.alexarchambault.libdaemon::libdaemon:0.0.10"
106-
def libsodiumjni = ivy"io.github.alexarchambault.tmp.libsodiumjni:libsodiumjni:0.0.3"
108+
def libsodiumjni = ivy"org.virtuslab.scala-cli:libsodiumjni:0.0.3"
107109
def macroParadise = ivy"org.scalamacros:::paradise:2.1.1"
108110
def metaconfigTypesafe =
109111
ivy"com.geirsson::metaconfig-typesafe-config:0.11.1"
@@ -170,7 +172,8 @@ def graalVmJvmId = s"graalvm-java$graalVmJavaVersion:$graalVmVersion"
170172

171173
def csDockerVersion = Deps.Versions.coursierCli
172174

173-
def buildCsVersion = Deps.Versions.coursierCli
175+
def buildCsVersion = Deps.Versions.coursierCli
176+
def buildCsM1Version = Deps.Versions.coursierM1Cli
174177

175178
// Native library used to encrypt GitHub secrets
176179
def libsodiumVersion = "1.0.18"

project/settings.sc

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ import $ivy.`com.goyeau::mill-scalafix::0.2.8`
22
import $ivy.`io.github.alexarchambault.mill::mill-native-image::0.1.19`
33
import $ivy.`io.github.alexarchambault.mill::mill-scala-cli::0.1.0`
44

5-
import $file.deps, deps.{BuildDeps, Deps, Docker, alpineVersion, buildCsVersion, libsodiumVersion}
5+
import $file.deps,
6+
deps.{BuildDeps, Deps, Docker, alpineVersion, buildCsVersion, buildCsM1Version, libsodiumVersion}
7+
import $file.utils, utils.isArmArchitecture
68

79
import com.goyeau.mill.scalafix.ScalafixModule
810
import de.tobiasroeser.mill.vcs.version.VcsVersion
@@ -49,30 +51,35 @@ def fromPath(name: String): String =
4951

5052
def cs: T[String] = T.persistent {
5153

52-
val ext = if (Properties.isWin) ".exe" else ""
53-
val dest = T.dest / s"cs-$buildCsVersion$ext"
54+
val arch = sys.props.getOrElse("os.arch", "").toLowerCase(Locale.ROOT)
55+
val ext = if (Properties.isWin) ".exe" else ""
56+
val csVersion = if (arch == "aarch64" && Properties.isMac) buildCsM1Version else buildCsVersion
57+
val dest = T.dest / s"cs-$csVersion$ext"
5458

5559
def downloadOpt(): Option[String] = {
56-
val arch = sys.props.getOrElse("os.arch", "").toLowerCase(Locale.ROOT)
5760
val urlOpt = arch match {
5861
case "x86_64" | "amd64" =>
5962
if (Properties.isWin)
6063
Some(
61-
s"https://github.com/coursier/coursier/releases/download/v$buildCsVersion/cs-x86_64-pc-win32.zip"
64+
s"https://github.com/coursier/coursier/releases/download/v$csVersion/cs-x86_64-pc-win32.zip"
6265
)
6366
else if (Properties.isMac)
6467
Some(
65-
s"https://github.com/coursier/coursier/releases/download/v$buildCsVersion/cs-x86_64-apple-darwin.gz"
68+
s"https://github.com/coursier/coursier/releases/download/v$csVersion/cs-x86_64-apple-darwin.gz"
6669
)
6770
else if (Properties.isLinux)
6871
Some(
69-
s"https://github.com/coursier/coursier/releases/download/v$buildCsVersion/cs-x86_64-pc-linux.gz"
72+
s"https://github.com/coursier/coursier/releases/download/v$csVersion/cs-x86_64-pc-linux.gz"
7073
)
7174
else None
7275
case "aarch64" =>
7376
if (Properties.isLinux)
7477
Some(
75-
s"https://github.com/coursier/coursier/releases/download/v$buildCsVersion/cs-aarch64-pc-linux.gz"
78+
s"https://github.com/coursier/coursier/releases/download/v$csVersion/cs-aarch64-pc-linux.gz"
79+
)
80+
else if (Properties.isMac)
81+
Some(
82+
s"https://github.com/VirtusLab/coursier-m1/releases/download/v$csVersion/cs-aarch64-apple-darwin.gz"
7683
)
7784
else None
7885
case _ =>
@@ -196,6 +203,7 @@ trait CliLaunchers extends SbtModule { self =>
196203
case Some("x86_64" | "amd64") =>
197204
if (Properties.isWin) ("x86_64-pc-win32", "lib")
198205
else if (Properties.isLinux) ("x86_64-pc-linux", "a")
206+
else if (Properties.isMac && isArmArchitecture) ("aarch64-apple-darwin", "a")
199207
else if (Properties.isMac) ("x86_64-apple-darwin", "a")
200208
else sys.error(s"Unsupported OS for x86_64 platform: ${sys.props("os.name")}")
201209
case Some("aarch64") =>
@@ -210,7 +218,7 @@ trait CliLaunchers extends SbtModule { self =>
210218
cs,
211219
"fetch",
212220
"--intransitive",
213-
s"io.github.alexarchambault.tmp.libsodiumjni:libsodiumjni:$libsodiumjniVersion,classifier=$classifier,ext=$ext,type=$ext",
221+
s"org.virtuslab.scala-cli:libsodiumjni:$libsodiumjniVersion,classifier=$classifier,ext=$ext,type=$ext",
214222
"-A",
215223
ext
216224
).call()

0 commit comments

Comments
 (0)