Skip to content

Widen the libsqlite3-sys bound to any 0.x - #261

Open
MichaelKreil wants to merge 1 commit into
georust:mainfrom
MichaelKreil:widen-libsqlite3-sys-bound
Open

Widen the libsqlite3-sys bound to any 0.x#261
MichaelKreil wants to merge 1 commit into
georust:mainfrom
MichaelKreil:widen-libsqlite3-sys-bound

Conversation

@MichaelKreil

Copy link
Copy Markdown

Fixes #235.

libsqlite3-sys declares links = "sqlite3", so cargo permits exactly one copy in a graph. The
current ceiling of <0.36 predates 0.36, 0.37 and 0.38, which means proj-sys cannot coexist with
any rusqlite newer than 0.37 - and there is no consumer-side fix, because the dependency is not
optional on either side.

#235 reports this and stalled on the reporter's mention of nix. That was a red herring: this is pure
cargo resolution and happens with no nix involved. Our case is an application using r2d2_sqlite:

Chain Requires libsqlite3-sys
gdal-sys (bundled) → gdal-src 0.3 → proj-sys 0.27 >=0.28, <0.36
r2d2_sqlite 0.35 → rusqlite 0.40 ^0.38
error: failed to select a version for `libsqlite3-sys`.
    ... required by package `proj-sys v0.27.0`
package `libsqlite3-sys` links to the native library `sqlite3`, but it conflicts with a
previous package which links to `sqlite3` as well: package `libsqlite3-sys v0.38.0`

Why widening rather than removing. #190 added this dependency deliberately, to give downstream
control over how libsqlite3 is linked in bundled builds - and it was merged specifically to unblock
georust/gdal's bundled build. That is exactly the case we are trying to use, so removing the
dependency would break the thing it was added for. Only the ceiling looks accidental.

Why the version does not matter. proj-sys's entire coupling to the crate is:

  • extern crate libsqlite3_sys; under the bundled_build cfg - linkage only, no API surface
  • DEP_SQLITE3_INCLUDE and DEP_SQLITE3_LIB_DIR in build.rs

Both cargo:include and cargo:lib_dir are emitted unchanged by libsqlite3-sys 0.35, 0.36, 0.37
and 0.38, so nothing in proj-sys has to change.

Why <1.0 rather than <0.39. For a links crate a version bound is not only "what I can build
against" - it constrains the whole downstream graph, with no opt-out. So a tight ceiling needs a new
proj-sys release every time libsqlite3-sys ships a minor, and every time it falls behind,
consumers cannot resolve at all. That treadmill is how <0.36 came to be three releases stale.
<1.0 still guards against a genuine 1.0 rewrite, since cargo treats each 0.x minor as breaking
anyway. It does bet that the two build-script keys stay stable across 0.x; if that ever broke, it
would be a clear build error in proj-sys rather than an unresolvable graph for everyone else.

Tested against the case the dependency exists for - a statically bundled GDAL, on macOS/arm64:
it resolves with libsqlite3-sys 0.38.2 alongside rusqlite 0.40, builds GDAL, PROJ and SQLite from
source, links with no gdal/proj/sqlite dylib, and reads a GeoTIFF into tiles with a correct Web
Mercator bbox - so PROJ's embedded proj.db resolves at runtime too.

The ceiling of <0.36 predates libsqlite3-sys 0.36, 0.37 and 0.38, so
proj-sys cannot coexist with any rusqlite newer than 0.37. Because
libsqlite3-sys declares links = "sqlite3", cargo permits exactly one
copy in a graph and there is no consumer-side fix.

proj-sys has no API surface on the crate — an extern crate for linkage
under bundled_build, plus DEP_SQLITE3_INCLUDE and DEP_SQLITE3_LIB_DIR
in build.rs, both emitted unchanged by 0.35 through 0.38.

<1.0 rather than a tighter ceiling: for a links crate the bound
constrains the whole downstream graph, so a tight one needs a release
every time libsqlite3-sys ships a minor, and breaks consumers whenever
it falls behind.

Fixes georust#235.
MichaelKreil added a commit to versatiles-org/versatiles-studio that referenced this pull request Aug 18, 2026
Carries a pinned proj-sys fork (georust/proj#261) to get past the
libsqlite3-sys links conflict that Q19's spike could not see, because it
measured GDAL outside Studio's dependency graph. Pinned to a commit so a
rebase cannot change what this builds; the exit condition is written
beside it.

Blocks pkg-config in .cargo/config.toml rather than in a shell, so the
build cannot differ between a laptop with Homebrew GDAL and CI.

The raster card needed no change — the catalogue drops kinds whose
operation the build lacks, so linking GDAL was enough to make it appear.

The extension check moves to GDAL's own driver metadata for that card:
from_gdal_raster's prose names one example filename, so matching against
it rejected .tiff correctly and uselessly. The card and the gdal-src
feature list are one choice in two files, and a test now keeps them one.
MichaelKreil added a commit to versatiles-org/versatiles-rs that referenced this pull request Aug 18, 2026
Depending on versatiles with `gdal` while building GDAL statically fails to
resolve: libsqlite3-sys declares `links = "sqlite3"`, and proj-sys 0.27 caps
it at <0.36 while our rusqlite chain needs ^0.38. The ceiling predates
libsqlite3-sys 0.36-0.38 and is not a real incompatibility — proj-sys uses
the crate only for linkage and the DEP_SQLITE3_* build-script keys.

The fix belongs upstream (georust/proj#261). Document the interim
`[patch.crates-io]` stanza, including that it must live in the consuming
application's workspace root rather than here.

Refs #226
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.

Is libsqlite3-sys really needed?

1 participant