From 8aaf3f2ca2dbce5f40f9e0d1695ea03c0579c19f Mon Sep 17 00:00:00 2001 From: Wodann Date: Sat, 27 Aug 2022 14:44:28 -0500 Subject: [PATCH] feat: add Mac M1 support --- CHANGELOG.md | 4 ++ crates/mun/Cargo.toml | 2 +- crates/mun_codegen/Cargo.toml | 1 + crates/mun_codegen/src/assembly.rs | 9 +++++ crates/mun_runtime/src/lib.rs | 39 ++++++++++++------- crates/mun_runtime/tests/memory.rs | 10 ++--- crates/mun_target/src/spec.rs | 4 +- .../src/spec/aarch64_apple_darwin.rs | 22 +++++++++++ crates/mun_target/src/spec/apple_base.rs | 1 + 9 files changed, 70 insertions(+), 22 deletions(-) create mode 100644 crates/mun_target/src/spec/aarch64_apple_darwin.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index 4d3cbf183..6ac316692 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Added + +- Mac M1 Support [#](https://github.com/mun-lang/mun/pull/444) + ## [0.3.0] - 2021-04-12 The third Mun release includes big usability improvements; multi-file projects, a language server with diagnostics and autocompletion, and improvements to robustness and developer workflow to name a few. diff --git a/crates/mun/Cargo.toml b/crates/mun/Cargo.toml index 4cdfd6b1a..f2d9daea7 100644 --- a/crates/mun/Cargo.toml +++ b/crates/mun/Cargo.toml @@ -17,13 +17,13 @@ default-run = "mun" anyhow = "1.0.31" clap = { version = "3.1.18", features=["derive"] } log = "0.4" -pretty_env_logger = "0.4" mun_abi = { version = "=0.3.0", path = "../mun_abi" } mun_compiler = { version = "=0.3.0", path = "../mun_compiler" } mun_compiler_daemon = { version = "=0.3.0", path = "../mun_compiler_daemon" } mun_runtime = { version = "=0.3.0", path = "../mun_runtime" } mun_language_server = { version = "=0.1.0", path = "../mun_language_server" } mun_project = { version = "=0.1.0", path = "../mun_project" } +pretty_env_logger = "0.4" [dev-dependencies.cargo-husky] version = "1" diff --git a/crates/mun_codegen/Cargo.toml b/crates/mun_codegen/Cargo.toml index b5b8d6157..fe0012302 100644 --- a/crates/mun_codegen/Cargo.toml +++ b/crates/mun_codegen/Cargo.toml @@ -15,6 +15,7 @@ categories = ["Game development", "Mun"] [dependencies] rustc-hash = "1.1.0" abi = { version = "=0.3.0", path = "../mun_abi", package = "mun_abi" } +apple-codesign = "0.17.0" bytemuck = "1.4.1" hir = { version = "=0.3.0", path = "../mun_hir", package = "mun_hir" } itertools = "0.10.3" diff --git a/crates/mun_codegen/src/assembly.rs b/crates/mun_codegen/src/assembly.rs index 4eeed52ef..caf29280e 100644 --- a/crates/mun_codegen/src/assembly.rs +++ b/crates/mun_codegen/src/assembly.rs @@ -4,6 +4,7 @@ use crate::{ ModuleGroupId, }; use anyhow::anyhow; +use apple_codesign::{SigningSettings, UnifiedSigner}; use inkwell::context::Context; use std::{path::Path, sync::Arc}; use tempfile::NamedTempFile; @@ -106,6 +107,14 @@ pub(crate) fn build_target_assembly( .into_shared_object(file.path()) .expect("could not link object file"); + let target = db.target(); + if target.options.is_like_osx { + let signer = UnifiedSigner::new(SigningSettings::default()); + signer + .sign_path_in_place(file.path()) + .expect("Failed to sign shared object"); + } + Arc::new(TargetAssembly { file }) } diff --git a/crates/mun_runtime/src/lib.rs b/crates/mun_runtime/src/lib.rs index 72e950c52..6d0502eaf 100644 --- a/crates/mun_runtime/src/lib.rs +++ b/crates/mun_runtime/src/lib.rs @@ -16,7 +16,7 @@ mod reflection; use anyhow::Result; use dispatch_table::DispatchTable; use garbage_collector::GarbageCollector; -use log::{debug, error, info}; +use log::{debug, error, info, warn}; use memory::{ gc::{self, GcRuntime}, type_table::TypeTable, @@ -379,6 +379,7 @@ impl Runtime { ) } + let mut requires_relink = false; while let Ok(event) = self.watcher_rx.try_recv() { if let Some(path) = event.path { let op = event.op.expect("Invalid event."); @@ -390,18 +391,7 @@ impl Runtime { if op.contains(notify::op::REMOVE) { debug!("Lockfile deleted"); - match relink_assemblies(self) { - Ok((dispatch_table, type_table)) => { - info!("Succesfully reloaded assemblies."); - - self.dispatch_table = dispatch_table; - self.type_table = type_table; - self.assemblies_to_relink.clear(); - - return true; - } - Err(e) => error!("Failed to relink assemblies, due to {}.", e), - } + requires_relink = true; } } else { let path = path.canonicalize().unwrap_or_else(|_| { @@ -416,7 +406,9 @@ impl Runtime { } else { self.renamed_files.insert(cookie, path); } - } else if op.contains(notify::op::WRITE) { + } else if op.intersects( + notify::op::CREATE | notify::op::WRITE | notify::op::CLOSE_WRITE, + ) { // TODO: don't overwrite existing self.assemblies_to_relink.push_back((path.clone(), path)); } @@ -424,6 +416,25 @@ impl Runtime { } } + if requires_relink { + if self.assemblies_to_relink.is_empty() { + debug!("The compiler didn't write a munlib."); + } else { + match relink_assemblies(self) { + Ok((dispatch_table, type_table)) => { + info!("Succesfully reloaded assemblies."); + + self.dispatch_table = dispatch_table; + self.type_table = type_table; + self.assemblies_to_relink.clear(); + + return true; + } + Err(e) => error!("Failed to relink assemblies, due to {}.", e), + } + } + } + false } diff --git a/crates/mun_runtime/tests/memory.rs b/crates/mun_runtime/tests/memory.rs index 70359a229..84957e6e7 100644 --- a/crates/mun_runtime/tests/memory.rs +++ b/crates/mun_runtime/tests/memory.rs @@ -327,15 +327,15 @@ fn map_struct_cast_fields1() { ); assert_eq!( foo_struct.as_ref(&driver.runtime).get::("0").unwrap(), - a.into() + u16::from(a) ); assert_eq!( foo_struct.as_ref(&driver.runtime).get::("1").unwrap(), - b.into() + i32::from(b) ); assert_eq!( foo_struct.as_ref(&driver.runtime).get::("2").unwrap(), - c.into() + u64::from(c) ); assert_eq!( foo_struct.as_ref(&driver.runtime).get::("3").unwrap(), @@ -343,7 +343,7 @@ fn map_struct_cast_fields1() { ); assert_eq!( foo_struct.as_ref(&driver.runtime).get::("4").unwrap(), - e.into() + f64::from(e) ); } @@ -625,7 +625,7 @@ fn map_struct_all() { ); assert_eq!( foo_struct.as_ref(&driver.runtime).get::("d").unwrap(), - d.into() + i64::from(d) ); assert_eq!( foo_struct.as_ref(&driver.runtime).get::("e").unwrap(), diff --git a/crates/mun_target/src/spec.rs b/crates/mun_target/src/spec.rs index e25127554..2e508a9e2 100644 --- a/crates/mun_target/src/spec.rs +++ b/crates/mun_target/src/spec.rs @@ -3,8 +3,7 @@ mod apple_sdk_base; mod linux_base; mod windows_msvc_base; -use crate::abi::Endian; -use crate::host_triple; +use crate::{abi::Endian, host_triple}; #[derive(Debug, Clone, Copy, Eq, Ord, PartialOrd, PartialEq, Hash)] pub enum LinkerFlavor { @@ -137,6 +136,7 @@ supported_targets!( ("x86_64-apple-ios", x86_64_apple_ios), ("x86_64-pc-windows-msvc", x86_64_pc_windows_msvc), ("x86_64-unknown-linux-gnu", x86_64_unknown_linux_gnu), + ("aarch64-apple-darwin", aarch64_apple_darwin), ("aarch64-apple-ios", aarch64_apple_ios), ("aarch64-apple-ios-sim", aarch64_apple_ios_sim), ); diff --git a/crates/mun_target/src/spec/aarch64_apple_darwin.rs b/crates/mun_target/src/spec/aarch64_apple_darwin.rs new file mode 100644 index 000000000..8b66d3f87 --- /dev/null +++ b/crates/mun_target/src/spec/aarch64_apple_darwin.rs @@ -0,0 +1,22 @@ +use crate::spec::{Target, TargetOptions}; + +pub fn target() -> Target { + // Clang automatically chooses a more specific target based on + // MACOSX_DEPLOYMENT_TARGET. To enable cross-language LTO to work + // correctly, we do too. + let arch = "arm64"; + let llvm_target = super::apple_base::ios_llvm_target(arch); + let (major, minor) = super::apple_base::macos_deployment_target(arch); + + Target { + llvm_target, + pointer_width: 64, + arch: "aarch64".into(), + data_layout: "e-m:o-i64:64-i128:128-n32:64-S128".into(), + options: TargetOptions { + cpu: "apple-a14".into(), + min_os_version: Some((major, minor, 0)), + .. super::apple_base::opts("macos") + }, + } +} \ No newline at end of file diff --git a/crates/mun_target/src/spec/apple_base.rs b/crates/mun_target/src/spec/apple_base.rs index 6e9f95f2f..be2e0bfe6 100644 --- a/crates/mun_target/src/spec/apple_base.rs +++ b/crates/mun_target/src/spec/apple_base.rs @@ -7,6 +7,7 @@ pub fn opts(os: &'static str) -> TargetOptions { vendor: "apple".into(), linker_flavor: LinkerFlavor::Ld64, dll_prefix: "lib".to_string(), + is_like_osx: os == "macos", ..Default::default() } }