I have a cargo workspace organized like this:
Cargo.toml
|-foo
| |-Cargo.toml
|  -src
|   |-main.rs
|-foo-runtime
| |-Cargo.toml
|  -src
|   |-lib.rs
|-target
main.rs has code somewhere that looks like
use std::sync::LazyLock;
use wasmer::{imports, Instance, Module, Store};
static RUNTIME_WASM: &[u8] = include_bytes!(???);
static INSTANCE: LazyLock<wasmer::Instance> = LazyLock::new(|| {
    let mut store = Store::default();
    let module = Module::from_binary(&store, RUNTIME_WASM)
        .unwrap_or_else(|e| panic!("couldn't load WASM module: {e}"));
    let import_object = imports! {};
    Instance::new(&mut store, &module, &import_object)
        .unwrap_or_else(|e| panic!("failed to create wasmer Instance: {e}"))
});
while lib.rs has code that looks like
#[no_mangle]
pub extern fn add_i64(a: i64, b: i64) -> i64 {
    a + b
}
foo-runtime/Cargo.toml looks like
cargo-features = ["per-package-target"]
[package]
default-target = "wasm32-unknown-unknown"
[lib]
crate-type = ["cdylib"]
so that cargo build on the foo-runtime crate produces target/wasm32-unknown-unknown/debug/foo_runtime.wasm. So far so good.
Now I want the rust binary crate foo to depend on the foo-runtime crate and in particular be able to include foo_runtime.wasm at compile-time, possibly using include_bytes!() as above. Loading at runtime would also be fine, but the questions in either case are (1) how do I correctly construct the path to foo_runtime.wasm during compile- (or run-) time in main.rs; and (2) how do I trigger all the necessary rebuilds when something in the dependencies changes?
I had thought the bindeps cargo experimental feature was the answer, but adding this to foo's Cargo.toml
[dependencies]
foo-runtime = { path = "../foo-runtime", artifact = "cdylib", target = "wasm32-unknown-unknown" }
doesn't work because this only causes cargo to compile a .so/.dylib shared library, not a .wasm binary, although it places it exactly where include_bytes!() would find it. (And I think it also correctly manages dependency rebuilds.)