rksm / hot-lib-reloader-rs

Reload Rust code without app restarts. For faster feedback cycles.
MIT License
577 stars 21 forks source link

Setting an absolute path to the lib dir. #22

Closed All8Up closed 1 year ago

All8Up commented 1 year ago

Unfortunately I have to change the working directory of the application which I was trying this on and found that the reloader blows up because it is assuming the target is relative to current working directory. The initial thought was to do something based on env! and/or related items but I don't believe I can get those passed into the proc-macro attributes properly. (Or I just suck with that bit of meta-programming, very possible.. :) ) So, I was wondering if it would be viable to do something which delays the reloader setup till entry into main such that I could then tell it, at runtime, use xyz path as the root path rather than assuming things are relative.

If I could set it in main, then I can use the env! macro and fiddle the compile time result to point to the correct place, i.e. a rooted path from the manifest directory down to the containing workspace directory where the 'target' folder lives. Or, I'd love a pointer on how to build that path such that the proc macro attribute would accept it correctly. I.e. I need: env!("CARGO_MANIFEST_DIR") + "/../../" to get the correct base path. But, of course that could change if I'm using the lib as a pulled crate rather than a part of the larger project (which is an eventual desire).

Thoughts and suggestions very welcome.

rksm commented 1 year ago

Hi there, thanks for opening this! So the quick fix for this is to specify the path to the directory where the library artifact can be found directly:

#[hot_lib_reloader::hot_module(
    dylib = "lib",
    lib_dir = "/path/to/your/project/target/debug"
)]
mod hot_lib {
    /* rest as usual */
}

That path should either be absolute or relative from your working dir (though that might not make much sense).

Right now that path can only be a literal string, not an expression. I'll put out a new version that will allow to do something like

#[hot_lib_reloader::hot_module(
    dylib = "lib",
    lib_dir = concat!(env!("CARGO_MANIFEST_DIR"), "/target/debug")
)]
mod hot_lib {
    /* rest as usual */
}

which should make this a bit more general.

All8Up commented 1 year ago

Hi there, thanks for opening this! So the quick fix for this is to specify the path to the directory where the library artifact can be found directly:


#[hot_lib_reloader::hot_module(
    dylib = "lib",
    lib_dir = "/path/to/your/project/target/debug"
)]

That's what I ended up doing temporarily, unfortunately I'm not sure it actually works. While I see the new hot libs built, copied and then I get the events for the reload and reloaded, no changes seem to be getting applied. I'm not actually sure if it is something I'm doing wrong or just the way I'm setting things up with the path in an unusual location. I'll be taking another look when you get the proposed change done.

#[hot_lib_reloader::hot_module(
    dylib = "lib",
    lib_dir = concat!(env!("CARGO_MANIFEST_DIR"), "/target/debug")
)]

Hah, that looks like what I tried the first time.. Thank you greatly for the change.

rksm commented 1 year ago

In version 0.6.4 the default lib_dir was changed and when it is customized, using an expression instead of just a literal string should work.

So

#[hot_module(dylib = "lib")]
/* ... */

expands to

#[hot_module(dylib = "lib", lib_dir = concat!(env!("CARGO_MANIFEST_DIR"), "/target/debug"))]
/* ... */

(or the target/release folder in release builds). Before it was just a relative path lib_dir = "target/debug" / lib_dir = "targe/release" which caused the issues when changing the working dir.

So in theory just updating should fix your problem. If not try setting the lib_dir. And if that doesn't help, feel free to reopen ;)

jrmoulton commented 3 months ago

Is there a reason you picked to use CARGO_MANIFEST_DIR instead of CARGO_TARGET_DIR?

The cargo build folder isn't always in the the same folder as the manifest as it can be set by using that environment variable.