Live data from Hacker News

Can a Rust binary use incompatible versions of the same library?

github.com

71–80 of 89 posts

Re: Can a Rust binary use incompatible versions of the same library?

#71

Earlier quoted context omitted.

> are you still astonished that they might give out the same IDs? No I think two sequences is exactly what's asked for. What I'm wondering is whether this is a warning when cargo fails to restore the crates and must use incompatible versions. I'd only be surprised if the behavior was a clean compile + a runtime crash. Because that's usually not the design chosen in Rust. > If the frog numbering code is using either c…

> What I'm wondering is whether this is a warning when cargo fails to restore the crates What does "fails to restore the crates" mean here? I've seen this verb "restore" used in some .NET software, but I can't see how it relates to Rust.

Sorry yeah I mean "resolve the dependency versions" from the listed version requirements, and if needed downloading them. "Restore" is used by e.g. NuGet (.NET) as you suggest and others (npm for js, etc).

The cargo dependency resolver runs and the results can be viewed by cargo tree. I saw in the docs now that cargo tree -d can be used to help find incompatible packages.

Re: Can a Rust binary use incompatible versions of the same library?

#74

How does that work if you want to export a symbol for dlopen?

I'm not sure I understand the use case here. Are you asking if you can depend on two versions of the same crate, for a crate that exports a `#[no_mangle]` or `#[export_name]` function?

I guess you could slap a `#[used]` attribute on your exported functions, and use their mangled name to call them with dlopen, but that would be unwieldy and guessing the disambiguator used by the compiler error prone to impossible.

Other than that, you cannot. What you can do is define the `#[no_mangle]` or `#[export_name]` function at the top-level of your shared library. It makes sense to have a single crate bear the responsibility of exporting the interface of your shared library.

I wish Rust would enforce that, but the shared library story in Rust is subpar. Fortunately it never actually comes into play, as the ecosystem relies on static linking

Re: Can a Rust binary use incompatible versions of the same library?

#75

Earlier quoted context omitted.

> What I'm wondering is whether this is a warning when cargo fails to restore the crates What does "fails to restore the crates" mean here? I've seen this verb "restore" used in some .NET software, but I can't see how it relates to Rust.

Sorry yeah I mean "resolve the dependency versions" from the listed version requirements, and if needed downloading them. "Restore" is used by e.g. NuGet (.NET) as you suggest and others (npm for js, etc). The cargo dependency resolver runs and the results can be viewed by cargo tree. I saw in the docs now that cargo tree -d can be used to help find incompatible packages.

The idiomatic Rust way to avoid a scenario where we might have different versions of the unique IDs is to reify unique IDs as an actual type (say named UniqueID) rather than just having a tacit understanding that these particular integers are supposed to be unique.

This lets the type's owner decide what affordances to give it (probably adding two UniqueIDs together is nonsense, but comparing them for equality definitely makes sense - should they be Ordered... chronologically? Or not?)

But importantly here now that it's a type, Rust knows counter v 1.2.3 UniqueID and counter v 4.5.6 UniqueID are different types, even though they have the same spelling. So this code now won't compile unless everybody is consistent e.g. the Frogs and Wizards all use v 1.2.3 but the unrelated Space Combat module works with v 4.5.6 UniqueID. Code that looks like it could work, where we try to use the unique ID of a Wizard as the identify of a sub-space laser blaster won't compile.

Re: Can a Rust binary use incompatible versions of the same library?

#76
post #3

I thought this was about loading two incompatible versions of a shared object into the same address space at first :-) The author correctly contrasts Rust (and NPM's) behavior with that of Python/pip, where only one version per package name is allowed. The Python packaging ecosystem could in theory standardize a form of package name mangling wherein multiple versions could be imported simultaneously (akin to what's c…

> dependency graph spaghetti The worst spaghetti comes from hard dependencies on minor versions and revisions. I will die on the hill that you should only ever specify dependencies on “at least this major-minor (and optionally and rarely revision for a bugfix)” in whatever the syntax is for your preferred language. Excepting of course a known incompatibility with a specific version or range of versions, and/or develo…

Building against recent and old version and publishing ranged lockfiles should be mandatory.

Re: Can a Rust binary use incompatible versions of the same library?

#77

How does that work if you want to export a symbol for dlopen?

I'm not sure I understand the use case here. Are you asking if you can depend on two versions of the same crate, for a crate that exports a `#[no_mangle]` or `#[export_name]` function? I guess you could slap a `#[used]` attribute on your exported functions, and use their mangled name to call them with dlopen, but that would be unwieldy and guessing the disambiguator used by the compiler error prone to impossible. Oth…

> I'm not sure I understand the use case here. Are you asking if you can depend on two versions of the same crate, for a crate that exports a `#[no_mangle]` or `#[export_name]` function?

Yes, exactly.

> Other than that, you cannot.

so, to the question "Can a Rust binary use incompatible versions of the same library?", then the answer is definitely "no". It's not yes if it cannot cover one of the most basic use cases when making OS-native software.

To be clear: no language targeting OS-native dynamic libraries can solve this, the problem is in how PE and ELF works.

Re: Can a Rust binary use incompatible versions of the same library?

#78

Earlier quoted context omitted.

Sorry yeah I mean "resolve the dependency versions" from the listed version requirements, and if needed downloading them. "Restore" is used by e.g. NuGet (.NET) as you suggest and others (npm for js, etc). The cargo dependency resolver runs and the results can be viewed by cargo tree. I saw in the docs now that cargo tree -d can be used to help find incompatible packages.

The idiomatic Rust way to avoid a scenario where we might have different versions of the unique IDs is to reify unique IDs as an actual type (say named UniqueID) rather than just having a tacit understanding that these particular integers are supposed to be unique. This lets the type's owner decide what affordances to give it (probably adding two UniqueIDs together is nonsense, but comparing them for equality definit…

That safety is merely accidental, it only appears if the dangerous state (the atomic counter memory location) is in the same crate as the UniqueNumber type exposed.

A pair of crates (one which defines the struct UniqueNumber(u32), and one which produces sequences of them) would still be suffering from this, because the sequencing crate could use v1 of the unique number struct crate, in both its v1 and v2.

This of course is even more contrived (now we have a specific split of state and types instead). So the real question is: does this happen in non-contrived scenarios in the wild?

Re: Can a Rust binary use incompatible versions of the same library?

#79

Earlier quoted context omitted.

I'm not sure I understand the use case here. Are you asking if you can depend on two versions of the same crate, for a crate that exports a `#[no_mangle]` or `#[export_name]` function? I guess you could slap a `#[used]` attribute on your exported functions, and use their mangled name to call them with dlopen, but that would be unwieldy and guessing the disambiguator used by the compiler error prone to impossible. Oth…

> I'm not sure I understand the use case here. Are you asking if you can depend on two versions of the same crate, for a crate that exports a `#[no_mangle]` or `#[export_name]` function? Yes, exactly. > Other than that, you cannot. so, to the question "Can a Rust binary use incompatible versions of the same library?", then the answer is definitely "no". It's not yes if it cannot cover one of the most basic use cases…

Rust uses -sys crates to link to non-native dependencies, with a links key in the manifest - https://doc.rust-lang.org/cargo/reference/build-scripts.html...

This mechanism allows Cargo to prevent multiply linking to an external library.

Re: Can a Rust binary use incompatible versions of the same library?

#80
post #18

I cannot shake the feeling that this is actually a misfeature that will get people into trouble in new and puzzling ways. The isolated classloaders in Java and the assembly domains in .Net didn't turn out to be very bright ideas and from a software design perspective this is virtually identical.

It's been working like that for a decade, and it's been fine.

Rust/Cargo have been designed for it from the start.

Post reply on HN