Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 29 additions & 2 deletions crates/bender-slang/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand All @@ -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);
Expand All @@ -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 {
Expand Down Expand Up @@ -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
Expand Down
64 changes: 61 additions & 3 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand Down
Loading