Build distribution for amd64 and aarch64 MacOS (#8407)

* Build distribution for amd64 and aarch64 MacOS

Possible after the GraalVM upgrade.

* Another attempt at building on MacOS M1

* One less hardcoded architecture

* Eliminate one more hardcoded architecture

* add more debug info

* nit
This commit is contained in:
Hubert Plociniczak 2023-12-05 11:24:02 +01:00 committed by GitHub
parent a67297aebf
commit 49e78adb88
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 66 additions and 32 deletions

View File

@ -2848,7 +2848,9 @@ lazy val buildGraalDistribution =
buildGraalDistribution := { buildGraalDistribution := {
val log = streams.value.log val log = streams.value.log
val distOs = "DIST_OS" val distOs = "DIST_OS"
val distArch = "DIST_ARCH"
val osName = "os.name" val osName = "os.name"
val archName = "os.arch"
val distName = sys.env.get(distOs).getOrElse { val distName = sys.env.get(distOs).getOrElse {
val name = sys.props(osName).takeWhile(!_.isWhitespace) val name = sys.props(osName).takeWhile(!_.isWhitespace)
if (sys.env.contains("CI")) { if (sys.env.contains("CI")) {
@ -2858,13 +2860,14 @@ buildGraalDistribution := {
} }
name 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.") throw new RuntimeException(s"Failed to determine OS: $distName.")
} }
packageBuilder.createGraalPackage( packageBuilder.createGraalPackage(
log, log,
os, os,
DistributionPackage.Architecture.X64 os.archs.head
) )
} }

View File

@ -118,17 +118,10 @@ object OS {
} }
/** Name of the architecture that the program is running on. /** 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 /** Wraps the base executable name with an optional platform-dependent
* extension. * extension.

View File

@ -436,15 +436,25 @@ object DistributionPackage {
def executableName(base: String): String = base def executableName(base: String): String = base
def archiveExt: String = ".tar.gz" def archiveExt: String = ".tar.gz"
def isUNIX: Boolean = true def isUNIX: Boolean = true
def archs: Seq[Architecture]
} }
object OS { object OS {
case object Linux extends OS { case object Linux extends OS {
override val name: String = "linux" override val name: String = "linux"
override val hasSupportForSulong: Boolean = true override val hasSupportForSulong: Boolean = true
override val archs = Seq(Architecture.X64)
} }
case object MacOS extends OS { trait MacOS extends OS {
override val name: String = "macos" override val name: String = "macos"
}
case object MacOSAmd extends MacOS {
override val hasSupportForSulong: Boolean = true 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 { case object Windows extends OS {
override val name: String = "windows" override val name: String = "windows"
@ -452,14 +462,24 @@ object DistributionPackage {
override def executableName(base: String): String = base + ".exe" override def executableName(base: String): String = base + ".exe"
override def archiveExt: String = ".zip" override def archiveExt: String = ".zip"
override def isUNIX: Boolean = false 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 { name.toLowerCase match {
case Linux.`name` => Some(Linux) case Linux.`name` => Some(Linux)
case MacOS.`name` => Some(MacOS) 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 Windows.`name` => Some(Windows)
case _ => None case _ => None
} }
@ -474,11 +494,15 @@ object DistributionPackage {
} }
object Architecture { object Architecture {
case object X64 extends 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" override def graalName: String = "x64"
} }
val archs = Seq(X64)
} }
/** A helper class that manages building distribution artifacts. */ /** A helper class that manages building distribution artifacts. */
@ -672,7 +696,7 @@ object DistributionPackage {
val executableFile = os match { val executableFile = os match {
case OS.Linux => case OS.Linux =>
shallowFile shallowFile
case OS.MacOS => case _: OS.MacOS =>
if (deepFile.exists) { if (deepFile.exists) {
deepFile deepFile
} else { } else {
@ -768,13 +792,19 @@ object DistributionPackage {
/** Path to the artifact that is built on this local machine. */ /** Path to the artifact that is built on this local machine. */
def localArtifact(component: String): File = { def localArtifact(component: String): File = {
val architecture = Architecture.X64
val os = val os =
if (Platform.isWindows) OS.Windows if (Platform.isWindows) OS.Windows
else if (Platform.isLinux) OS.Linux else if (Platform.isLinux) OS.Linux
else if (Platform.isMacOS) OS.MacOS else if (Platform.isMacOS) {
else throw new IllegalStateException("Unknown OS") if (Platform.isAmd64) OS.MacOSAmd
artifactRoot / artifactName(component, os, architecture) 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. /** Path to a built archive.
@ -814,7 +844,7 @@ object DistributionPackage {
val log = state.log val log = state.log
for { for {
os <- OS.platforms os <- OS.platforms
arch <- Architecture.archs arch <- os.archs
} { } {
val launcher = builtArtifact("launcher", os, arch) val launcher = builtArtifact("launcher", os, arch)
if (launcher.exists()) { if (launcher.exists()) {
@ -853,7 +883,7 @@ object DistributionPackage {
val log = state.log val log = state.log
for { for {
os <- OS.platforms os <- OS.platforms
arch <- Architecture.archs arch <- os.archs
} { } {
val launcher = builtArtifact("launcher", os, arch) val launcher = builtArtifact("launcher", os, arch)
if (launcher.exists()) { if (launcher.exists()) {

View File

@ -15,6 +15,14 @@ object Platform {
def isMacOS: Boolean = def isMacOS: Boolean =
sys.props("os.name").toLowerCase().contains("mac") 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. /** Returns the dynamic library file name on the current platform.
* *
* @param libraryName the library name * @param libraryName the library name