Compiling Bevy using NixOS
A guide to compiling Bevy or other Rust/SDL2 programs on NixOS
I recommend reading fasterthanlime’s blog post about compiling rust with nix (flakes).
I also found out later that bevy has a NixOS guide.
Initially I tried to compile it using cargo2nix but that was really slow, complicated, badly documented, and didn’t work in the end. The latest rust version selectable by cargo2nix was 1.76.0, for which Bevy errored out on nightly features (stable in later version). I tried using rust-overlay to select a newer version which worked, but then Bevy errored out on a trait resolution somehow? I still don’t know what the issue is.
But using fasterthanlime’s post and making a simpler dev shell flake, I got the point of my function containing this.
let
overlays = [ (import rust-overlay) ];
rustToolchain = pkgs.pkgsBuildHost.rust-bin.fromRustupToolchainFile ./rust-toolchain.toml;
nativeBuildInputs = with pkgs; [
rustToolchain
mold
pkg-config
];
buildInputs = with pkgs; [ ];
in
{
devShells.default = pkgs.mkShell {
inherit buildInputs nativeBuildInputs;
};
}
If you go and add dependencies by trial and error (or reading Bevy’s docs), you’ll end up with these dependencies for X11 and Wayland respectively, along with Alsa, SystemD and vulkan-loader.
xorgBuildInputs = with pkgs; [ xorg.libX11 xorg.libXcursor xorg.libXi ];
waylandBuildInputs = with pkgs; [ libxkbcommon wayland ];
buildInputs = with pkgs; [
alsa-lib
systemd
vulkan-loader
] ++ xorgBuildInputs ++ waylandBuildInputs;
Because mkShell
doesnt automatically expose buildInputs
’s entries to the linker, you need to manually export it like this.
devShells.default = pkgs.mkShell {
inherit buildInputs nativeBuildInputs;
# 👇 Adding this field
shellHook = ''
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${pkgs.lib.makeLibraryPath buildInputs}"
'';
};
The shellHook
command gets executed when the devShell is entered, so the library paths are exposed to the compiler like so.
[nobbele@delta:~/Projects/moonfox]$ echo $LD_LIBRARY_PATH
...:/nix/store/zcq4irdcgn3ljqdnlpm2zjp7f1kw9jvm-libX11-1.8.10/lib:/nix/store/x9y3nsv92pqbwy9h4ndvvy5vyi1dyhrz-libXcursor-1.2.2/lib:/nix/store/p4mjdx6l2q4ff3ssjwh989rlw4xwljb7-alsa-lib-1.2.12/lib:/nix/store/bl5dgjbbr9y4wpdw6k959mkq4ig0jwyg-systemd-256.10/lib:/nix/store/s2z1araqqjaddfsalibiq64fa48g07j5-vulkan-loader-1.3.296.0/lib:/nix/store/zcq4irdcgn3ljqdnlpm2zjp7f1kw9jvm-libX11-1.8.10/lib:...
The final flake.nix file ended up looking like this.
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.11";
flake-utils.url = "github:numtide/flake-utils";
rust-overlay = {
url = "github:oxalica/rust-overlay";
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs = { self, nixpkgs, flake-utils, rust-overlay }:
flake-utils.lib.eachDefaultSystem
(system:
let
overlays = [ (import rust-overlay) ];
pkgs = import nixpkgs {
inherit system overlays;
};
rustToolchain = pkgs.pkgsBuildHost.rust-bin.fromRustupToolchainFile ./rust-toolchain.toml;
nativeBuildInputs = with pkgs; [ rustToolchain mold pkg-config ];
xorgBuildInputs = with pkgs; [ xorg.libX11 xorg.libXcursor xorg.libXi ];
waylandBuildInputs = with pkgs; [ libxkbcommon wayland ];
buildInputs = with pkgs; [
alsa-lib
systemd
vulkan-loader
] ++ xorgBuildInputs ++ waylandBuildInputs;
in
{
devShells.default = pkgs.mkShell {
inherit buildInputs nativeBuildInputs;
shellHook = ''
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${pkgs.lib.makeLibraryPath buildInputs}"
'';
};
}
);
}
Written