gpui: make build dependencies mac only

Niklas Wimmer created

This removes bindgen and cbindgen from the dependency graph on non-macos
systems, improving compile times on those systems.

Signed-off-by: Niklas Wimmer <mail@nwimmer.me>

Change summary

crates/gpui/Cargo.toml |   2 
crates/gpui/build.rs   | 349 ++++++++++++++++++++++---------------------
2 files changed, 181 insertions(+), 170 deletions(-)

Detailed changes

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"
 

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<PathBuf> {
-        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<PathBuf> {
+            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);
+        }
     }
 }