bevy icon indicating copy to clipboard operation
bevy copied to clipboard

`embedded_asset!` is broken on Windows Wasm builds

Open janhohenheim opened this issue 1 year ago • 6 comments

Bevy version

0.14.0

Relevant system information

  • rustc --version: rustc 1.81.0-nightly (6292b2af6 2024-07-02)
  • Running Windows 11
`AdapterInfo { name: "NVIDIA GeForce GTX 1080 Ti", vendor: 4318, device: 6918, device_type: DiscreteGpu, driver: "NVIDIA", driver_info: "555.99", backend: Vulkan }`

What you did

There's a minimal reproduction here: https://github.com/janhohenheim/asset-crash

The relevant code is just this main.rs:

use bevy::{asset::embedded_asset, prelude::*};

fn main() {
    let mut app = App::new();
    app.add_plugins(DefaultPlugins);
    embedded_asset!(app, "splash.png");
    app.run();
}

The setup is:

  • crate
    • src/
      • main.rs
      • splash.png

What went wrong

Running this with cargo run works. Running it on Wasm on Windows instead gives me:

Failed to find src_prefix "src" in "src\\screen\\splash\\mod.rs"

This is the part of the Bevy code that panics: https://github.com/bevyengine/bevy/blob/main/crates/bevy_asset/src/io/embedded/mod.rs#L141 And this is the PR that introduced it: https://github.com/bevyengine/bevy/pull/10383

Note that this is not reproducible on Linux

Additional information

The minimal example has a workaround. Move crate/src/splash.png into crate/assets/splash.png and embed it with embedded_asset!(app, "../assets/splash.png");. For reasons unknown to me, doing the same workaround on https://github.com/TheBevyFlock/bevy-template does not work.

I also tried running the embedded assets example with cargo build --example ... and that one works.

Using load_internal_binary_asset like this works as well:

    load_internal_binary_asset!(
        app,
        SPLASH_IMAGE_HANDLE,
        "splash.png",
        |bytes, _path: String| {
            Image::from_buffer(
                bytes,
                ImageType::Extension("png"),
                default(),
                true,
                ImageSampler::linear(),
                RenderAssetUsages::RENDER_WORLD | RenderAssetUsages::MAIN_WORLD,
            )
            .unwrap()
        }
    );

janhohenheim avatar Jul 09 '24 15:07 janhohenheim

load_internal_binary_asset! doesn't have this issue, but it's awkward to use.

Bevy doesn't seem to use embedded_asset! anywhere internally -- it only uses load_internal_binary_asset! -- so bugs like this take longer to surface.

benfrankel avatar Jul 09 '24 17:07 benfrankel

This seems like a rustc bug. The argument to embedded_asset! that behaves weirdly comes straight from the built-in file! macro, and it seems like it has an edge case. Here is a code snippet I ran inside the bevy template:

let path: &Path = file!().as_ref();
let components = path.components().into_iter().collect::<Vec<_>>();
panic!("path: {} components: {:?}", path.display(), components);

This results in:

Windows native:

path: src\screen\splash.rs components: [Normal("src"), Normal("screen"), Normal("splash.rs")]

Windows wasm:

path: src\screen\splash.rs components: [Normal("src\\screen\\splash.rs")]

And, just to top it off, windows native in a separate project I made to test this:

path: src/main.rs components: [Normal("src"), Normal("main.rs")]

I don't know why file! has both behaviors on Windows yet, but it makes sense that the Windows paths aren't parsed properly on wasm.

kristoff3r avatar Jul 09 '24 22:07 kristoff3r

@kristoff3r that last point sounds like an explanation for why the workaround I reported works in one project but not the other

janhohenheim avatar Jul 09 '24 22:07 janhohenheim

I found the difference between the 2 projects, it happens when a project has both a lib.rs and a main.rs.

So as far as I can tell the file macro gives unix paths in crates without a lib.rs, and windows path with lib.rs.

kristoff3r avatar Jul 09 '24 22:07 kristoff3r

@kristoff3r did you submit a bug report to rustc? If so, could you link it? If not, do you want me to file one for you? Marking this as blocked in the meantime

janhohenheim avatar Jul 10 '24 09:07 janhohenheim

I also encountered this problem when compiling Android targets on Windows:

07-12 10:40:10.005  7706  7734 I RustStdoutStderr: thread '<unnamed>' panicked at D:\rust\cargo\registry\src\index.crate
s.io-6f17d22bba15001f\bevy_asset-0.14.0\src\io\embedded\mod.rs:141:13:
07-12 10:40:10.005  7706  7734 I RustStdoutStderr: Failed to find src_prefix "src" in "src\\menu.rs"
07-12 10:40:10.005  7706  7734 I RustStdoutStderr: note: run with `RUST_BACKTRACE=1` environment variable to display a b
acktrace

The path in Windows is so unique that it does not use the common slash '/'. Perhaps the easiest way to change it is to put file! () call is changed tofile!().replace(r"\", "/") 。 I hope there will be good progress as soon as possible, thank you.

mzdk100 avatar Jul 12 '24 03:07 mzdk100

I found the difference between the 2 projects, it happens when a project has both a lib.rs and a main.rs.

So as far as I can tell the file macro gives unix paths in crates without a lib.rs, and windows path with lib.rs.

Nooooo wayyy That's the reason?

FYI, i cannot load assets at all on windows with main.rs and lib.rs: I get the following error:

2024-08-04T21:49:03.430604Z ERROR bevy_asset::server: Path not found: C:\Users\<path to project dir>\assets\Spaceship.glb#Scene0

kartonrad avatar Aug 04 '24 21:08 kartonrad

I can guarantee that the path actually exists

kartonrad avatar Aug 04 '24 21:08 kartonrad

Oops - no it was not the reason - i was using PathBuf::new("Spaceship.glb#Scene0") That was a headscratcher! Should i make an issue for a better error message - i assume PathBuf is just not a supported AssetPath?

kartonrad avatar Aug 04 '24 21:08 kartonrad

Woops - seems like the label stays part of the path when converting to AssetPath from a PathBuf or Path. I would delete this impl or parse the label here. image

kartonrad avatar Aug 04 '24 21:08 kartonrad

This is another issue, sorry for spamming it in here: #14618

kartonrad avatar Aug 04 '24 22:08 kartonrad

I reproduced this with Bevy main (after 0.16.0). So this is still an issue on WASM + Windows.

P.S. Thank you @janhohenheim for the fantastic MRE!

andriyDev avatar May 09 '25 07:05 andriyDev