Skip to content

Commit

Permalink
Always generate + override [lib] for filtered crates (#114)
Browse files Browse the repository at this point in the history
The core way this project works for filtered crates is to replace
them with a "stub" that only has an empty `src/lib.rs`. When
processing the manifest previously, we didn't override the `lib`
section that might have been present. Usually this worked because
of autodiscovery.

But in the corner case that arose recently in cxx where there
was a `bin`-only crate as a build dependency, things broke
because we dropped the `bin` section but didn't add a `lib`.

Now arguably, there's a bug in `cargo` here because it dropped
the dependency in `cargo metadata` but still checks it in
`cargo build`.

But anyways it's clearly correct here for us to have a canonical
`lib` section always (whether it was present or not in the filtered
crate) so do that.

Closes: #111
  • Loading branch information
cgwalters authored Jan 16, 2025
1 parent ef915d3 commit 0e5b84b
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 1 deletion.
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ pub const RESPECT_SOURCE_CONFIG: &str = "--respect-source-config";
pub const VERSIONED_DIRS: &str = "--versioned-dirs";
/// The package entry
pub const MANIFEST_KEY_PACKAGE: &str = "package";
/// The well-known cargo target for a library
pub const LIB: &str = "lib";
/// Extra targets which we need to remove because Cargo validates them and will
/// error out when we've replaced the library with a stub.
pub const UNWANTED_MANIFEST_KEYS: &[&str] = &["bin", "example", "test", "bench"];
Expand Down
53 changes: 52 additions & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ use cargo_vendor_filterer::*;
mod dep_kinds_filtering;
mod tiers;

/// The path to the stub library file we write
const STUB_LIBRS: &str = "src/lib.rs";

/// This is the .cargo-checksum.json in a crate/package.
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
struct CargoChecksums {
Expand Down Expand Up @@ -222,6 +225,9 @@ struct Args {

fn filter_manifest(manifest: &mut toml::Value) {
if let Some(t) = manifest.as_table_mut() {
let mut libtable = toml::Table::new();
libtable.insert("path".into(), STUB_LIBRS.into());
t.insert("lib".into(), libtable.into());
for &k in UNWANTED_MANIFEST_KEYS {
t.remove(k);
}
Expand Down Expand Up @@ -301,7 +307,7 @@ fn replace_with_stub(path: &Utf8Path) -> Result<()> {
// An empty Cargo.toml
writef(Utf8Path::new(CARGO_TOML), cargo_toml_data.as_bytes())?;
// And an empty source file
writef(Utf8Path::new("src/lib.rs"), b"")?;
writef(Utf8Path::new(STUB_LIBRS), b"")?;
// Finally, serialize the new checksums
let mut w = std::fs::File::create(checksums_path).map(std::io::BufWriter::new)?;
serde_json::to_writer(&mut w, &checksums)?;
Expand Down Expand Up @@ -1091,6 +1097,51 @@ name = "somebench"
}
}

/// Test case for https://github.com/coreos/cargo-vendor-filterer/issues/111
#[test]
fn test_filter_manifest_binonly() {
let mut v: toml::Value = toml::from_str(
r#"
[package]
name = "cxxbridge-cmd"
version = "1.0.136"
authors = ["David Tolnay <[email protected]>"]
categories = ["development-tools::build-utils", "development-tools::ffi"]
description = "C++ code generator for integrating `cxx` crate into a non-Cargo build."
edition = "2021"
exclude = ["build.rs"]
homepage = "https://cxx.rs"
keywords = ["ffi"]
license = "MIT OR Apache-2.0"
repository = "https://github.com/dtolnay/cxx"
rust-version = "1.73"
[[bin]]
name = "cxxbridge"
path = "src/main.rs"
[features]
# incomplete features that are not covered by a compatibility guarantee:
experimental-async-fn = []
[dependencies]
clap = { version = "4.3.11", default-features = false, features = ["error-context", "help", "std", "suggestions", "usage"] }
codespan-reporting = "0.11.1"
proc-macro2 = { version = "1.0.74", default-features = false, features = ["span-locations"] }
quote = { version = "1.0.35", default-features = false }
syn = { version = "2.0.46", default-features = false, features = ["clone-impls", "full", "parsing", "printing"] }
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]
"#,
)
.unwrap();
filter_manifest(&mut v);
let table = v.as_table().unwrap();
assert!(table.get("bin").is_none());
assert!(table.get("lib").is_some());
}

#[test]
fn test_cli() {
use clap::CommandFactory;
Expand Down

0 comments on commit 0e5b84b

Please sign in to comment.