diff --git a/build.sbt b/build.sbt index 3d996e6df79..37bc4b59e7e 100644 --- a/build.sbt +++ b/build.sbt @@ -2846,9 +2846,11 @@ buildProjectManagerDistribution := { lazy val buildGraalDistribution = taskKey[Unit]("Builds the GraalVM distribution") buildGraalDistribution := { - val log = streams.value.log - val distOs = "DIST_OS" - val osName = "os.name" + val log = streams.value.log + val distOs = "DIST_OS" + val distArch = "DIST_ARCH" + val osName = "os.name" + val archName = "os.arch" val distName = sys.env.get(distOs).getOrElse { val name = sys.props(osName).takeWhile(!_.isWhitespace) if (sys.env.contains("CI")) { @@ -2858,13 +2860,14 @@ buildGraalDistribution := { } name } - val os = DistributionPackage.OS(distName).getOrElse { + val arch = sys.env.get(distArch).orElse(sys.env.get(archName)) + val os = DistributionPackage.OS(distName, arch).getOrElse { throw new RuntimeException(s"Failed to determine OS: $distName.") } packageBuilder.createGraalPackage( log, os, - DistributionPackage.Architecture.X64 + os.archs.head ) } diff --git a/lib/scala/cli/src/main/scala/org/enso/cli/OS.scala b/lib/scala/cli/src/main/scala/org/enso/cli/OS.scala index a1e537726e3..34161eebc2c 100644 --- a/lib/scala/cli/src/main/scala/org/enso/cli/OS.scala +++ b/lib/scala/cli/src/main/scala/org/enso/cli/OS.scala @@ -118,17 +118,10 @@ object OS { } /** Name of the architecture that the program is running on. - * - * Currently the Launcher Native Image builds only support amd64 - * architecture, so it is hardcoded here. In the future, more architectures - * may be supported. In that case, this will need to be updated to get the - * target architecture from the build settings. - * - * This property should not use `System.getProperty("os.arch")` directly - * because it can return different values for the same architecture (for - * example on some systems `amd64` is called `x86_64`). */ - val architecture: String = "amd64" + val architecture: String = + if (System.getProperty("os.arch").contains("aarch64")) "aarch64" + else "amd64" /** Wraps the base executable name with an optional platform-dependent * extension. diff --git a/project/DistributionPackage.scala b/project/DistributionPackage.scala index 14b51b6d736..3d6690e7628 100644 --- a/project/DistributionPackage.scala +++ b/project/DistributionPackage.scala @@ -436,15 +436,25 @@ object DistributionPackage { def executableName(base: String): String = base def archiveExt: String = ".tar.gz" def isUNIX: Boolean = true + def archs: Seq[Architecture] } object OS { case object Linux extends OS { override val name: String = "linux" override val hasSupportForSulong: Boolean = true + override val archs = Seq(Architecture.X64) } - case object MacOS extends OS { - override val name: String = "macos" + trait MacOS extends OS { + override val name: String = "macos" + } + case object MacOSAmd extends MacOS { override val hasSupportForSulong: Boolean = true + override val archs = Seq(Architecture.X64) + } + + case object MacOSArm extends MacOS { + override val hasSupportForSulong: Boolean = true + override val archs = Seq(Architecture.AarchX64) } case object Windows extends OS { override val name: String = "windows" @@ -452,16 +462,26 @@ object DistributionPackage { override def executableName(base: String): String = base + ".exe" override def archiveExt: String = ".zip" override def isUNIX: Boolean = false + override val archs = Seq(Architecture.X64) } - val platforms = Seq(Linux, MacOS, Windows) + val platforms = Seq(Linux, MacOSArm, MacOSAmd, Windows) - def apply(name: String): Option[OS] = + def apply(name: String, arch: Option[String]): Option[OS] = name.toLowerCase match { - case Linux.`name` => Some(Linux) - case MacOS.`name` => Some(MacOS) - case Windows.`name` => Some(Windows) - case _ => None + case Linux.`name` => Some(Linux) + case MacOSAmd.`name` => + arch match { + case Some(Architecture.X64.`name`) => + Some(MacOSAmd) + case Some(Architecture.AarchX64.`name`) => + Some(MacOSArm) + case _ => + None + } + case MacOSArm.`name` => Some(MacOSArm) + case Windows.`name` => Some(Windows) + case _ => None } } @@ -474,11 +494,15 @@ object DistributionPackage { } object Architecture { case object X64 extends Architecture { - override def name: String = "amd64" + override val name: String = "amd64" + override def graalName: String = "x64" + } + + case object AarchX64 extends Architecture { + override val name: String = "aarch64" override def graalName: String = "x64" } - val archs = Seq(X64) } /** A helper class that manages building distribution artifacts. */ @@ -672,7 +696,7 @@ object DistributionPackage { val executableFile = os match { case OS.Linux => shallowFile - case OS.MacOS => + case _: OS.MacOS => if (deepFile.exists) { deepFile } else { @@ -768,13 +792,19 @@ object DistributionPackage { /** Path to the artifact that is built on this local machine. */ def localArtifact(component: String): File = { - val architecture = Architecture.X64 val os = if (Platform.isWindows) OS.Windows else if (Platform.isLinux) OS.Linux - else if (Platform.isMacOS) OS.MacOS - else throw new IllegalStateException("Unknown OS") - artifactRoot / artifactName(component, os, architecture) + else if (Platform.isMacOS) { + if (Platform.isAmd64) OS.MacOSAmd + else if (Platform.isArm64) OS.MacOSArm + else + throw new IllegalStateException( + "Unknown Arch: " + sys.props("os.arch") + ) + } else + throw new IllegalStateException("Unknown OS: " + sys.props("os.name")) + artifactRoot / artifactName(component, os, os.archs.head) } /** Path to a built archive. @@ -814,7 +844,7 @@ object DistributionPackage { val log = state.log for { os <- OS.platforms - arch <- Architecture.archs + arch <- os.archs } { val launcher = builtArtifact("launcher", os, arch) if (launcher.exists()) { @@ -853,7 +883,7 @@ object DistributionPackage { val log = state.log for { os <- OS.platforms - arch <- Architecture.archs + arch <- os.archs } { val launcher = builtArtifact("launcher", os, arch) if (launcher.exists()) { diff --git a/project/Platform.scala b/project/Platform.scala index 23efa7ba3a9..7dda29e257e 100644 --- a/project/Platform.scala +++ b/project/Platform.scala @@ -15,6 +15,14 @@ object Platform { def isMacOS: Boolean = sys.props("os.name").toLowerCase().contains("mac") + def isAmd64: Boolean = { + val arch = sys.props("os.arch").toLowerCase() + arch.contains("amd64") || arch.contains("x86_64") + } + + def isArm64: Boolean = + sys.props("os.arch").toLowerCase().contains("aarch64") + /** Returns the dynamic library file name on the current platform. * * @param libraryName the library name