Summary
Future enhancement — not blocking users today. When a build graph contains both rnp[vendored] and botan[vendored] (e.g. a tool needing OpenPGP plus raw Botan primitives), Botan is compiled twice and the final link binds whichever libbotan-3 archive comes first in search-path order.
What happens today
botan-sys (via botan[vendored]) compiles Botan in its OUT_DIR; rnp-src compiles its own in another. botan_src::build() lands the build in whichever crate's OUT_DIR calls it — there is no shared cache.
- Cargo cannot unify
0.x minor versions, so with version skew the graph carries two different Botan versions. Both emit -lbotan-3 with different search paths; one archive silently wins.
- The loser's consumer breaks: either missing-symbol link errors, or — worse — a silent C++ ABI/layout mismatch (Botan's C++ ABI is unstable across minors, per its sonames). Nothing warns.
Mitigations already shipped
The actual goal
Exactly one Botan compilation per cargo build graph, shared by every consumer. Real fixes live upstream in botan-rs:
- A shared build cache inside
botan-src, keyed by version/target/configuration — universal, but pushes cache-key correctness, locking, and staleness onto upstream.
- Links metadata (
lib_dir/include_dir) from botan-sys's vendored path — small, but insufficient in general: build scripts cannot retroactively configure a dependency's already-finished build (e.g. our BOTAN_CONFIGURE_ENABLE_MODULES for PQC runs before our own Botan build, which ordering can't work when botan-sys's build already ran), and it would expose botan-sys's build-tree layout as a quasi-API.
A meek, constraint-framed issue draft for botan-rs exists and will be filed when we prioritize this. Until then, the mitigations above keep mixed graphs correct-if-wasteful.
Summary
Future enhancement — not blocking users today. When a build graph contains both
rnp[vendored]andbotan[vendored](e.g. a tool needing OpenPGP plus raw Botan primitives), Botan is compiled twice and the final link binds whicheverlibbotan-3archive comes first in search-path order.What happens today
botan-sys(viabotan[vendored]) compiles Botan in itsOUT_DIR;rnp-srccompiles its own in another.botan_src::build()lands the build in whichever crate'sOUT_DIRcalls it — there is no shared cache.0.xminor versions, so with version skew the graph carries two different Botan versions. Both emit-lbotan-3with different search paths; one archive silently wins.Mitigations already shipped
rnp-srcpins the samebotan-srcasbotan-sys(0.31300.0 = Botan 3.13.0), so mixed graphs compile the same version twice — wasteful (~10 min), but correct.botan-sys-detectfeature): loudcargo:warningwhen another vendored Botan is present in the graph.libbotan, zero duplication), then aligned-vendored.The actual goal
Exactly one Botan compilation per cargo build graph, shared by every consumer. Real fixes live upstream in botan-rs:
botan-src, keyed by version/target/configuration — universal, but pushes cache-key correctness, locking, and staleness onto upstream.lib_dir/include_dir) frombotan-sys's vendored path — small, but insufficient in general: build scripts cannot retroactively configure a dependency's already-finished build (e.g. ourBOTAN_CONFIGURE_ENABLE_MODULESfor PQC runs before our own Botan build, which ordering can't work when botan-sys's build already ran), and it would expose botan-sys's build-tree layout as a quasi-API.A meek, constraint-framed issue draft for botan-rs exists and will be filed when we prioritize this. Until then, the mitigations above keep mixed graphs correct-if-wasteful.