From 6ee25bc31dbe53a9ee03b30686f964dd70d64a3a Mon Sep 17 00:00:00 2001 From: Tim Fischer Date: Thu, 29 Jan 2026 23:45:08 +0100 Subject: [PATCH 1/7] bender-slang(build): Link libc++ statically on linux and windows --- crates/bender-slang/build.rs | 39 +++++++++++++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/crates/bender-slang/build.rs b/crates/bender-slang/build.rs index 10ea4e63..983d9fcb 100644 --- a/crates/bender-slang/build.rs +++ b/crates/bender-slang/build.rs @@ -13,6 +13,7 @@ fn main() { .define("CMAKE_DISABLE_FIND_PACKAGE_fmt", "ON") // TODO(fischeti): Investigate how boost should be handled properly. .cxxflag("-DSLANG_BOOST_SINGLE_HEADER=1") + .static_crt(true) .build(); // Configure Linker to find Slang static library @@ -27,6 +28,7 @@ fn main() { bridge_build .file("cpp/slang_bridge.cpp") .flag_if_supported("-std=c++20") + .flag_if_supported("/std:c++20") // Static Linking Definition // Tells Slang headers not to look for DLL import/export symbols. .define("SLANG_STATIC_DEFINE", "1") @@ -35,11 +37,8 @@ fn main() { // TODO(fischeti): Investigate how boost should be handled properly. .define("SLANG_BOOST_SINGLE_HEADER", "1") // Include Paths - // 1. Slang source headers .include("vendor/slang/include") - // 2. Slang external headers (where boost_unordered.hpp lives) .include("vendor/slang/external") - // 3. CMake build output (where slang_export.h and fmt headers live) .include(dst.join("include")); // TODO(fischeti): Check whether debug definitions are necessary. @@ -47,6 +46,40 @@ fn main() { bridge_build.define("SLANG_DEBUG", "1"); } + // Linux: we try static linking of libstdc++ to avoid issues on older distros. + if std::env::var("CARGO_CFG_TARGET_OS").unwrap() == "linux" { + // Determine the C++ compiler to use. Respect the CXX environment variable if set. + let compiler = std::env::var("CXX").unwrap_or_else(|_| "g++".to_string()); + // We search for the static libstdc++ file using g++ + let output = std::process::Command::new(&compiler) + .args(&["-print-file-name=libstdc++.a"]) + .output() + .expect("Failed to run g++"); + + if output.status.success() { + let path_str = std::str::from_utf8(&output.stdout).unwrap().trim(); + let path = std::path::Path::new(path_str); + + if path.is_absolute() && path.exists() { + if let Some(parent) = path.parent() { + // Add the directory containing libstdc++.a to the link search path + println!("cargo:rustc-link-search=native={}", parent.display()); + } + + bridge_build.cpp_set_stdlib(None); + println!("cargo:rustc-link-lib=static=stdc++"); + } else { + println!( + "cargo:warning=Could not find static libstdc++.a, falling back to dynamic linking" + ); + } + } + // Windows / MSVC: we force static linking of the CRT to avoid missing DLL issues + } else if std::env::var("CARGO_CFG_TARGET_ENV").unwrap() == "msvc" { + bridge_build.static_crt(true); + } + // macOS: we leave the default dynamic linking of libc++ as is. + bridge_build.compile("slang-bridge"); println!("cargo:rerun-if-changed=src/lib.rs"); From cc06f2100a69a472f6c5b2f0c6bdb3cb31278e1e Mon Sep 17 00:00:00 2001 From: Tim Fischer Date: Thu, 29 Jan 2026 23:46:41 +0100 Subject: [PATCH 2/7] ci: Enable `slang` for Windows again --- .github/workflows/ci.yml | 4 ++-- .github/workflows/cli_regression.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 37b443a9..7130951a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -47,9 +47,9 @@ jobs: with: toolchain: stable - name: Build - run: cargo build + run: cargo build --all-features - name: Cargo Test - run: cargo test + run: cargo test --workspace --all-features - name: Run unit-tests run: tests/run_all.sh shell: bash diff --git a/.github/workflows/cli_regression.yml b/.github/workflows/cli_regression.yml index e9c93dee..bfdcf9bd 100644 --- a/.github/workflows/cli_regression.yml +++ b/.github/workflows/cli_regression.yml @@ -29,7 +29,7 @@ jobs: with: toolchain: stable - name: Run CLI Regression - run: cargo test --test cli_regression -- --ignored + run: cargo test --all-features --test cli_regression -- --ignored env: BENDER_TEST_GOLDEN_BRANCH: ${{ github.base_ref }} From 0bfddc1305b1d2640120542fe7de893e7b095d07 Mon Sep 17 00:00:00 2001 From: Tim Fischer Date: Sat, 31 Jan 2026 22:14:11 +0100 Subject: [PATCH 3/7] bender-slang(build): Fix `fmt` library in release builds --- crates/bender-slang/build.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/crates/bender-slang/build.rs b/crates/bender-slang/build.rs index 983d9fcb..cfb364df 100644 --- a/crates/bender-slang/build.rs +++ b/crates/bender-slang/build.rs @@ -21,7 +21,12 @@ fn main() { // Note: Linux is case-sensitive, so we use lowercase here. // On macOS, the library is called `svLang`, but the linker is case-insensitive there. println!("cargo:rustc-link-lib=static=svlang"); - println!("cargo:rustc-link-lib=static=fmtd"); + + if std::env::var("PROFILE").unwrap() == "debug" { + println!("cargo:rustc-link-lib=static=fmtd"); + } else { + println!("cargo:rustc-link-lib=static=fmt"); + } // Compile the C++ Bridge let mut bridge_build = cxx_build::bridge("src/lib.rs"); From 8c50812ca9c3d784071f347aa038f8823f052b67 Mon Sep 17 00:00:00 2001 From: Tim Fischer Date: Sat, 31 Jan 2026 22:53:45 +0100 Subject: [PATCH 4/7] bender-slang(build): Clean up --- crates/bender-slang/build.rs | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/crates/bender-slang/build.rs b/crates/bender-slang/build.rs index cfb364df..796020e7 100644 --- a/crates/bender-slang/build.rs +++ b/crates/bender-slang/build.rs @@ -1,6 +1,13 @@ fn main() { - // Build Slang with CMake into a static library - let dst = cmake::Config::new("vendor/slang") + let target_os = std::env::var("CARGO_CFG_TARGET_OS").unwrap(); + let target_env = std::env::var("CARGO_CFG_TARGET_ENV").unwrap(); + let build_profile = std::env::var("PROFILE").unwrap(); + + // Create the configuration builder + let mut slang_lib = cmake::Config::new("vendor/slang"); + + // Apply common settings + slang_lib .define("SLANG_INCLUDE_TESTS", "OFF") .define("SLANG_INCLUDE_TOOLS", "OFF") .define("SLANG_INCLUDE_PYSLANG", "OFF") @@ -18,14 +25,13 @@ fn main() { // Configure Linker to find Slang static library println!("cargo:rustc-link-search=native={}/lib", dst.display()); - // Note: Linux is case-sensitive, so we use lowercase here. - // On macOS, the library is called `svLang`, but the linker is case-insensitive there. println!("cargo:rustc-link-lib=static=svlang"); - if std::env::var("PROFILE").unwrap() == "debug" { - println!("cargo:rustc-link-lib=static=fmtd"); - } else { - println!("cargo:rustc-link-lib=static=fmt"); + // Link the appropriate fmt library based on build profile + match build_profile.as_str() { + "debug" => println!("cargo:rustc-link-lib=static=fmtd"), + "release" => println!("cargo:rustc-link-lib=static=fmt"), + _ => unreachable!(), } // Compile the C++ Bridge @@ -52,7 +58,7 @@ fn main() { } // Linux: we try static linking of libstdc++ to avoid issues on older distros. - if std::env::var("CARGO_CFG_TARGET_OS").unwrap() == "linux" { + if target_os == "linux" { // Determine the C++ compiler to use. Respect the CXX environment variable if set. let compiler = std::env::var("CXX").unwrap_or_else(|_| "g++".to_string()); // We search for the static libstdc++ file using g++ From 8f8987de9a09a5f990e4cf218ccffe9f0dd8e86f Mon Sep 17 00:00:00 2001 From: Tim Fischer Date: Sat, 31 Jan 2026 23:41:37 +0100 Subject: [PATCH 5/7] bender-slang(build): Enable `mimalloc` library again --- crates/bender-slang/build.rs | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/crates/bender-slang/build.rs b/crates/bender-slang/build.rs index 796020e7..40088672 100644 --- a/crates/bender-slang/build.rs +++ b/crates/bender-slang/build.rs @@ -14,8 +14,6 @@ fn main() { .define("BUILD_SHARED_LIBS", "OFF") // Forces installation into 'lib' instead of 'lib64' on some systems. .define("CMAKE_INSTALL_LIBDIR", "lib") - // TODO(fischeti): Check whether mimalloc can/should be enabled again. - .define("SLANG_USE_MIMALLOC", "OFF") // TODO(fischeti): `fmt` currently causes issues on my machine since there is a system-wide installation. .define("CMAKE_DISABLE_FIND_PACKAGE_fmt", "ON") // TODO(fischeti): Investigate how boost should be handled properly. @@ -27,11 +25,13 @@ fn main() { println!("cargo:rustc-link-search=native={}/lib", dst.display()); println!("cargo:rustc-link-lib=static=svlang"); - // Link the appropriate fmt library based on build profile - match build_profile.as_str() { - "debug" => println!("cargo:rustc-link-lib=static=fmtd"), - "release" => println!("cargo:rustc-link-lib=static=fmt"), - _ => unreachable!(), + // Link the additional libraries based on build profile + if build_profile == "debug" { + println!("cargo:rustc-link-lib=static=fmtd"); + println!("cargo:rustc-link-lib=static=mimalloc-debug") + } else { + println!("cargo:rustc-link-lib=static=fmt"); + println!("cargo:rustc-link-lib=static=mimalloc") } // Compile the C++ Bridge @@ -52,11 +52,6 @@ fn main() { .include("vendor/slang/external") .include(dst.join("include")); - // TODO(fischeti): Check whether debug definitions are necessary. - if std::env::var("PROFILE").unwrap() == "debug" { - bridge_build.define("SLANG_DEBUG", "1"); - } - // Linux: we try static linking of libstdc++ to avoid issues on older distros. if target_os == "linux" { // Determine the C++ compiler to use. Respect the CXX environment variable if set. From 7c3211fcf50a9018ac24e603db8d98f510082dfb Mon Sep 17 00:00:00 2001 From: Tim Fischer Date: Sat, 31 Jan 2026 22:54:07 +0100 Subject: [PATCH 6/7] bender-slang(build): Fix windows build --- .github/workflows/ci.yml | 4 +-- .github/workflows/cli_regression.yml | 2 +- crates/bender-slang/build.rs | 42 ++++++++++++++++++---------- 3 files changed, 30 insertions(+), 18 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7130951a..5a05403f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -47,9 +47,9 @@ jobs: with: toolchain: stable - name: Build - run: cargo build --all-features + run: cargo build --all-features --release - name: Cargo Test - run: cargo test --workspace --all-features + run: cargo test --workspace --all-features --release - name: Run unit-tests run: tests/run_all.sh shell: bash diff --git a/.github/workflows/cli_regression.yml b/.github/workflows/cli_regression.yml index bfdcf9bd..91069aef 100644 --- a/.github/workflows/cli_regression.yml +++ b/.github/workflows/cli_regression.yml @@ -29,7 +29,7 @@ jobs: with: toolchain: stable - name: Run CLI Regression - run: cargo test --all-features --test cli_regression -- --ignored + run: cargo test --all-features --test cli_regression --release -- --ignored env: BENDER_TEST_GOLDEN_BRANCH: ${{ github.base_ref }} diff --git a/crates/bender-slang/build.rs b/crates/bender-slang/build.rs index 40088672..8132e1a7 100644 --- a/crates/bender-slang/build.rs +++ b/crates/bender-slang/build.rs @@ -17,21 +17,31 @@ fn main() { // TODO(fischeti): `fmt` currently causes issues on my machine since there is a system-wide installation. .define("CMAKE_DISABLE_FIND_PACKAGE_fmt", "ON") // TODO(fischeti): Investigate how boost should be handled properly. - .cxxflag("-DSLANG_BOOST_SINGLE_HEADER=1") - .static_crt(true) - .build(); + .cxxflag("-DSLANG_BOOST_SINGLE_HEADER=1"); + + // Windows / MSVC specific flags + if target_env == "msvc" { + slang_lib.cxxflag("/EHsc").cxxflag("/utf-8"); + } + + // Build the slang library + let dst = slang_lib.build(); // Configure Linker to find Slang static library println!("cargo:rustc-link-search=native={}/lib", dst.display()); println!("cargo:rustc-link-lib=static=svlang"); - // Link the additional libraries based on build profile - if build_profile == "debug" { - println!("cargo:rustc-link-lib=static=fmtd"); - println!("cargo:rustc-link-lib=static=mimalloc-debug") - } else { - println!("cargo:rustc-link-lib=static=fmt"); - println!("cargo:rustc-link-lib=static=mimalloc") + // Link the additional libraries based on build profile and OS + match (build_profile.as_str(), target_env.as_str()) { + ("release", _) | (_, "msvc") => { + println!("cargo:rustc-link-lib=static=fmt"); + println!("cargo:rustc-link-lib=static=mimalloc"); + } + ("debug", _) => { + println!("cargo:rustc-link-lib=static=fmtd"); + println!("cargo:rustc-link-lib=static=mimalloc-debug"); + } + _ => unreachable!(), } // Compile the C++ Bridge @@ -39,7 +49,6 @@ fn main() { bridge_build .file("cpp/slang_bridge.cpp") .flag_if_supported("-std=c++20") - .flag_if_supported("/std:c++20") // Static Linking Definition // Tells Slang headers not to look for DLL import/export symbols. .define("SLANG_STATIC_DEFINE", "1") @@ -80,10 +89,13 @@ fn main() { ); } } - // Windows / MSVC: we force static linking of the CRT to avoid missing DLL issues - } else if std::env::var("CARGO_CFG_TARGET_ENV").unwrap() == "msvc" { - bridge_build.static_crt(true); - } + // Windows / MSVC: we set the appropriate flags for C++20 and exception handling. + } else if target_env == "msvc" { + bridge_build + .flag_if_supported("/std:c++20") + .flag("/EHsc") + .flag("/utf-8"); + }; // macOS: we leave the default dynamic linking of libc++ as is. bridge_build.compile("slang-bridge"); From 9f579f1e844de785dd210fe0bf8bede35beed444 Mon Sep 17 00:00:00 2001 From: Tim Fischer Date: Sun, 1 Feb 2026 00:46:32 +0100 Subject: [PATCH 7/7] bender-slang(build): Don't use system-installed slang dependencies --- crates/bender-slang/build.rs | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/crates/bender-slang/build.rs b/crates/bender-slang/build.rs index 8132e1a7..e253fc80 100644 --- a/crates/bender-slang/build.rs +++ b/crates/bender-slang/build.rs @@ -14,10 +14,10 @@ fn main() { .define("BUILD_SHARED_LIBS", "OFF") // Forces installation into 'lib' instead of 'lib64' on some systems. .define("CMAKE_INSTALL_LIBDIR", "lib") - // TODO(fischeti): `fmt` currently causes issues on my machine since there is a system-wide installation. + // Disable finding system-installed packages, we want to fetch and build them from source. .define("CMAKE_DISABLE_FIND_PACKAGE_fmt", "ON") - // TODO(fischeti): Investigate how boost should be handled properly. - .cxxflag("-DSLANG_BOOST_SINGLE_HEADER=1"); + .define("CMAKE_DISABLE_FIND_PACKAGE_mimalloc", "ON") + .define("CMAKE_DISABLE_FIND_PACKAGE_Boost", "ON"); // Windows / MSVC specific flags if target_env == "msvc" { @@ -49,14 +49,10 @@ fn main() { bridge_build .file("cpp/slang_bridge.cpp") .flag_if_supported("-std=c++20") - // Static Linking Definition // Tells Slang headers not to look for DLL import/export symbols. .define("SLANG_STATIC_DEFINE", "1") - // Boost Vendored Mode - // Tells Slang to use the local 'external/boost_*.hpp' files instead of system Boost. - // TODO(fischeti): Investigate how boost should be handled properly. + // Tells Slang to use vendor-provided instead of system-installed Boost header files. .define("SLANG_BOOST_SINGLE_HEADER", "1") - // Include Paths .include("vendor/slang/include") .include("vendor/slang/external") .include(dst.join("include"));