Prevent cargo from installing dependency of dependency libraries

Hi,

I have a Rust version 0.19.0, which is really really old. I cannot do anything about it though. Now i am trying to use a flatbuffers crate which has the latest version in my code. Flatbuffers started supporting rust in 2018. When i add flatbuffers as my dependency in Cargo.toml file, it fetches another dependent library smallvec.

I get this error while building.

error[E0432]: unresolved import std::mem::ManuallyDrop
--> /root/.cargo/git/checkouts/rust-smallvec-f85065a4e6040d19/a775b5f/lib.rs:63:5
|
63 | use std::mem::ManuallyDrop;
| ^^^^^^^^^^^^^^^^^^^^^^ no ManuallyDrop in mem

The requirement is something like this. My code <= flatbuffer <= smallvec

Without modifying the rust version and flatbuffers, is it possible to prevent Cargo from downloading/compiling smallvec or making this error get suppressed?

Thank you in advance. Apologies for any mistakes/misconceptions.

1 Like

Bloody hell. I'm somewhat of a stickler for backwards compatibility, but I wouldn't even attempt to write code that worked with 0.19.0. That predates stabilisation. The odds of anything written in the last year working on that are vanishingly small.

As an aside: when the topic of back-compat comes up, a common reason not to bother is "why don't you just install the latest version?". As such, I'd be very interested in knowing even a little about why you can't update. Having another example of why it's not always so simple is useful. Also, I'm curious as to how you've ended up stuck on a pre-release version of Rust.

Anyway, you can't not compile dependencies. It'd be like trying to fly a plane after removing a wing because it failed safety inspection. It kind of needs those. You also can't suppress compile errors: that is like "suppressing" a failure to attach the engines to a plane. Again, they're rather necessary.

Your best (possibly only) bet is to try the earliest version of all dependencies you can find and hope they work on 0.19.0. To do this, you need to take your immediate dependencies (like flatbuffers), get on crates.io and find the earliest version you can. Then, set that as the version you depend on with something like:

flatbuffers = "=0.4.0"

It looks like flatbuffers goes back to 0.1.0 in 2016, but every version before 0.4.0 has been yanked, so presumably there are security issues with those versions, and you can't use them.

At that point, try compiling. If a transitive dependency fails, find it on crates.io, and add an explicit dependency on the earliest version you can find that is also compatible with whatever requires it. flatbuffers 0.4.0 requires smallvec 0.6 or compatible, so you'd need to find the earliest version of smallvec 0.6.* that works.

And if that fails... you can either try to fork and back-port the dependencies to Rust 0.19.0, not use that dependency and write the needed code yourself, or give up entirely.


†: At least, not without hand-editing the Cargo.lock file. I couldn't tell you how to do that.

1 Like

Bloody hell. I’m somewhat of a stickler for backwards compatibility, but I wouldn’t even attempt to write code that worked with 0.19.0. That predates stabilisation. The odds of anything written in the last year working on that are vanishingly small.

They probably mean 1.19; there was no 0.19 release.

1 Like

Well, slightly less impossible to cope with, then. Still, that only really affects the first paragraph, and last sentence of the second. :stuck_out_tongue:

1 Like

Cargo lacks ability to limit crates to Rust versions:

https://github.com/rust-lang/rfcs/pull/2495

so use of an old Rust version is going to be a massive PITA.

If you can't update Rust beyond 1.19, and you don't have a compatible Cargo.lock file, then dependencies are going to be a whack-a-mole of breakage.

You could try:

  1. When flatbuffers uses smallvec, also add smallvec to your crate.
  2. Set version of smallvec to an old one that is compatible with your version of Rust, but still has the same major version that is used by flatbuffers. Make sure to use smallvec = "=0.6.0" syntax with the extra =.
  3. If the oldest version of smallvec with the same semver-major version is still not compatible, try older version of flatbuffers that uses older semver-major version of smallvec (or doesn't use it at all)

The trick here is that Cargo uses one version of library per semver-major of that library (so 1.x and 2.x can coexist, but if you require 1.0, then cargo won't upgrade to 1.1).

You may end up repeating the process several times for several dependencies deep.

It's going to be awful, so I'd recommend figuring out how to upgrade Rust. Maybe even cross-compile from another machine that has a newer version — even that may be easier than using less-than-latest Rust.

1 Like

Other solution: you clone the flatbuffer repo locally, replace on Cargo.toml the dependency of ::flatbuffer from your code with you local one

[dependencies]
# remove: flatbuffer = "x.y.z"
# add:
flatbuffer = { path = "relative/path/to/local/clone" }

Now you can tweak the code of you local flatbuffer and replace all occurrences of Smallvec with classic Vecs. This way ypu should be able to remove the ::smallvec dependency from flatbuffer's Cargo.toml

One more possible solution that came to my mind — replace crates.io's index with an old one.

It's not as trivial as I'd like, because it's a bare repository and crates.io has flattened history. But if you manage to replace ~/.cargo/registry/index/github.com-1ecc6299db9ec823/ with a custom clone of an old branch of the registry from a couple of years ago, you may trick Cargo into seeing only old crates.

Newer cargo can replace index in the config, but the old cargo probably doesn't have that option (yet).