From 20f0533d3e91c98acfad2e89097830914eac8bcf Mon Sep 17 00:00:00 2001 From: Zach Vorhies Date: Fri, 25 Sep 2026 21:26:01 -0700 Subject: [PATCH 1/5] ci: canary setup-soldr 218672f before v0 promotion Pins the build template to zackees/setup-soldr main 218672f8 (setup-soldr#530: no toolchain snapshots when solo-toolchain-cache is off) so the v0 promotion gate can verify it. --- .github/workflows/template_build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/template_build.yml b/.github/workflows/template_build.yml index 5df5f0d3..281f1043 100644 --- a/.github/workflows/template_build.yml +++ b/.github/workflows/template_build.yml @@ -48,7 +48,7 @@ jobs: - name: Setup soldr id: setup-soldr # Canary exact setup-soldr main SHA before v0 promotion. - uses: zackees/setup-soldr@a71cd1c92c72f8effbe65862e1440e9627678189 + uses: zackees/setup-soldr@218672f8a77500785cb73bdb49e184dbfff05f44 with: # cache-preset: foundation expands to: # build-cache: true, target-cache: false, From 36ce042b37c8634bb9efbd8ca578d9d512df72c1 Mon Sep 17 00:00:00 2001 From: Zach Vorhies Date: Fri, 25 Sep 2026 22:04:12 -0700 Subject: [PATCH 2/5] fix(build-engine): use NormalizedPath for the perf-log JSON sink #1470 cached FBUILD_PERF_LOG_JSON as a std::path::PathBuf, which the ban_std_pathbuf dylint rejects, failing Dylint Full on linux and windows. --- crates/fbuild-build-engine/src/perf_log.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/crates/fbuild-build-engine/src/perf_log.rs b/crates/fbuild-build-engine/src/perf_log.rs index b1b4efa7..c4c88e3a 100644 --- a/crates/fbuild-build-engine/src/perf_log.rs +++ b/crates/fbuild-build-engine/src/perf_log.rs @@ -29,8 +29,9 @@ //! // auto-summary on drop //! ``` +use fbuild_core::path::NormalizedPath; use std::io::Write; -use std::path::{Path, PathBuf}; +use std::path::Path; use std::sync::OnceLock; use std::sync::atomic::{AtomicBool, Ordering}; use std::time::{Duration, Instant}; @@ -57,13 +58,14 @@ pub fn enabled() -> bool { /// /// Cached after the first call. pub fn json_sink_path() -> Option<&'static Path> { - static SINK: OnceLock> = OnceLock::new(); + static SINK: OnceLock> = OnceLock::new(); SINK.get_or_init(|| { std::env::var_os("FBUILD_PERF_LOG_JSON") .filter(|v| !v.is_empty()) - .map(PathBuf::from) + .map(NormalizedPath::new) }) - .as_deref() + .as_ref() + .map(NormalizedPath::as_path) } /// Append `value` as a single JSON line to `path` (append + create). From 11c25a017527e9a9f64785b9379034d5f0588d1c Mon Sep 17 00:00:00 2001 From: Zach Vorhies Date: Fri, 25 Sep 2026 22:37:43 -0700 Subject: [PATCH 3/5] fix(bench): satisfy dylint in the build-comparison harness #1470 added find_compile_db and raw_baseline_ms with a std PathBuf, a raw .fbuild/build path and an unrooted TempDir, which ban_std_pathbuf, ban_raw_fbuild_path and ban_unrooted_tempdir reject. Use NormalizedPath, fbuild_paths::get_project_build_root and a TempDir under fbuild_paths::temp_subdir, as the bench's main.rs already does. --- bench/fastled-examples/src/build_comparison.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/bench/fastled-examples/src/build_comparison.rs b/bench/fastled-examples/src/build_comparison.rs index fda6a7b8..2981462c 100644 --- a/bench/fastled-examples/src/build_comparison.rs +++ b/bench/fastled-examples/src/build_comparison.rs @@ -11,7 +11,7 @@ use std::env; use std::ffi::{OsStr, OsString}; use std::fs::{self, File}; use std::io::{self, Write}; -use std::path::{Path, PathBuf}; +use std::path::Path; use std::process::{Command, Output}; use std::sync::Mutex; use std::sync::atomic::{AtomicUsize, Ordering}; @@ -423,11 +423,11 @@ fn phase_medians(trials: &[BTreeMap]) -> BTreeMap { } /// Locate the compile DB fbuild wrote for env `uno`. -fn find_compile_db(project_dir: &Path) -> Option { - fn search(dir: &Path) -> Option { +fn find_compile_db(project_dir: &Path) -> Option { + fn search(dir: &Path) -> Option { let candidate = dir.join("compile_commands.json"); if candidate.is_file() { - return Some(candidate); + return Some(NormalizedPath::from(candidate)); } let mut subdirs = fs::read_dir(dir) .ok()? @@ -438,9 +438,9 @@ fn find_compile_db(project_dir: &Path) -> Option { subdirs.sort(); subdirs.iter().find_map(|sub| search(sub)) } - search(&project_dir.join(".fbuild/build/uno")).or_else(|| { + search(&fbuild_paths::get_project_build_root(project_dir).join("uno")).or_else(|| { let fallback = project_dir.join("compile_commands.json"); - fallback.is_file().then_some(fallback) + fallback.is_file().then(|| NormalizedPath::from(fallback)) }) } @@ -575,7 +575,7 @@ fn rewrite_compile_argv(argv: &[String], output: &Path) -> Vec { /// Replay every compile DB entry with the bare compiler across `jobs` threads. fn raw_baseline_ms(entries: &[CompileEntry], jobs: usize) -> AppResult { - let temp = tempfile::TempDir::new()?; + let temp = tempfile::TempDir::new_in(fbuild_paths::temp_subdir("fastled-examples-bench"))?; let next = AtomicUsize::new(0); let failure: Mutex> = Mutex::new(None); let started = Instant::now(); From 8d4deeee909c938a5f46e4870ca7a5626404c301 Mon Sep 17 00:00:00 2001 From: Zach Vorhies Date: Fri, 25 Sep 2026 23:37:53 -0700 Subject: [PATCH 4/5] ci: canary setup-soldr dfbe962 (current main) before v0 promotion --- .github/workflows/template_build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/template_build.yml b/.github/workflows/template_build.yml index 281f1043..75d3fe3c 100644 --- a/.github/workflows/template_build.yml +++ b/.github/workflows/template_build.yml @@ -48,7 +48,7 @@ jobs: - name: Setup soldr id: setup-soldr # Canary exact setup-soldr main SHA before v0 promotion. - uses: zackees/setup-soldr@218672f8a77500785cb73bdb49e184dbfff05f44 + uses: zackees/setup-soldr@dfbe9627f6cb0226716b61625b99a58949162720 with: # cache-preset: foundation expands to: # build-cache: true, target-cache: false, From 387591ae0b6163a090c7ac427ca3dd97a91b115f Mon Sep 17 00:00:00 2001 From: Zach Vorhies Date: Sat, 26 Sep 2026 00:51:47 -0700 Subject: [PATCH 5/5] fix(build-engine): keep raw FBUILD_PERF_LOG_JSON sink path NormalizedPath lexically resolves '..', which can open a different file when the sink path crosses a symlink. Cache the raw OsString instead (addresses CodeRabbit review on #1471). --- crates/fbuild-build-engine/src/perf_log.rs | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/crates/fbuild-build-engine/src/perf_log.rs b/crates/fbuild-build-engine/src/perf_log.rs index c4c88e3a..dc145da9 100644 --- a/crates/fbuild-build-engine/src/perf_log.rs +++ b/crates/fbuild-build-engine/src/perf_log.rs @@ -29,7 +29,7 @@ //! // auto-summary on drop //! ``` -use fbuild_core::path::NormalizedPath; +use std::ffi::OsString; use std::io::Write; use std::path::Path; use std::sync::OnceLock; @@ -58,14 +58,12 @@ pub fn enabled() -> bool { /// /// Cached after the first call. pub fn json_sink_path() -> Option<&'static Path> { - static SINK: OnceLock> = OnceLock::new(); - SINK.get_or_init(|| { - std::env::var_os("FBUILD_PERF_LOG_JSON") - .filter(|v| !v.is_empty()) - .map(NormalizedPath::new) - }) - .as_ref() - .map(NormalizedPath::as_path) + // Keep the raw value: lexical normalization would resolve `..` across + // symlinks and could open a different file than the caller named. + static SINK: OnceLock> = OnceLock::new(); + SINK.get_or_init(|| std::env::var_os("FBUILD_PERF_LOG_JSON").filter(|v| !v.is_empty())) + .as_ref() + .map(Path::new) } /// Append `value` as a single JSON line to `path` (append + create).