From 97f1d61a4a9cc3e9ed4f13fa7e4893a316413345 Mon Sep 17 00:00:00 2001 From: Niklas Wimmer Date: Wed, 13 Mar 2024 14:34:47 +0100 Subject: [PATCH] gpui: make build dependencies mac only This removes bindgen and cbindgen from the dependency graph on non-macos systems, improving compile times on those systems. Signed-off-by: Niklas Wimmer --- crates/gpui/Cargo.toml | 2 +- crates/gpui/build.rs | 349 +++++++++++++++++++++-------------------- 2 files changed, 181 insertions(+), 170 deletions(-) diff --git a/crates/gpui/Cargo.toml b/crates/gpui/Cargo.toml index f76d83394706502dd6f762c99541774b2d400140..1f49943fb24ad6e391932a59d2b8565392c47ea2 100644 --- a/crates/gpui/Cargo.toml +++ b/crates/gpui/Cargo.toml @@ -78,7 +78,7 @@ backtrace = "0.3" collections = { workspace = true, features = ["test-support"] } util = { workspace = true, features = ["test-support"] } -[build-dependencies] +[target.'cfg(target_os = "macos")'.build-dependencies] bindgen = "0.65.1" cbindgen = "0.26.0" diff --git a/crates/gpui/build.rs b/crates/gpui/build.rs index c9c483d6b461d95582411f76e222c171c190afb6..1c87b391f693a3820f5c28642d2aebee30aa1bc7 100644 --- a/crates/gpui/build.rs +++ b/crates/gpui/build.rs @@ -1,186 +1,197 @@ #![cfg_attr(any(not(target_os = "macos"), feature = "macos-blade"), allow(unused))] -use std::{ - env, - path::{Path, PathBuf}, -}; - -use cbindgen::Config; - //TODO: consider generating shader code for WGSL //TODO: deprecate "runtime-shaders" and "macos-blade" fn main() { #[cfg(target_os = "macos")] - generate_dispatch_bindings(); - #[cfg(all(target_os = "macos", not(feature = "macos-blade")))] - let header_path = generate_shader_bindings(); - #[cfg(all(target_os = "macos", not(feature = "macos-blade")))] - #[cfg(feature = "runtime_shaders")] - emit_stitched_shaders(&header_path); - #[cfg(all(target_os = "macos", not(feature = "macos-blade")))] - #[cfg(not(feature = "runtime_shaders"))] - compile_metal_shaders(&header_path); + macos::build(); } -fn generate_dispatch_bindings() { - println!("cargo:rustc-link-lib=framework=System"); - println!("cargo:rerun-if-changed=src/platform/mac/dispatch.h"); - - let bindings = bindgen::Builder::default() - .header("src/platform/mac/dispatch.h") - .allowlist_var("_dispatch_main_q") - .allowlist_var("_dispatch_source_type_data_add") - .allowlist_var("DISPATCH_QUEUE_PRIORITY_DEFAULT") - .allowlist_var("DISPATCH_QUEUE_PRIORITY_HIGH") - .allowlist_var("DISPATCH_TIME_NOW") - .allowlist_function("dispatch_get_global_queue") - .allowlist_function("dispatch_async_f") - .allowlist_function("dispatch_after_f") - .allowlist_function("dispatch_time") - .allowlist_function("dispatch_source_merge_data") - .allowlist_function("dispatch_source_create") - .allowlist_function("dispatch_source_set_event_handler_f") - .allowlist_function("dispatch_resume") - .allowlist_function("dispatch_suspend") - .allowlist_function("dispatch_source_cancel") - .allowlist_function("dispatch_set_context") - .parse_callbacks(Box::new(bindgen::CargoCallbacks)) - .layout_tests(false) - .generate() - .expect("unable to generate bindings"); - - let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()); - bindings - .write_to_file(out_path.join("dispatch_sys.rs")) - .expect("couldn't write dispatch bindings"); -} - -fn generate_shader_bindings() -> PathBuf { - let output_path = PathBuf::from(env::var("OUT_DIR").unwrap()).join("scene.h"); - let crate_dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap()); - let mut config = Config::default(); - config.include_guard = Some("SCENE_H".into()); - config.language = cbindgen::Language::C; - config.export.include.extend([ - "Bounds".into(), - "Corners".into(), - "Edges".into(), - "Size".into(), - "Pixels".into(), - "PointF".into(), - "Hsla".into(), - "ContentMask".into(), - "Uniforms".into(), - "AtlasTile".into(), - "PathRasterizationInputIndex".into(), - "PathVertex_ScaledPixels".into(), - "ShadowInputIndex".into(), - "Shadow".into(), - "QuadInputIndex".into(), - "Underline".into(), - "UnderlineInputIndex".into(), - "Quad".into(), - "SpriteInputIndex".into(), - "MonochromeSprite".into(), - "PolychromeSprite".into(), - "PathSprite".into(), - "SurfaceInputIndex".into(), - "SurfaceBounds".into(), - "TransformationMatrix".into(), - ]); - config.no_includes = true; - config.enumeration.prefix_with_name = true; - - let mut builder = cbindgen::Builder::new(); - - let src_paths = [ - crate_dir.join("src/scene.rs"), - crate_dir.join("src/geometry.rs"), - crate_dir.join("src/color.rs"), - crate_dir.join("src/window.rs"), - crate_dir.join("src/platform.rs"), - crate_dir.join("src/platform/mac/metal_renderer.rs"), - ]; - for src_path in src_paths { - println!("cargo:rerun-if-changed={}", src_path.display()); - builder = builder.with_src(src_path); +#[cfg(target_os = "macos")] +mod macos { + use std::{ + env, + path::{Path, PathBuf}, + }; + + use cbindgen::Config; + + pub(super) fn build() { + generate_dispatch_bindings(); + #[cfg(not(feature = "macos-blade"))] + { + let header_path = generate_shader_bindings(); + + #[cfg(feature = "runtime_shaders")] + emit_stitched_shaders(&header_path); + #[cfg(not(feature = "runtime_shaders"))] + compile_metal_shaders(&header_path); + } } - builder - .with_config(config) - .generate() - .expect("Unable to generate bindings") - .write_to_file(&output_path); - - output_path -} + fn generate_dispatch_bindings() { + println!("cargo:rustc-link-lib=framework=System"); + println!("cargo:rerun-if-changed=src/platform/mac/dispatch.h"); + + let bindings = bindgen::Builder::default() + .header("src/platform/mac/dispatch.h") + .allowlist_var("_dispatch_main_q") + .allowlist_var("_dispatch_source_type_data_add") + .allowlist_var("DISPATCH_QUEUE_PRIORITY_DEFAULT") + .allowlist_var("DISPATCH_QUEUE_PRIORITY_HIGH") + .allowlist_var("DISPATCH_TIME_NOW") + .allowlist_function("dispatch_get_global_queue") + .allowlist_function("dispatch_async_f") + .allowlist_function("dispatch_after_f") + .allowlist_function("dispatch_time") + .allowlist_function("dispatch_source_merge_data") + .allowlist_function("dispatch_source_create") + .allowlist_function("dispatch_source_set_event_handler_f") + .allowlist_function("dispatch_resume") + .allowlist_function("dispatch_suspend") + .allowlist_function("dispatch_source_cancel") + .allowlist_function("dispatch_set_context") + .parse_callbacks(Box::new(bindgen::CargoCallbacks)) + .layout_tests(false) + .generate() + .expect("unable to generate bindings"); + + let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()); + bindings + .write_to_file(out_path.join("dispatch_sys.rs")) + .expect("couldn't write dispatch bindings"); + } -/// To enable runtime compilation, we need to "stitch" the shaders file with the generated header -/// so that it is self-contained. -#[cfg(feature = "runtime_shaders")] -fn emit_stitched_shaders(header_path: &Path) { - use std::str::FromStr; - fn stitch_header(header: &Path, shader_path: &Path) -> std::io::Result { - let header_contents = std::fs::read_to_string(header)?; - let shader_contents = std::fs::read_to_string(shader_path)?; - let stitched_contents = format!("{header_contents}\n{shader_contents}"); - let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()).join("stitched_shaders.metal"); - std::fs::write(&out_path, stitched_contents)?; - Ok(out_path) + fn generate_shader_bindings() -> PathBuf { + let output_path = PathBuf::from(env::var("OUT_DIR").unwrap()).join("scene.h"); + let crate_dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap()); + let mut config = Config::default(); + config.include_guard = Some("SCENE_H".into()); + config.language = cbindgen::Language::C; + config.export.include.extend([ + "Bounds".into(), + "Corners".into(), + "Edges".into(), + "Size".into(), + "Pixels".into(), + "PointF".into(), + "Hsla".into(), + "ContentMask".into(), + "Uniforms".into(), + "AtlasTile".into(), + "PathRasterizationInputIndex".into(), + "PathVertex_ScaledPixels".into(), + "ShadowInputIndex".into(), + "Shadow".into(), + "QuadInputIndex".into(), + "Underline".into(), + "UnderlineInputIndex".into(), + "Quad".into(), + "SpriteInputIndex".into(), + "MonochromeSprite".into(), + "PolychromeSprite".into(), + "PathSprite".into(), + "SurfaceInputIndex".into(), + "SurfaceBounds".into(), + "TransformationMatrix".into(), + ]); + config.no_includes = true; + config.enumeration.prefix_with_name = true; + + let mut builder = cbindgen::Builder::new(); + + let src_paths = [ + crate_dir.join("src/scene.rs"), + crate_dir.join("src/geometry.rs"), + crate_dir.join("src/color.rs"), + crate_dir.join("src/window.rs"), + crate_dir.join("src/platform.rs"), + crate_dir.join("src/platform/mac/metal_renderer.rs"), + ]; + for src_path in src_paths { + println!("cargo:rerun-if-changed={}", src_path.display()); + builder = builder.with_src(src_path); + } + + builder + .with_config(config) + .generate() + .expect("Unable to generate bindings") + .write_to_file(&output_path); + + output_path } - let shader_source_path = "./src/platform/mac/shaders.metal"; - let shader_path = PathBuf::from_str(shader_source_path).unwrap(); - stitch_header(header_path, &shader_path).unwrap(); - println!("cargo:rerun-if-changed={}", &shader_source_path); -} -#[cfg(not(feature = "runtime_shaders"))] -fn compile_metal_shaders(header_path: &Path) { - use std::process::{self, Command}; - let shader_path = "./src/platform/mac/shaders.metal"; - let air_output_path = PathBuf::from(env::var("OUT_DIR").unwrap()).join("shaders.air"); - let metallib_output_path = PathBuf::from(env::var("OUT_DIR").unwrap()).join("shaders.metallib"); - println!("cargo:rerun-if-changed={}", shader_path); - - let output = Command::new("xcrun") - .args([ - "-sdk", - "macosx", - "metal", - "-gline-tables-only", - "-mmacosx-version-min=10.15.7", - "-MO", - "-c", - shader_path, - "-include", - &header_path.to_str().unwrap(), - "-o", - ]) - .arg(&air_output_path) - .output() - .unwrap(); - - if !output.status.success() { - eprintln!( - "metal shader compilation failed:\n{}", - String::from_utf8_lossy(&output.stderr) - ); - process::exit(1); + + /// To enable runtime compilation, we need to "stitch" the shaders file with the generated header + /// so that it is self-contained. + #[cfg(feature = "runtime_shaders")] + fn emit_stitched_shaders(header_path: &Path) { + use std::str::FromStr; + fn stitch_header(header: &Path, shader_path: &Path) -> std::io::Result { + let header_contents = std::fs::read_to_string(header)?; + let shader_contents = std::fs::read_to_string(shader_path)?; + let stitched_contents = format!("{header_contents}\n{shader_contents}"); + let out_path = + PathBuf::from(env::var("OUT_DIR").unwrap()).join("stitched_shaders.metal"); + std::fs::write(&out_path, stitched_contents)?; + Ok(out_path) + } + let shader_source_path = "./src/platform/mac/shaders.metal"; + let shader_path = PathBuf::from_str(shader_source_path).unwrap(); + stitch_header(header_path, &shader_path).unwrap(); + println!("cargo:rerun-if-changed={}", &shader_source_path); } - let output = Command::new("xcrun") - .args(["-sdk", "macosx", "metallib"]) - .arg(air_output_path) - .arg("-o") - .arg(metallib_output_path) - .output() - .unwrap(); - - if !output.status.success() { - eprintln!( - "metallib compilation failed:\n{}", - String::from_utf8_lossy(&output.stderr) - ); - process::exit(1); + #[cfg(not(feature = "runtime_shaders"))] + fn compile_metal_shaders(header_path: &Path) { + use std::process::{self, Command}; + let shader_path = "./src/platform/mac/shaders.metal"; + let air_output_path = PathBuf::from(env::var("OUT_DIR").unwrap()).join("shaders.air"); + let metallib_output_path = + PathBuf::from(env::var("OUT_DIR").unwrap()).join("shaders.metallib"); + println!("cargo:rerun-if-changed={}", shader_path); + + let output = Command::new("xcrun") + .args([ + "-sdk", + "macosx", + "metal", + "-gline-tables-only", + "-mmacosx-version-min=10.15.7", + "-MO", + "-c", + shader_path, + "-include", + &header_path.to_str().unwrap(), + "-o", + ]) + .arg(&air_output_path) + .output() + .unwrap(); + + if !output.status.success() { + eprintln!( + "metal shader compilation failed:\n{}", + String::from_utf8_lossy(&output.stderr) + ); + process::exit(1); + } + + let output = Command::new("xcrun") + .args(["-sdk", "macosx", "metallib"]) + .arg(air_output_path) + .arg("-o") + .arg(metallib_output_path) + .output() + .unwrap(); + + if !output.status.success() { + eprintln!( + "metallib compilation failed:\n{}", + String::from_utf8_lossy(&output.stderr) + ); + process::exit(1); + } } }