Skip to content

Put the libduckdb download client behind a default download-lib feature - #842

Open
gurinderu wants to merge 1 commit into
duckdb:mainfrom
gurinderu:download-lib-feature
Open

Put the libduckdb download client behind a default download-lib feature#842
gurinderu wants to merge 1 commit into
duckdb:mainfrom
gurinderu:download-lib-feature

Conversation

@gurinderu

Copy link
Copy Markdown

Motivation

libduckdb-sys lists ureq (with rustls) as an unconditional
[build-dependencies] entry. Build dependencies are compiled for the host on
every build of every consumer, so each duckdb user compiles a TLS stack
(ureqrustlsring) for the build script, even with bundled, where
the download path is never reached.

This has two costs:

  • It can break builds. ring 0.17.14 (the last release in that line)
    fails its aarch64-apple CPU-feature const-asserts on some macOS CI runners:

    error[E0080]: evaluation panicked: assertion failed: (CAPS_STATIC & MIN_STATIC_FEATURES) == MIN_STATIC_FEATURES
      --> ring-0.17.14/src/cpu/arm/darwin.rs:44:5
    

    A consumer that has already removed ring from its own runtime graph still
    cannot build, because Cargo features are additive and there is no way to
    strip a dependency's build-dependency from the outside.

  • It is wasted work. A bundled build compiles the engine from the
    vendored tarball and never touches the network, yet still pays for
    compiling an HTTP client and a TLS provider.

Changes

Minimal and behaviour-preserving for existing users:

  • New download-lib feature on libduckdb-sys owning ureq and zip
    (both now optional). It is in the default feature set, so default builds
    and DUCKDB_DOWNLOAD_LIB keep working exactly as before.

  • The DUCKDB_DOWNLOAD_LIB code path in build.rs is gated on the feature.
    Setting the variable without the feature panics with a message pointing at
    download-lib.

  • The workspace dependency on libduckdb-sys is declared with
    default-features = false, and the duckdb crate forwards the sys defaults
    through its own default feature. Consumers can therefore drop the HTTP
    client with:

    duckdb = { version = "...", default-features = false, features = ["bundled"] }
  • One-line README note. No CI changes, Cargo.lock unchanged.

Verification

  • cargo tree -p duckdb --no-default-features --features bundled --edges normal,build --invert ring
    reports no ring package; with default features ring is present via
    ureq, as before.
  • cargo clippy -p libduckdb-sys --all-targets -- -D warnings passes with
    default features and with --no-default-features --features vcpkg,pkg-config.
  • A full cargo build -p duckdb --no-default-features --features bundled
    on aarch64-apple is in progress locally; I will post the result in a comment.

Compatibility

No change for anyone using default features. Only consumers who opt into
default-features = false lose the download path, and they get a clear
build-script error if they also set DUCKDB_DOWNLOAD_LIB.

`ureq` (with rustls/ring) was an unconditional build-dependency of
libduckdb-sys, so every consumer compiled a TLS stack for the build script
even with `bundled`, where the download path is never reached. ring 0.17's
aarch64-apple const-asserts fail on some macOS CI runners, breaking those
builds, and Cargo offers no way to strip a build-dependency from outside.

Move `ureq` and `zip` behind a new `download-lib` feature and gate the
DUCKDB_DOWNLOAD_LIB code path behind it. The feature is on by default, so
default builds behave exactly as before. The `duckdb` crate depends on
libduckdb-sys without defaults and forwards them through its own `default`
feature, so `duckdb = { default-features = false, features = ["bundled"] }`
yields a graph with no ureq/rustls/ring. Setting DUCKDB_DOWNLOAD_LIB without
the feature panics with a message pointing at it.
@gurinderu

Copy link
Copy Markdown
Author

Follow-up on Verification: cargo build -p duckdb --no-default-features --features bundled (aarch64-apple-darwin, Rust 1.98) completed successfully on 76b8eba.

gurinderu added a commit to gurinderu/net-observer that referenced this pull request Sep 3, 2026
Upstream libduckdb-sys carries an unconditional build-dependency on ureq,
whose rustls feature hard-enables ring. ring then fails to compile on the CI
runner — const-assert on aarch64 static CPU features — before a single test
runs, which is why the tests workflow has been red on every state of the trunk
while lints stayed green. Features only ever add, so it could not be switched
off from here.

The fork moves that download path behind a default feature, so
`default-features = false` with `bundled` drops ureq and ring entirely:
cargo tree --invert ring --edges normal,build now finds nothing.

Pinned to a revision, not a branch: a branch moves and takes reproducibility
with it. The change is upstream as duckdb/duckdb-rs#842 — when it lands, this
pin comes off and the dependency returns to crates.io.

(realm net-observer, node #45)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant