From 22f8838285a37579e7d5cfcd2f792298b20ee24b Mon Sep 17 00:00:00 2001 From: Kai Berszin Date: Fri, 3 Jul 2026 16:42:50 +0200 Subject: [PATCH] flake: fix build with slang feature --- crates/bender-slang/build.rs | 31 +++++++++++++++-- flake.nix | 64 ++++++++++++++++++++++++++++++++++-- 2 files changed, 90 insertions(+), 5 deletions(-) diff --git a/crates/bender-slang/build.rs b/crates/bender-slang/build.rs index ef7518ab..487aa3b0 100644 --- a/crates/bender-slang/build.rs +++ b/crates/bender-slang/build.rs @@ -45,6 +45,13 @@ fn main() { vec!["-std=c++20"] }; + // Allow overriding FetchContent source directories via environment variables. + // This is used by Nix (and other sandboxed build systems) where network access + // is blocked and dependencies must be pre-fetched. + let slang_src_dir = std::env::var("SLANG_SRC_DIR").ok(); + let fmt_src_dir = std::env::var("FMT_SRC_DIR").ok(); + let mimalloc_src_dir = std::env::var("MIMALLOC_SRC_DIR").ok(); + // Apply cmake configuration for Slang library slang_lib .define("SLANG_INCLUDE_TESTS", "OFF") @@ -57,6 +64,16 @@ fn main() { .define("CMAKE_DISABLE_FIND_PACKAGE_Boost", "ON") .profile(cmake_profile); + if let Some(ref dir) = slang_src_dir { + slang_lib.define("FETCHCONTENT_SOURCE_DIR_SLANG", dir); + } + if let Some(ref dir) = fmt_src_dir { + slang_lib.define("FETCHCONTENT_SOURCE_DIR_FMT", dir); + } + if let Some(ref dir) = mimalloc_src_dir { + slang_lib.define("FETCHCONTENT_SOURCE_DIR_MIMALLOC", dir); + } + // Apply common defines and flags for (def, value) in common_cxx_defines.iter() { slang_lib.define(def, *value); @@ -70,10 +87,17 @@ fn main() { let dst = slang_lib.build(); // With FetchContent, cmake builds slang in a _deps subdirectory rather than // installing it. Point directly at the FetchContent build/source directories. + // When source dirs are overridden, include paths come from those instead. let slang_lib_dir = dst.join("build/_deps/slang-build/lib"); - let slang_include_dir = dst.join("build/_deps/slang-src/include"); + let slang_include_dir = match slang_src_dir { + Some(dir) => std::path::PathBuf::from(dir).join("include"), + None => dst.join("build/_deps/slang-src/include"), + }; let slang_generated_include_dir = dst.join("build/_deps/slang-build/source"); - let fmt_include_dir = dst.join("build/_deps/fmt-src/include"); + let fmt_include_dir = match fmt_src_dir { + Some(dir) => std::path::PathBuf::from(dir).join("include"), + None => dst.join("build/_deps/fmt-src/include"), + }; // Generate cpp/compile_flags.txt for clangd IDE support if !in_publish { @@ -138,6 +162,9 @@ fn main() { println!("cargo:rerun-if-changed=cpp/rewriter.cpp"); println!("cargo:rerun-if-changed=cpp/print.cpp"); println!("cargo:rerun-if-changed=cpp/analysis.cpp"); + println!("cargo:rerun-if-env-changed=SLANG_SRC_DIR"); + println!("cargo:rerun-if-env-changed=FMT_SRC_DIR"); + println!("cargo:rerun-if-env-changed=MIMALLOC_SRC_DIR"); } // Generates cpp/compile_flags.txt so that clangd gets the correct include paths diff --git a/flake.nix b/flake.nix index 53e7ab75..b85302d0 100644 --- a/flake.nix +++ b/flake.nix @@ -18,20 +18,78 @@ system: let pkgs = nixpkgs.legacyPackages.${system}; - teraTemplFilter = path: _type: builtins.match ".*src/script_fmt/.*tera" path != null; - benderFilter = path: type: ((craneLib.filterCargoSources path type) || (teraTemplFilter path type)); + + # Pre-fetched sources for bender-slang's cmake FetchContent dependencies. + # The Nix sandbox blocks network access, so we fetch these ourselves and + # inject them via FETCHCONTENT_SOURCE_DIR_* variables in build.rs. + slangSrc = pkgs.fetchFromGitHub { + owner = "MikePopoloski"; + repo = "slang"; + tag = "v11.0"; + hash = "sha256-popHzwX0qwv2POAl7/qX3e//OwJRXGtSl9xogpSn2LI="; + }; + fmtSrc = pkgs.fetchFromGitHub { + owner = "fmtlib"; + repo = "fmt"; + tag = "12.1.0"; + hash = "sha256-ZmI1Dv0ZabPlxa02OpERI47jp7zFfjpeWCy1WyuPYZ0="; + }; + mimallocSrc = pkgs.fetchFromGitHub { + owner = "microsoft"; + repo = "mimalloc"; + tag = "v3.3.2"; + hash = "sha256-GZ37qQVDe9jgMb4Coe5oKvgaLTspZDlSkS5rdy1MfUU="; + }; craneLib = crane.mkLib pkgs; + + # Source filter: cargo sources + tera templates + bender-slang C++/CMake files + test fixtures + slangCrateFilter = path: _type: + builtins.match ".*/crates/bender-slang/(cpp/.*|CMakeLists\\.txt|build\\.rs)" path != null; + teraTemplFilter = path: _type: builtins.match ".*src/script_fmt/.*tera" path != null; + testFixtureFilter = path: _type: builtins.match ".*/tests/.*" path != null; + benderFilter = path: type: + (craneLib.filterCargoSources path type) + || (teraTemplFilter path type) + || (slangCrateFilter path type) + || (testFixtureFilter path type); + src = pkgs.lib.cleanSourceWith { src = ./.; filter = benderFilter; name = "bender-source"; }; - bender = craneLib.buildPackage { + commonArgs = { inherit src; strictDeps = true; + nativeBuildInputs = with pkgs; [ + cmake + python3 + ]; }; + + cargoArtifacts = craneLib.buildDepsOnly commonArgs; + + bender = craneLib.buildPackage (commonArgs // { + inherit cargoArtifacts; + + nativeCheckInputs = [ pkgs.gitMinimal ]; + + # Point build.rs at pre-fetched FetchContent sources + SLANG_SRC_DIR = slangSrc; + FMT_SRC_DIR = fmtSrc; + MIMALLOC_SRC_DIR = mimallocSrc; + + # owo-colors wraps test assertions in ANSI codes when TERM is set, + # causing string-matching tests to fail in the sandbox. + preCheck = "export NO_COLOR=1"; + + postCheck = '' + patchShebangs --build tests + BENDER="$PWD/target/''${CARGO_BUILD_TARGET:-}/release/bender" tests/run_all.sh + ''; + }); in { packages = {