4

I'm trying to follow bevy's tutorial and setup everything on Windows 10 (21H1) x64. The setup kinda works. I did the following build optimizations (from bevy's tutorial):

  1. bevy's dynamic link feature
  2. switch to the LLD linker
  3. switch to latest rust nightly
  4. disable shared generics (because of this issue)

My cargo.toml

[package]
name = "foo"
version = "0.1.0"
authors = ["foo <foo@bar.com>"]
edition = "2018"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
bevy = "0.5"

My main.rs (the only code file so far):

use bevy::prelude::*;

fn main() {
    println!("hello");
    App::build().run();
}

My .cargo/config.toml:

[target.x86_64-pc-windows-msvc]
linker = "rust-lld.exe"
rustflags = ["-Zshare-generics=off"]

After building my application, target/debug/ looks something like this (I removed some entries):

deps/
bevy_dylib.dll
bevy_dylib.dll.lib
bevy_dylib.pdb
foo.d
foo.exe
foo.pdb

I can build and run the application just fine using cargo with the command cargo run --features bevy/dynamic. The program prints "hello" and exists normally. However, if I run the program from the terminal (powershell in my case) nothing is print and the program exists with no error code. Seeing that lldb also crashes with "unknown error" I went ahead and took a closer look with procmon.

cargo run vs .\foo.exe

Using cargo run --features bevy/dynamic works fine, but .\foo.exe (run directly from powershell) fails without errors. Procmon reveals that .\foo.exe tries to load a different dll, it searches for bevy_dylib-d54840081e5b3869.dll instead of bevy_dylib.dll. This obviously fails because this file doesn't exist and so the program terminates before it even reaches main().

But why does cargo run --features bevy/dynamic work then? Well it turns out that the program still tries to load bevy_dylib-d54840081e5b3869.dll, however this time the loader looks up different paths. There is an additional search path: {my_project}/target/debug/deps/. And that directory actually has a dll with that exact name which is then loaded and the program can execute normally. So it turns out we never even try to use the dll target/debug/bevy_dylib.dll which makes me wonder why it's there in the first place.

My questions are:

  1. Why does cargo run use additional lookup directories at load time linking?
  2. Why does the program search for bevy_dylib-d54840081e5b3869.dll instead of bevy_dylib.dll?
  3. Is this fixable without some nasty post build tasks that copy dlls manually around?
Timo
  • 9,269
  • 2
  • 28
  • 58
  • Have the same problem. The exe file does not work from file explorer. But I see the error that it cannot find this bevy-dylib-xxx.dll. – keiv.fly May 01 '22 at 22:02

1 Answers1

0

The --features bevy/dynamic is only really intended for enabling fast builds while developing your app. For release builds you want to distribute, it's almost always better to not use that feature and then the exe will not require the dll.

This is noted in the bevy setup instructions:

NOTE: Remember to revert this before releasing your game! Otherwise you will need to include libbevy_dylib alongside your game if you want it to run. If you remove the "dynamic" feature, your game executable can run standalone.

I wasn't able to figure out how to ship the dll next to your game, it didn't seem to work for me even by finding and moving the dll that has the numbers into the same directory. Sorry if you need to do that for some reason. For most people that's not actually what they want anyway, just remove the dynamic feature for releases.

Paul Hansen
  • 1,167
  • 1
  • 10
  • 23