What happened
once query targets derives Cargo targets from Cargo.lock without applying Cargo’s feature resolution. Every package present in the lockfile becomes a rust_crate target, including packages that the enabled feature set excludes from the build.
For a crate depending on sqlx with default-features = false and only the postgres driver enabled, Once emits build targets for the SQLite and MySQL drivers. cargo build never compiles these.
This is not cosmetic: once build then tries to compile sqlx-sqlite, which fails, so no target that depends on sqlx can be built at all.
Reproduction
Cargo.toml:
[package]
name = "demo"
version = "0.1.0"
edition = "2021"
[dependencies]
sqlx = { version = "0.8.6", default-features = false, features = ["runtime-tokio-rustls", "postgres", "uuid", "time", "macros", "migrate", "json"] }
uuid = { version = "1", features = ["v4"] }
src/main.rs:
fn main() {
println!("{}", std::any::type_name::<sqlx::PgPool>());
}
Then:
cargo generate-lockfile
once query targets | grep -iE 'sqlx-(sqlite|mysql)|libsqlite3'
Actual
libsqlite3-sys-0.30.1 (rust_crate) [build]
libsqlite3-sys-0.30.1-host (rust_crate) [build]
sqlx-mysql-0.8.6 (rust_crate) [build]
sqlx-mysql-0.8.6-host (rust_crate) [build]
sqlx-sqlite-0.8.6 (rust_crate) [build]
sqlx-sqlite-0.8.6-host (rust_crate) [build]
Cargo disagrees — these are not part of the build:
$ cargo tree -i libsqlite3-sys
warning: nothing to print.
$ cargo tree -i sqlx-mysql
warning: nothing to print.
They are in Cargo.lock (the migrate feature pulls them into the resolve graph) but the feature set excludes them from compilation.
Expected
Targets are emitted only for packages that the resolved feature set actually builds, matching cargo tree -e normal.
Impact
Target counts for the reproduction above:
|
count |
once query targets (rust_crate) |
311 |
packages in Cargo.lock |
203 |
| crates Cargo actually builds |
136 |
The extra packages are not merely listed — they are reachable as build dependencies of the binary:
$ once query "MATCH (t)-[:DEPENDS_ON*]->(d) WHERE t.name = 'cargo_demo_bin_demo' RETURN d.name" | grep -iE 'sqlite|mysql'
sqlx-mysql-0.8.6
sqlx-sqlite-0.8.6
libsqlite3-sys-0.30.1
sqlx-mysql-0.8.6-host
sqlx-sqlite-0.8.6-host
libsqlite3-sys-0.30.1-host
Transitive dependency count for that binary: 306 in Once vs 132 that Cargo builds.
So Once schedules roughly 2.3× the necessary compilation work, and the surplus includes a package with a bundled C library (libsqlite3-sys) that the enabled feature set is specifically meant to avoid.
I have not been able to observe the resulting compile failure end-to-end, because once build currently stops earlier on an unrelated issue (build scripts, filed separately) before reaching these targets. The graph query above is the reliable evidence.
Environment
- once 0.42.0 (x86_64-unknown-linux-gnu release build)
- Linux 6.8, x86_64