Skip to content
Merged
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
232 changes: 105 additions & 127 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ owo-colors = "4"
# duplicate symbol: rp_native_process_start_public`, …). Keep this rev in
# lockstep with the `rev` in zccache's workspace Cargo.toml when repinning
# zccache.
running-process = { version = "4.6.0", git = "https://github.com/zackees/running-process.git", rev = "59556ebbb779a66a95811c75bb1533cf3db1c525", default-features = false, features = ["client-async"] }
running-process = { version = "4.8.1", git = "https://github.com/zackees/running-process.git", rev = "359b4e3d92660e54eb9b16b6e83de8ce26932ff8", default-features = false, features = ["client-async"] }

[profile.dev]
debug = "line-tables-only"
Expand Down
2 changes: 1 addition & 1 deletion crates/fbuild-build-arm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ tar = { workspace = true }
zip = { workspace = true }
tree-sitter = { workspace = true }
tree-sitter-cpp = { workspace = true }
zccache = { git = "https://github.com/zackees/zccache", rev = "5ee292ff61e0f5909e1893916efe3bd963db8032" }
zccache = { git = "https://github.com/zackees/zccache", rev = "8cf6dd0ef5d6f2ff2980039290b9e498fb5a6b0e" }

[dev-dependencies]
filetime = { workspace = true }
Expand Down
2 changes: 1 addition & 1 deletion crates/fbuild-build-engine/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ tar = { workspace = true }
zip = { workspace = true }
tree-sitter = { workspace = true }
tree-sitter-cpp = { workspace = true }
zccache = { git = "https://github.com/zackees/zccache", rev = "5ee292ff61e0f5909e1893916efe3bd963db8032" }
zccache = { git = "https://github.com/zackees/zccache", rev = "8cf6dd0ef5d6f2ff2980039290b9e498fb5a6b0e" }

[dev-dependencies]
filetime = { workspace = true }
Expand Down
2 changes: 1 addition & 1 deletion crates/fbuild-build-esp/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ tar = { workspace = true }
zip = { workspace = true }
tree-sitter = { workspace = true }
tree-sitter-cpp = { workspace = true }
zccache = { git = "https://github.com/zackees/zccache", rev = "5ee292ff61e0f5909e1893916efe3bd963db8032" }
zccache = { git = "https://github.com/zackees/zccache", rev = "8cf6dd0ef5d6f2ff2980039290b9e498fb5a6b0e" }

[dev-dependencies]
filetime = { workspace = true }
Expand Down
2 changes: 1 addition & 1 deletion crates/fbuild-build-mcu/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ tar = { workspace = true }
zip = { workspace = true }
tree-sitter = { workspace = true }
tree-sitter-cpp = { workspace = true }
zccache = { git = "https://github.com/zackees/zccache", rev = "5ee292ff61e0f5909e1893916efe3bd963db8032" }
zccache = { git = "https://github.com/zackees/zccache", rev = "8cf6dd0ef5d6f2ff2980039290b9e498fb5a6b0e" }

[dev-dependencies]
filetime = { workspace = true }
Expand Down
2 changes: 1 addition & 1 deletion crates/fbuild-build/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ tree-sitter-cpp = { workspace = true }
#
# `running-process` in the workspace root must be pinned to the SAME git rev
# zccache uses, or its unmangled `rp_*_public` C symbols get linked twice.
zccache = { git = "https://github.com/zackees/zccache", rev = "5ee292ff61e0f5909e1893916efe3bd963db8032" }
zccache = { git = "https://github.com/zackees/zccache", rev = "8cf6dd0ef5d6f2ff2980039290b9e498fb5a6b0e" }

[dev-dependencies]
filetime = { workspace = true }
Expand Down
10 changes: 10 additions & 0 deletions crates/fbuild-core/tests/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# fbuild-core integration tests

- **`dep_identity.rs`** -- regression guard for FastLED/fbuild#1239. fbuild
embeds zccache and also depends directly on `running-process`, whose
unmangled `rp_*_public` native symbols mean that resolving two package
identities would link two copies of those symbols. The test parses the
workspace `Cargo.lock` and fails if more than one `running-process`
package identity/source/revision is resolved, and mechanically checks
that the workspace `Cargo.toml` pin matches the locked revision (i.e.
fbuild's direct pin equals the revision zccache resolved transitively).
91 changes: 91 additions & 0 deletions crates/fbuild-core/tests/dep_identity.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
//! Regression guard for FastLED/fbuild#1239: the workspace must resolve
//! exactly ONE `running-process` package identity.
//!
//! fbuild depends on `running-process` directly AND transitively through
//! the embedded zccache. `running-process` exports unmangled
//! `rp_*_public` native symbols, so two resolved identities (two
//! versions, two sources, or two revisions) would link two copies of
//! those symbols into fbuild. The dependency cascade discipline is:
//! fbuild's direct git pin must be byte-identical to the pin inside the
//! zccache release fbuild embeds — this test fails the build when the
//! pins drift apart.

use std::path::Path;

fn workspace_root() -> &'static Path {
// crates/fbuild-core -> workspace root.
Path::new(env!("CARGO_MANIFEST_DIR"))
.parent()
.and_then(Path::parent)
.expect("workspace root above crates/fbuild-core")
}

/// Extract every `[[package]]` block for `name` from Cargo.lock, returning
/// each block's `(version, source)` pair.
fn locked_packages(lock: &str, name: &str) -> Vec<(String, String)> {
let mut found = Vec::new();
for block in lock.split("[[package]]") {
let mut pkg_name = None;
let mut version = None;
let mut source = None;
for line in block.lines().map(str::trim) {
if let Some(v) = line.strip_prefix("name = ") {
pkg_name = Some(v.trim_matches('"').to_string());
} else if let Some(v) = line.strip_prefix("version = ") {
version = Some(v.trim_matches('"').to_string());
} else if let Some(v) = line.strip_prefix("source = ") {
source = Some(v.trim_matches('"').to_string());
}
}
if pkg_name.as_deref() == Some(name) {
found.push((version.unwrap_or_default(), source.unwrap_or_default()));
}
}
found
}

/// The `rev = "..."` recorded for `dep` in the workspace Cargo.toml.
fn workspace_pin_rev(cargo_toml: &str, dep: &str) -> String {
let line = cargo_toml
.lines()
.find(|l| l.trim_start().starts_with(&format!("{dep} = {{")))
.unwrap_or_else(|| panic!("no `{dep}` dependency line in workspace Cargo.toml"));
let rev_key = "rev = \"";
let start = line
.find(rev_key)
.unwrap_or_else(|| panic!("`{dep}` line has no rev pin: {line}"))
+ rev_key.len();
line[start..]
.split('"')
.next()
.expect("terminated rev string")
.to_string()
}

#[test]
fn exactly_one_running_process_identity_matching_the_workspace_pin() {
let root = workspace_root();
let lock = std::fs::read_to_string(root.join("Cargo.lock")).expect("read Cargo.lock");
let cargo_toml =
std::fs::read_to_string(root.join("Cargo.toml")).expect("read workspace Cargo.toml");

let packages = locked_packages(&lock, "running-process");
assert_eq!(
packages.len(),
1,
"Cargo.lock must resolve exactly one `running-process` identity — \
multiple identities link duplicate rp_*_public symbols \
(FastLED/fbuild#1239). Resolved: {packages:?}"
);

let (version, source) = &packages[0];
let pinned_rev = workspace_pin_rev(&cargo_toml, "running-process");
assert!(
source.contains(&pinned_rev),
"the locked running-process source must be the workspace-pinned rev.\n \
locked: {version} @ {source}\n \
pinned: {pinned_rev}\n \
The direct pin and the zccache release's transitive pin have drifted — \
re-run the FastLED/fbuild#1239 cascade (running-process -> zccache -> fbuild)."
);
}
Loading