diff --git a/content/blog/getting-started-with-bevy-on-nixos.org b/content/blog/getting-started-with-bevy-on-nixos.org new file mode 100644 index 0000000000000000000000000000000000000000..72f7532b42827cd2fde5aea8711b5a47d042f6f6 --- /dev/null +++ b/content/blog/getting-started-with-bevy-on-nixos.org @@ -0,0 +1,244 @@ +#+DESCRIPTION: When trying to follow the Bevy getting started guide, I ran into some NixOS related issues. Here's what they were and what I had to do to fix them! +#+PUBLISHED: 2021-08-28T17:31:35+02:00 +#+TAGS: rust, bevy, nixos, ndc, ndc2021 +#+TITLE: Bevy: getting started on NixOS +#+SUBTITLE: A tutorial for the tutorial + +A little while ago, I received the good news that I had gotten two +(/TWO/ 🎉) of my talk proposals accepted by [[https://ndcoslo.com/][NDC Oslo]] this year: one on +profiling performance issues and one on building Rust games for the +browser 🥳 While this /is/ great, it also means that I need to start +doing some serious work, because /these talks don't exist yet/. + +For the talk on building games with Rust, I knew immediately that I +wanted to use [[https://bevyengine.org/][the Bevy game engine]]. However, I've never used Bevy +before, so I thought I'd start with [[https://bevyengine.org/learn/book/introduction/][the Bevy Book]] and [[https://bevyengine.org/learn/book/getting-started/][its /Getting +Started/ section]]. For most cases, the docs should be sufficient, but +if you run NixOS (I do 🙋), then you might run into some cases not +covered by the guide. This post details all the extra steps I had to +take to get through the tutorial. At the end, I'll put the whole +~shell.nix~ file that I ended up with as well as any other changes I +had to make. + +This was for Bevy 0.5 running on NixOS 21.05 on a Dell XPS 9570 using +the NVIDIA graphics card. If your system is different, the steps in +this post may or may not work for you. But if you try and follow the +steps in this post, /do/ let me know how it went [[https://twitter.com/thomasheartman][(@ me on Twitter!]])! + +Oh, and before we get started: I'd like to extend a big thank you to +everyone who helped me out in the [[https://discord.gg/bevy][Bevy discord]] as well as to the +people behind the engine itself and the docs ❤️ + +* Initial setup + +Let's get a dev environment going with the dependencies we need. The +Bevy GitHub repo has a [[https://github.com/bevyengine/bevy/blob/main/docs/linux_dependencies.md#nixos][linux setup file (with a specific section for +NixOS!)]] that tells you what you need. As mentioned in the text, add +this to a ~build.rs~ file (in your project root): + +#+BEGIN_SRC rust + fn main() { + if cfg!(target_os = "linux") { + println!("cargo:rustc-link-lib=vulkan"); + } + } +#+END_SRC + +It also gives you a Nix shell that you can use. It contains most +dependencies, but as we'll see, we need to modify it slightly (or at +least I had to). The version that's there is: + +#+begin_src nix + { pkgs ? import { } }: + with pkgs; + mkShell { + buildInputs = [ + cargo + pkgconfig udev alsaLib lutris + x11 xorg.libXcursor xorg.libXrandr xorg.libXi + vulkan-tools vulkan-headers vulkan-loader vulkan-validation-layers + ]; + } +#+end_src + +* Problem 1: fast compilation + +The first issues I ran into were in [[https://bevyengine.org/learn/book/getting-started/setup/][the /Setup/ section of the guide]]. Specifically around /fast compilation/. + +The guide says to copy [[https://github.com/bevyengine/bevy/blob/main/.cargo/config_fast_builds][this Cargo config file]] into +~YOUR_WORKSPACE/.cargo/config.toml~. This config file enables fast +compilation by configuring the linker and specific Rust flags. The +configuration for building on Linux looks like this: + +#+BEGIN_SRC toml + [target.x86_64-unknown-linux-gnu] + linker = "/usr/bin/clang" + rustflags = ["-Clink-arg=-fuse-ld=lld", "-Zshare-generics=y"] +#+END_SRC + +If you've used NixOS for a bit, you'll probably realize why this won't +work: there's no ~/usr/bin~ directory on NixOS. Also, if you look at +the ~shell.nix~ file from before, there's no ~clang~ /or/ ~lld~ included. + +We'll fix this by changing the linker to just ~clang~ and by adding +~clang~ and ~lld~ to the ~shell.nix~ build inputs. That means the +~.cargo/config.toml~ file should look like this: + +#+BEGIN_SRC toml + [target.x86_64-unknown-linux-gnu] + linker = "clang" + rustflags = ["-Clink-arg=-fuse-ld=lld", "-Zshare-generics=y"] +#+END_SRC + +* Problem 2: Apps + +The next issue I ran into was in [[https://bevyengine.org/learn/book/getting-started/apps/][the next section, /Apps/.]] The basic +"Hello World" program you get when starting a new project via Cargo +built and ran just fine. However, it suddenly stopped working when I +tried to import and use Bevy. + +The error I got was: + +#+begin_example + target/debug/: error while loading shared libraries: + libudev.so.1: cannot open shared object file: No such file or + directory +#+end_example + +The solution was to modify the environment's ~LD_LIBRARY_PATH~ by +adding ~udev~. This took some searching to find out, but thanks to +[[https://github.com/MaikKlein/ash/issues/312#issuecomment-814491730][this GitHub comment]] and @LegendOfMiracles [[https://discordapp.com/channels/691052431525675048/742884593551802431/843481717318484018][post in the Bevy Discord's +#help channel]], I got there in the end. + +In addition to ~udev~ we also need to add ~alsaLib~ to the +~LD_LIBRARY_PATH~. To achieve this, add this to your ~shell.nix~: + +#+BEGIN_SRC nix + shellHook = ''export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${pkgs.lib.makeLibraryPath [ + pkgs.alsaLib + pkgs.udev + ]}"''; +#+END_SRC + +* Problem 3: Plugins + +The third and final problem I ran into was with [[https://bevyengine.org/learn/book/getting-started/plugins/][the section on +/Plugins/]]. When I added ~DefaultPlugins~, the program immediately +panicked with this message: + +#+begin_example + Finished dev [unoptimized + debuginfo] target(s) in 0.08s + Running `target/debug/bevy-tutorial` + thread 'main' panicked at 'Unable to find a GPU! Make sure you have installed required drivers!', /home/thomas/.cargo/registry/src/github.com-1ecc6299db9ec823/bevy_wgpu-0.5.0/src/wgpu_renderer.rs:47:14 + note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace +#+end_example + +Turns out the solution to this was to modify the ~LD_LIBRARY_PATH~ +further and add ~vulkan-loader~ too. When I added the ~vulkan-loader~ +everything ran and worked as expected. + +* Summary and full files + +It took some extra work, but I got there in the end. Below are the +files that I ended up with. In addition to these, remember to also add +the ~build.rs~ file as specified above. + +** ~shell.nix~ + +Here's what I use for the dev environment. I use [[https://github.com/nix-community/fenix][fenix]] for managing +the Rust toolchain. I've also added ~cargo-edit~ and ~cargo-watch~ +because they're handy tools to have. Everything else is Bevy-related. + + #+BEGIN_SRC nix + { pkgs ? import {} }: + + let + + fenix = import "${ + fetchTarball "https://github.com/nix-community/fenix/archive/main.tar.gz" + }/packages.nix"; + + in + + pkgs.mkShell { + shellHook = ''export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${pkgs.lib.makeLibraryPath [ + pkgs.alsaLib + pkgs.udev + pkgs.vulkan-loader + ]}"''; + + buildInputs = with pkgs; [ + ( + with fenix; + combine ( + with default; [ + cargo + clippy-preview + latest.rust-src + rust-analyzer + rust-std + rustc + rustfmt-preview + ] + ) + ) + cargo-edit + cargo-watch + + lld + clang + + # # bevy-specific deps (from https://github.com/bevyengine/bevy/blob/main/docs/linux_dependencies.md) + pkgconfig + udev + alsaLib + lutris + x11 + xorg.libXcursor + xorg.libXrandr + xorg.libXi + vulkan-tools + vulkan-headers + vulkan-loader + vulkan-validation-layers + ]; + + } + #+END_SRC + +** ~.cargo/config.toml~ + +This is what the full ~config.toml~ file looks like after adjusting +the Linux config for NixOS. + +#+BEGIN_SRC toml + # Add the contents of this file to `config.toml` to enable "fast build" configuration. Please read the notes below. + + # NOTE: For maximum performance, build using a nightly compiler + # If you are using rust stable, remove the "-Zshare-generics=y" below. + + [target.x86_64-unknown-linux-gnu] + linker = "clang" + rustflags = ["-Clink-arg=-fuse-ld=lld", "-Zshare-generics=y"] + + # NOTE: you must manually install https://github.com/michaeleisel/zld on mac. you can easily do this with the "brew" package manager: + # `brew install michaeleisel/zld/zld` + [target.x86_64-apple-darwin] + rustflags = ["-C", "link-arg=-fuse-ld=/usr/local/bin/zld", "-Zshare-generics=y"] + + [target.x86_64-pc-windows-msvc] + linker = "rust-lld.exe" + rustflags = ["-Zshare-generics=y"] + + # Optional: Uncommenting the following improves compile times, but reduces the amount of debug info to 'line number tables only' + # In most cases the gains are negligible, but if you are on macos and have slow compile times you should see significant gains. + #[profile.dev] + #debug = 1 +#+END_SRC + + + +----- +That's it for now. I hope this is useful to someone. + +Until next time! 👋 diff --git a/src/css/code.css b/src/css/code.css index 34bd255d98498db9a42c544084840b32179ec89b..ab789e5b5ecf7f5461928bef818cc8a45d5cddaf 100644 --- a/src/css/code.css +++ b/src/css/code.css @@ -17,4 +17,5 @@ pre { border-radius: var(--border-radius); box-shadow: var(--box-shadow); font-size: 0.9em; + color: var(--font-color-code-block) } diff --git a/src/css/preload/variables.css b/src/css/preload/variables.css index c916687b0678047b61e1b5113941dd143d4b1445..b754feb215b2387a82fcfb253d85422cb1e1524c 100644 --- a/src/css/preload/variables.css +++ b/src/css/preload/variables.css @@ -26,6 +26,7 @@ --background-color-inline-code: #e5f5e5; --background-color-code-block: #2d2d2d; + --font-color-code-block: #ccc; --padding-inline-code: 0.125em 0.25em; --font-color-inline-code: var(--highlight-color-dark);