Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I access assets included in a Rust/Cargo project installed via `cargo install`?

I have a project which includes some associated assets (Lua scripts), which I need to find at runtime. This can mean two things:

  • During development (e.g. cargo run), I want to find it relative to the source
  • When installed via cargo install, the assets should be installed somewhere as well, and the installed version of the executable should find the installed assets.

I know about the option to use something like include_str!() to compile text files into the binary, but I don't want to do that in this case.

As far as I can tell, cargo install doesn't have any support for installing anything other than the executable at the moment, which is the first problem, though I don't mind having a wrapper install script to help.

like image 973
Chris Emerson Avatar asked Oct 06 '16 05:10

Chris Emerson


People also ask

Where does Cargo store downloaded crates?

The "Cargo home" functions as a download and source cache. When building a crate, Cargo stores downloaded build dependencies in the Cargo home.

Where are Rust packages installed?

In the Rust development environment, all tools are installed to the ~/. cargo/bin. directory, and this is where you will find the Rust toolchain, including rustc , cargo , and rustup . Accordingly, it is customary for Rust developers to include this directory in their PATH environment variable.

How does cargo install work?

The cargo install command allows you to install and use binary crates locally. This isn't intended to replace system packages; it's meant to be a convenient way for Rust developers to install tools that others have shared on crates.io. You can only install packages that have binary targets.

How does cargo work Rust?

Cargo is the Rust package manager. Cargo downloads your Rust package's dependencies, compiles your packages, makes distributable packages, and uploads them to crates.io, the Rust community's package registry.


2 Answers

Depending on how you want it structured, you could try a mix of env::current_dir to get the current directory, and if that doesn't find anything you can try using the executable path and load things from there. You get that with env::current_exe.


I see the difficulty, which is that cargo install only copies the binary into .cargo/bin which means that additional resources stay in the source folder located at .cargo/registry/src/....

In this case, I agree with @ljedrz that include! seems to be the only way.

like image 50
Neikos Avatar answered Oct 23 '22 21:10

Neikos


In my private project, I had to replace a "open, seek, read" by a include_bytes! because, as you wrote, cargo install doesn't handle assets. Here's an example:

File::open version

let mut f = File::open("examples/vertices.npy")
    .expect("Can't read file 'examples/vertices.npy'");
f.seek(SeekFrom::Start(80)).unwrap();
let mut reader = BufReader::new(f);

include_bytes! version

let vertices_bytes = include_bytes!("vertices.npy");
let mut reader = BufReader::new(&vertices_bytes[80..]);

I still prefer the normal reader and I'll change it when Rust supports it, but it's still a good solution while we wait.

like image 40
Nil Avatar answered Oct 23 '22 23:10

Nil