Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cargo upgrade selects versions of native dependencies which are not compatible with transitive packages #844

Open
udoprog opened this issue Apr 10, 2023 · 1 comment

Comments

@udoprog
Copy link

udoprog commented Apr 10, 2023

Originally reported in diesel-rs/diesel#3587 and rust-lang/cargo#11948

The issue here is that diesel depends on libsqlite3-sys, which as a native dependency and declares that it links to sqlite3. If the crate being upgraded has a direct dependency to libsqlite3-sys (something which is needed to activate features in it that are not re-exported by diesel) this can cause cargo upgrade to potentially select an incompatible version to upgrade to.

If you run cargo upgrade on a manifest with the following:

[dependencies]
libsqlite3-sys = { version = "0.25.2", features = ["bundled", "unlock_notify"] }
diesel = { version = "2.0.3", features = ["sqlite", "chrono"] }

It gets upgraded to this:

[dependencies]
libsqlite3-sys = { version = "0.26.0", features = ["bundled", "unlock_notify"] }
diesel = { version = "2.0.3", features = ["sqlite", "chrono"] }

Trying to build it results in this error:

    Updating crates.io index
error: failed to select a version for `libsqlite3-sys`.
    ... required by package `diesel v2.0.3`
    ... which satisfies dependency `diesel = "~2.0.0"` of package `diesel_migrations v2.0.0`
    ... which satisfies dependency `diesel_migrations = "^2.0.0"` of package `oxidize v0.0.0 (D:\Repo\*snip*)`
versions that meet the requirements `>=0.17.2, <0.26.0` are: 0.25.2, 0.25.1, 0.25.0, 0.24.2, 0.24.1, 0.24.0, 0.23.2, 0.23.1, 0.23.0, 0.22.2, 0.22.1, 0.22.0, 0.20.1, 0.20.0, 0.18.0, 0.17.3, 0.17.2

the 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.26.0`
    ... which satisfies dependency `libsqlite3-sys = "^0.26.0"` of package `oxidize v0.0.0 (D:\Repo\*snip*)`
Only one package in the dependency graph may specify the same links value. This helps ensure that only one copy of a native library is linked in the final binary. Try to adjust your dependencies so that only one package uses the links ='libsqlite3-sys' value. For more information, see https://doc.rust-lang.org/cargo/reference/resolver.html#links.

failed to select a version for `libsqlite3-sys` which could resolve this conflict

Possible Solution(s)

We could opt to only upgrade to versions of libsqlite3-sys which are compatible. That means it would have to analyze linking restrictions when selecting a new version.

We could also opt to allow the activation of transitive features. I'm sure that's been discussed somewhere but I can't find it right now.

Note that there's also the option for the transitive crate to re-export the desired feature, but in the case of diesel the maintainer is unwilling to do so.

@epage
Copy link
Collaborator

epage commented Apr 10, 2023

Interesting, links is another spin on the public/private dependency issue but requires arbitrarily walking the entire dependency tree. I think I'll follow where we go with the cargo add side of this

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants