How do I access assets included in a Rust/Cargo pr

2020-03-10 16:50发布

问题:

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.

回答1:

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.



回答2:

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.