From ee756fa25cdac7765cd437f1faa9db6d5a3153e7 Mon Sep 17 00:00:00 2001 From: Mikayla Date: Fri, 16 Feb 2024 12:46:11 -0800 Subject: [PATCH] Encapsulate the changes needed for the blade renderer --- crates/gpui/src/gpui.rs | 4 - crates/gpui/src/platform.rs | 6 + .../gpui/src/{render.rs => platform/blade.rs} | 0 .../{render => platform/blade}/blade_atlas.rs | 0 .../{render => platform/blade}/blade_belt.rs | 0 .../blade}/blade_renderer.rs | 101 ++++++++++++-- .../{render => platform/blade}/shaders.wgsl | 0 crates/gpui/src/platform/mac.rs | 15 +- .../gpui/src/platform/mac/metal_renderer.rs | 51 ++++--- crates/gpui/src/platform/mac/platform.rs | 11 +- crates/gpui/src/platform/mac/window.rs | 131 ++++-------------- script/bundle | 10 +- 12 files changed, 170 insertions(+), 159 deletions(-) rename crates/gpui/src/{render.rs => platform/blade.rs} (100%) rename crates/gpui/src/{render => platform/blade}/blade_atlas.rs (100%) rename crates/gpui/src/{render => platform/blade}/blade_belt.rs (100%) rename crates/gpui/src/{render => platform/blade}/blade_renderer.rs (91%) rename crates/gpui/src/{render => platform/blade}/shaders.wgsl (100%) diff --git a/crates/gpui/src/gpui.rs b/crates/gpui/src/gpui.rs index 318dafbdc6..79115a8d78 100644 --- a/crates/gpui/src/gpui.rs +++ b/crates/gpui/src/gpui.rs @@ -81,8 +81,6 @@ mod key_dispatch; mod keymap; mod platform; pub mod prelude; -#[cfg(any(not(target_os = "macos"), feature = "macos-blade"))] -mod render; mod scene; mod shared_string; mod shared_uri; @@ -132,8 +130,6 @@ use key_dispatch::*; pub use keymap::*; pub use platform::*; pub use refineable::*; -#[cfg(any(not(target_os = "macos"), feature = "macos-blade"))] -use render::*; pub use scene::*; use seal::Sealed; pub use shared_string::*; diff --git a/crates/gpui/src/platform.rs b/crates/gpui/src/platform.rs index 6739fee6fc..cf3ded1285 100644 --- a/crates/gpui/src/platform.rs +++ b/crates/gpui/src/platform.rs @@ -3,10 +3,16 @@ mod app_menu; mod keystroke; + #[cfg(target_os = "linux")] mod linux; + #[cfg(target_os = "macos")] mod mac; + +#[cfg(any(target_os = "linux", feature = "macos-blade"))] +mod blade; + #[cfg(any(test, feature = "test-support"))] mod test; diff --git a/crates/gpui/src/render.rs b/crates/gpui/src/platform/blade.rs similarity index 100% rename from crates/gpui/src/render.rs rename to crates/gpui/src/platform/blade.rs diff --git a/crates/gpui/src/render/blade_atlas.rs b/crates/gpui/src/platform/blade/blade_atlas.rs similarity index 100% rename from crates/gpui/src/render/blade_atlas.rs rename to crates/gpui/src/platform/blade/blade_atlas.rs diff --git a/crates/gpui/src/render/blade_belt.rs b/crates/gpui/src/platform/blade/blade_belt.rs similarity index 100% rename from crates/gpui/src/render/blade_belt.rs rename to crates/gpui/src/platform/blade/blade_belt.rs diff --git a/crates/gpui/src/render/blade_renderer.rs b/crates/gpui/src/platform/blade/blade_renderer.rs similarity index 91% rename from crates/gpui/src/render/blade_renderer.rs rename to crates/gpui/src/platform/blade/blade_renderer.rs index 26577735d4..4ca8bae97c 100644 --- a/crates/gpui/src/render/blade_renderer.rs +++ b/crates/gpui/src/platform/blade/blade_renderer.rs @@ -1,16 +1,18 @@ // Doing `if let` gives you nice scoping with passes/encoders #![allow(irrefutable_let_patterns)] -use super::{BladeBelt, BladeBeltDescriptor}; +use super::{BladeAtlas, BladeBelt, BladeBeltDescriptor, PATH_TEXTURE_FORMAT}; use crate::{ - AtlasTextureKind, AtlasTile, BladeAtlas, Bounds, ContentMask, Hsla, MonochromeSprite, Path, - PathId, PathVertex, PolychromeSprite, PrimitiveBatch, Quad, ScaledPixels, Scene, Shadow, - Underline, PATH_TEXTURE_FORMAT, + AtlasTextureKind, AtlasTile, Bounds, ContentMask, Hsla, MonochromeSprite, Path, PathId, + PathVertex, PolychromeSprite, PrimitiveBatch, Quad, ScaledPixels, Scene, Shadow, Size, + Underline, }; use bytemuck::{Pod, Zeroable}; use collections::HashMap; #[cfg(target_os = "macos")] use media::core_video::CVMetalTextureCache; +#[cfg(target_os = "macos")] +use std::ffi::c_void; use blade_graphics as gpu; use std::{mem, sync::Arc}; @@ -18,6 +20,61 @@ use std::{mem, sync::Arc}; const SURFACE_FRAME_COUNT: u32 = 3; const MAX_FRAME_TIME_MS: u32 = 1000; +pub type Context = (); +pub type Renderer = BladeRenderer; + +#[cfg(target_os = "macos")] +pub unsafe fn new_renderer( + _context: self::Context, + native_window: *mut c_void, + native_view: *mut c_void, + bounds: crate::Size, +) -> Renderer { + struct RawWindow { + window: *mut c_void, + view: *mut c_void, + } + + unsafe impl blade_rwh::HasRawWindowHandle for RawWindow { + fn raw_window_handle(&self) -> blade_rwh::RawWindowHandle { + let mut wh = blade_rwh::AppKitWindowHandle::empty(); + wh.ns_window = self.window; + wh.ns_view = self.view; + wh.into() + } + } + + unsafe impl blade_rwh::HasRawDisplayHandle for RawWindow { + fn raw_display_handle(&self) -> blade_rwh::RawDisplayHandle { + let dh = blade_rwh::AppKitDisplayHandle::empty(); + dh.into() + } + } + + let gpu = Arc::new( + gpu::Context::init_windowed( + &RawWindow { + window: native_window as *mut _, + view: native_view as *mut _, + }, + gpu::ContextDesc { + validation: cfg!(debug_assertions), + capture: false, + }, + ) + .unwrap(), + ); + + BladeRenderer::new( + gpu, + gpu::Extent { + width: bounds.width as u32, + height: bounds.height as u32, + depth: 1, + }, + ) +} + #[repr(C)] #[derive(Clone, Copy, Pod, Zeroable)] struct GlobalParams { @@ -354,17 +411,18 @@ impl BladeRenderer { } } - pub fn destroy(&mut self) { - self.wait_for_gpu(); - self.atlas.destroy(); - self.instance_belt.destroy(&self.gpu); - self.gpu.destroy_command_encoder(&mut self.command_encoder); - } + pub fn update_drawable_size(&mut self, size: Size) { + let gpu_size = gpu::Extent { + width: size.width as u32, + height: size.height as u32, + depth: 1, + }; - pub fn resize(&mut self, size: gpu::Extent) { - self.wait_for_gpu(); - self.gpu.resize(Self::make_surface_config(size)); - self.viewport_size = size; + if gpu_size != self.viewport_size() { + self.wait_for_gpu(); + self.gpu.resize(Self::make_surface_config(gpu_size)); + self.viewport_size = gpu_size; + } } pub fn viewport_size(&self) -> gpu::Extent { @@ -380,6 +438,12 @@ impl BladeRenderer { self.gpu.metal_layer().unwrap() } + #[cfg(target_os = "macos")] + pub fn layer_ptr(&self) -> *mut metal::CAMetalLayer { + use metal::foreign_types::ForeignType as _; + self.gpu.metal_layer().unwrap().as_ptr() + } + fn rasterize_paths(&mut self, paths: &[Path]) { self.path_tiles.clear(); let mut vertices_by_texture_id = HashMap::default(); @@ -432,6 +496,13 @@ impl BladeRenderer { } } + pub fn destroy(&mut self) { + self.wait_for_gpu(); + self.atlas.destroy(); + self.instance_belt.destroy(&self.gpu); + self.gpu.destroy_command_encoder(&mut self.command_encoder); + } + pub fn draw(&mut self, scene: &Scene) { let frame = self.gpu.acquire_frame(); self.command_encoder.start(); @@ -646,4 +717,4 @@ impl BladeRenderer { self.wait_for_gpu(); self.last_sync_point = Some(sync_point); } -} +} \ No newline at end of file diff --git a/crates/gpui/src/render/shaders.wgsl b/crates/gpui/src/platform/blade/shaders.wgsl similarity index 100% rename from crates/gpui/src/render/shaders.wgsl rename to crates/gpui/src/platform/blade/shaders.wgsl diff --git a/crates/gpui/src/platform/mac.rs b/crates/gpui/src/platform/mac.rs index b976b27682..15d10225ba 100644 --- a/crates/gpui/src/platform/mac.rs +++ b/crates/gpui/src/platform/mac.rs @@ -4,10 +4,18 @@ mod dispatcher; mod display; mod display_link; mod events; + #[cfg(not(feature = "macos-blade"))] mod metal_atlas; #[cfg(not(feature = "macos-blade"))] -mod metal_renderer; +pub mod metal_renderer; + +#[cfg(not(feature = "macos-blade"))] +use metal_renderer as renderer; + +#[cfg(feature = "macos-blade")] +use crate::platform::blade as renderer; + mod open_type; mod platform; mod text_system; @@ -19,16 +27,13 @@ use cocoa::{ base::{id, nil}, foundation::{NSAutoreleasePool, NSNotFound, NSRect, NSSize, NSString, NSUInteger}, }; -#[cfg(not(feature = "macos-blade"))] -use metal_renderer::*; + use objc::runtime::{BOOL, NO, YES}; use std::ops::Range; pub(crate) use dispatcher::*; pub(crate) use display::*; pub(crate) use display_link::*; -#[cfg(not(feature = "macos-blade"))] -pub(crate) use metal_atlas::*; pub(crate) use platform::*; pub(crate) use text_system::*; pub(crate) use window::*; diff --git a/crates/gpui/src/platform/mac/metal_renderer.rs b/crates/gpui/src/platform/mac/metal_renderer.rs index 6b30787b52..a82a643c76 100644 --- a/crates/gpui/src/platform/mac/metal_renderer.rs +++ b/crates/gpui/src/platform/mac/metal_renderer.rs @@ -1,8 +1,9 @@ use crate::{ platform::mac::ns_string, point, size, AtlasTextureId, AtlasTextureKind, AtlasTile, Bounds, - ContentMask, DevicePixels, Hsla, MetalAtlas, MonochromeSprite, Path, PathId, PathVertex, + ContentMask, DevicePixels, Hsla, MonochromeSprite, Path, PathId, PathVertex, PolychromeSprite, PrimitiveBatch, Quad, ScaledPixels, Scene, Shadow, Size, Surface, Underline, }; +use super::metal_atlas::MetalAtlas; use block::ConcreteBlock; use cocoa::{ base::{nil, NO, YES}, @@ -13,7 +14,7 @@ use collections::HashMap; use core_foundation::base::TCFType; use foreign_types::ForeignType; use media::core_video::CVMetalTextureCache; -use metal::{CommandQueue, MTLPixelFormat, MTLResourceOptions, NSRange}; +use metal::{CAMetalLayer, CommandQueue, MTLPixelFormat, MTLResourceOptions, NSRange}; use objc::{self, msg_send, sel, sel_impl}; use parking_lot::Mutex; use smallvec::SmallVec; @@ -29,6 +30,18 @@ const SHADERS_SOURCE_FILE: &'static str = include_str!(concat!(env!("OUT_DIR"), "/stitched_shaders.metal")); const INSTANCE_BUFFER_SIZE: usize = 2 * 1024 * 1024; // This is an arbitrary decision. There's probably a more optimal value (maybe even we could adjust dynamically...) +pub type Context = Arc>>; +pub type Renderer = MetalRenderer; + +pub unsafe fn new_renderer( + context: self::Context, + _native_window: *mut c_void, + _native_view: *mut c_void, + _bounds: crate::Size, +) -> Renderer { + MetalRenderer::new(context) +} + pub(crate) struct MetalRenderer { device: metal::Device, layer: metal::MetalLayer, @@ -196,25 +209,12 @@ impl MetalRenderer { &self.layer } - pub fn sprite_atlas(&self) -> &Arc { - &self.sprite_atlas + pub fn layer_ptr(&self) -> *mut CAMetalLayer { + self.layer.as_ptr() } - /// Enables or disables the Metal HUD for debugging purposes. Note that this only works - /// when the app is bundled and it has the `MetalHudEnabled` key set to true in Info.plist. - pub fn set_hud_enabled(&mut self, enabled: bool) { - unsafe { - if enabled { - let hud_properties = NSDictionary::dictionaryWithObject_forKey_( - nil, - ns_string("default"), - ns_string("mode"), - ); - let _: () = msg_send![&*self.layer, setDeveloperHUDProperties: hud_properties]; - } else { - let _: () = msg_send![&*self.layer, setDeveloperHUDProperties: NSDictionary::dictionary(nil)]; - } - } + pub fn sprite_atlas(&self) -> &Arc { + &self.sprite_atlas } pub fn set_presents_with_transaction(&mut self, presents_with_transaction: bool) { @@ -223,6 +223,19 @@ impl MetalRenderer { .set_presents_with_transaction(presents_with_transaction); } + pub fn update_drawable_size(&mut self, size: Size) { + unsafe { + let _: () = msg_send![ + self.layer(), + setDrawableSize: size + ]; + } + } + + pub fn destroy(&mut self) { + // nothing to do + } + pub fn draw(&mut self, scene: &Scene) { let layer = self.layer.clone(); let viewport_size = layer.drawable_size(); diff --git a/crates/gpui/src/platform/mac/platform.rs b/crates/gpui/src/platform/mac/platform.rs index b5d2441ed8..473fb5978a 100644 --- a/crates/gpui/src/platform/mac/platform.rs +++ b/crates/gpui/src/platform/mac/platform.rs @@ -52,6 +52,8 @@ use std::{ }; use time::UtcOffset; +use super::renderer; + #[allow(non_upper_case_globals)] const NSUTF8StringEncoding: NSUInteger = 4; @@ -145,8 +147,7 @@ pub(crate) struct MacPlatformState { background_executor: BackgroundExecutor, foreground_executor: ForegroundExecutor, text_system: Arc, - #[cfg(not(feature = "macos-blade"))] - instance_buffer_pool: Arc>>, + renderer_context: renderer::Context, pasteboard: id, text_hash_pasteboard_type: id, metadata_pasteboard_type: id, @@ -176,8 +177,7 @@ impl MacPlatform { background_executor: BackgroundExecutor::new(dispatcher.clone()), foreground_executor: ForegroundExecutor::new(dispatcher), text_system: Arc::new(MacTextSystem::new()), - #[cfg(not(feature = "macos-blade"))] - instance_buffer_pool: Arc::default(), + renderer_context: renderer::Context::default(), pasteboard: unsafe { NSPasteboard::generalPasteboard(nil) }, text_hash_pasteboard_type: unsafe { ns_string("zed-text-hash") }, metadata_pasteboard_type: unsafe { ns_string("zed-metadata") }, @@ -500,8 +500,7 @@ impl Platform for MacPlatform { handle, options, self.foreground_executor(), - #[cfg(not(feature = "macos-blade"))] - self.0.lock().instance_buffer_pool.clone(), + self.0.lock().renderer_context.clone(), )) } diff --git a/crates/gpui/src/platform/mac/window.rs b/crates/gpui/src/platform/mac/window.rs index 85a397c9f5..70767cc49b 100644 --- a/crates/gpui/src/platform/mac/window.rs +++ b/crates/gpui/src/platform/mac/window.rs @@ -1,8 +1,4 @@ -#[cfg(not(feature = "macos-blade"))] -use super::MetalRenderer; -use super::{global_bounds_from_ns_rect, ns_string, MacDisplay, NSRange}; -#[cfg(feature = "macos-blade")] -use crate::BladeRenderer; +use super::{global_bounds_from_ns_rect, ns_string, MacDisplay, NSRange, renderer}; use crate::{ global_bounds_to_ns_rect, platform::PlatformInputHandler, point, px, size, AnyWindowHandle, Bounds, DisplayLink, ExternalPaths, FileDropEvent, ForegroundExecutor, GlobalPixels, @@ -11,8 +7,6 @@ use crate::{ PlatformWindow, Point, PromptLevel, Size, Timer, WindowAppearance, WindowBounds, WindowKind, WindowOptions, }; -#[cfg(feature = "macos-blade")] -use blade_graphics as gpu; use block::ConcreteBlock; use cocoa::{ appkit::{ @@ -327,10 +321,7 @@ struct MacWindowState { native_window: id, native_view: NonNull, display_link: Option, - #[cfg(not(feature = "macos-blade"))] - renderer: MetalRenderer, - #[cfg(feature = "macos-blade")] - renderer: BladeRenderer, + renderer: renderer::Renderer, kind: WindowKind, request_frame_callback: Option>, event_callback: Option bool>>, @@ -459,24 +450,10 @@ impl MacWindowState { } fn update_drawable_size(&mut self, drawable_size: NSSize) { - #[cfg(not(feature = "macos-blade"))] - unsafe { - let _: () = msg_send![ - self.renderer.layer(), - setDrawableSize: drawable_size - ]; - } - #[cfg(feature = "macos-blade")] - { - let gpu_size = gpu::Extent { - width: drawable_size.width as u32, - height: drawable_size.height as u32, - depth: 1, - }; - if gpu_size != self.renderer.viewport_size() { - self.renderer.resize(gpu_size); - } - } + self.renderer.update_drawable_size(Size { + width: drawable_size.width, + height: drawable_size.height, + }) } fn titlebar_height(&self) -> Pixels { @@ -500,27 +477,6 @@ impl MacWindowState { unsafe impl Send for MacWindowState {} -#[cfg(feature = "macos-blade")] -struct RawWindow { - window: *mut c_void, - view: *mut c_void, -} -#[cfg(feature = "macos-blade")] -unsafe impl blade_rwh::HasRawWindowHandle for RawWindow { - fn raw_window_handle(&self) -> blade_rwh::RawWindowHandle { - let mut wh = blade_rwh::AppKitWindowHandle::empty(); - wh.ns_window = self.window; - wh.ns_view = self.view; - wh.into() - } -} -#[cfg(feature = "macos-blade")] -unsafe impl blade_rwh::HasRawDisplayHandle for RawWindow { - fn raw_display_handle(&self) -> blade_rwh::RawDisplayHandle { - let dh = blade_rwh::AppKitDisplayHandle::empty(); - dh.into() - } -} pub(crate) struct MacWindow(Arc>); @@ -529,7 +485,7 @@ impl MacWindow { handle: AnyWindowHandle, options: WindowOptions, executor: ForegroundExecutor, - #[cfg(not(feature = "macos-blade"))] instance_buffer_pool: Arc>>, + renderer_context: renderer::Context, ) -> Self { unsafe { let pool = NSAutoreleasePool::new(nil); @@ -592,22 +548,7 @@ impl MacWindow { let native_view = NSView::init(native_view); assert!(!native_view.is_null()); - #[cfg(feature = "macos-blade")] - let gpu = Arc::new( - gpu::Context::init_windowed( - &RawWindow { - window: native_window as *mut _, - view: native_view as *mut _, - }, - gpu::ContextDesc { - validation: cfg!(debug_assertions), - capture: false, - }, - ) - .unwrap(), - ); - #[cfg(feature = "macos-blade")] - let gpu_size = { + let window_size = { let bounds = match options.bounds { WindowBounds::Fullscreen | WindowBounds::Maximized => { native_window.screen().visibleFrame() @@ -615,11 +556,7 @@ impl MacWindow { WindowBounds::Fixed(bounds) => global_bounds_to_ns_rect(bounds), }; let scale = get_scale_factor(native_window); - gpu::Extent { - width: (bounds.size.width as f32 * scale) as u32, - height: (bounds.size.height as f32 * scale) as u32, - depth: 1, - } + size(bounds.size.width as f32 * scale, bounds.size.height as f32 * scale) }; let window = Self(Arc::new(Mutex::new(MacWindowState { @@ -628,10 +565,7 @@ impl MacWindow { native_window, native_view: NonNull::new_unchecked(native_view), display_link: None, - #[cfg(not(feature = "macos-blade"))] - renderer: MetalRenderer::new(instance_buffer_pool), - #[cfg(feature = "macos-blade")] - renderer: BladeRenderer::new(gpu, gpu_size), + renderer: renderer::new_renderer(renderer_context, native_window as *mut _, native_view as *mut _, window_size), kind: options.kind, request_frame_callback: None, event_callback: None, @@ -666,23 +600,6 @@ impl MacWindow { Arc::into_raw(window.0.clone()) as *const c_void, ); - #[cfg(feature = "macos-blade")] - if false { - //TODO - // Hook up resize notification - let notification_center: id = - msg_send![class!(NSNotificationCenter), defaultCenter]; - let frame_did_change_notification_name = - NSString::alloc(nil).init_str("NSViewFrameDidChangeNotification"); - let _: () = msg_send![ - notification_center, - addObserver: native_view - selector: sel!(frameDidChange:) - name: &*frame_did_change_notification_name - object: native_view - ]; - } - if let Some(title) = options .titlebar .as_ref() @@ -805,7 +722,6 @@ impl MacWindow { impl Drop for MacWindow { fn drop(&mut self) { let mut this = self.0.lock(); - #[cfg(feature = "macos-blade")] this.renderer.destroy(); let window = this.native_window; this.display_link.take(); @@ -1134,10 +1050,22 @@ impl PlatformWindow for MacWindow { /// Enables or disables the Metal HUD for debugging purposes. Note that this only works /// when the app is bundled and it has the `MetalHudEnabled` key set to true in Info.plist. fn set_graphics_profiler_enabled(&self, enabled: bool) { - #[cfg(not(feature = "macos-blade"))] - self.0.lock().renderer.set_hud_enabled(enabled); - #[cfg(feature = "macos-blade")] - let _ = enabled; + let this_lock = self.0.lock(); + let layer = this_lock.renderer.layer(); + + unsafe { + if enabled { + let hud_properties = NSDictionary::dictionaryWithObject_forKey_( + nil, + ns_string("default"), + ns_string("mode"), + ); + let _: () = msg_send![layer, setDeveloperHUDProperties: hud_properties]; + } else { + let _: () = msg_send![layer, setDeveloperHUDProperties: NSDictionary::dictionary(nil)]; + } + } + } } @@ -1591,14 +1519,9 @@ extern "C" fn close_window(this: &Object, _: Sel) { } extern "C" fn make_backing_layer(this: &Object, _: Sel) -> id { - #[cfg(not(feature = "macos-blade"))] - use foreign_types::ForeignTypeRef as _; - #[cfg(feature = "macos-blade")] - use metal::foreign_types::ForeignType as _; - let window_state = unsafe { get_window_state(this) }; let window_state = window_state.as_ref().lock(); - window_state.renderer.layer().as_ptr() as id + window_state.renderer.layer_ptr() as id } extern "C" fn view_did_change_backing_properties(this: &Object, _: Sel) { diff --git a/script/bundle b/script/bundle index 7eced084c2..a3ff52d6d7 100755 --- a/script/bundle +++ b/script/bundle @@ -135,16 +135,14 @@ echo "Bundled ${app_path}" if [ "$local_arch" = false ]; then echo "Uploading dSYMs" - dsymutil --flat target/aarch64-apple-darwin/release/Zed - dsymutil --flat target/x86_64-apple-darwin/release/Zed + dsymutil --flat target/aarch64-apple-darwin/${target_dir}/Zed + dsymutil --flat target/x86_64-apple-darwin/${target_dir}/Zed version="$(cargo metadata --no-deps --manifest-path crates/zed/Cargo.toml --offline --format-version=1 | jq -r '.packages | map(select(.name == "zed"))[0].version')" if [ "$channel" == "nightly" ]; then version="$version-$(git rev-parse --short HEAD)" fi - gzip target/aarch64-apple-darwin/release/Zed.dwarf - gzip target/x86_64-apple-darwin/release/Zed.dwarf - uploadDsym target/aarch64-apple-darwin/release/Zed.dwarf.gz "$channel/Zed-$version-aarch64-apple-darwin.dwarf.gz" - uploadDsym target/x86_64-apple-darwin/release/Zed.dwarf.gz "$channel/Zed-$version-x86_64-apple-darwin.dwarf.gz" + gzip target/aarch64-apple-darwin/${target_dir}/Zed.dwarf + gzip target/x86_64-apple-darwin/${target_dir}/Zed.dwarf echo "Creating fat binaries" lipo \