Michael-F-Bryan / include_dir

The logical evolution of the include_str macro for embedding a directory tree into your binary.
https://michael-f-bryan.github.io/include_dir
MIT License
319 stars 36 forks source link

Add a macro which includes a dir from `OUT_DIR` #56

Closed JakubValtar closed 2 years ago

JakubValtar commented 3 years ago

This PR adds a new macro which resolves the path relative to OUT_DIR environment variable, as opposed to CARGO_MANIFEST_DIR.

This is useful for crates which use a build script (build.rs) to generate some files and wish to include them in the binary. OUT_DIR is the only directory where the build script should write files (reference).

I switched env::var to env:var_os to remove the roundtrip OsString -> Unicode -> OsString. The macros should now work even if the project path is not a valid Unicode string.

Resolves #55

Michael-F-Bryan commented 3 years ago

I'm not a massive fan of introducing another macro which just changes how include_dir!()'s path is interpreted.

As an alternative, what about requiring paths to start with either $CARGO_MANIFEST_DIR or $OUT_DIR so we know where they are meant to be resolved relative to? We could allow arbitrary variable interpolation, but that may make things too powerful and let you create code that can't be run on other machines.

Or another alternative, what about exposing some of the code generation tools used by the include_dir!() macro so they can be used from build.rs?

You are already generating some code in build.rs, so that would let you reuse the include_dir!() plumbing and generate your own code for embedding the contents of $OUT_DIR. It also gives you the ability to tweak things however you want.

I'm envisioning a crate structure like this:

JakubValtar commented 3 years ago

As an alternative, what about requiring paths to start with either $CARGO_MANIFEST_DIR or $OUT_DIR

That seems quite non-standard and might be a pain to implement. As a user I would have to google for the name of that variable, I don't remeber how it's called (CARGO_MANIFEST_DIR)

Or another alternative, what about exposing some of the code generation tools used by the include_dir!() macro so they can be used from build.rs?

I think this will be too difficult to use. Using build.rs doesn't necessarily mean you are generating Rust code. In my case, I build an npm project (web frontend) and then include it into the executable of my Rust server.

How about adding a macro_rules macro which can do both? You'd have to have a frontend crate though, since you can't export a macro_rules macro from a proc macro crate.

// Hardcode an OUT_DIR variant
include_dir!("relative/to/root");
include_dir!(out_dir: "relative/to/out-dir");

or something like this (probably an overkill, I think most of the time people want the project root and much less frequently OUT_DIR, other env vars will be very rare)

// Add a variant which accepts a name of an env var to load the parent path from
include_dir!("relative/to/root");
include_dir!("relative/to/env_var", parent = ENV_VAR);
VZout commented 3 years ago

This is a feature I'm interested in as well. Could we get an update on this?

Michael-F-Bryan commented 2 years ago

66 now allows your path to contain environment variables so you can do include_dir!("$OUT_DIR/whatever").

JakubValtar commented 2 years ago

Thanks for implementing it, Michael!