rec { description = "Rust Environment"; inputs = { nixpkgs.url = "nixpkgs"; # Use nixpkgs from system registry flake-utils.url = "github:numtide/flake-utils"; rust-overlay.url = "github:oxalica/rust-overlay"; rust-overlay.inputs.nixpkgs.follows = "nixpkgs"; }; outputs = { self, nixpkgs, flake-utils, rust-overlay, }: # Create a shell (and possibly package) for each possible system, not only x86_64-linux flake-utils.lib.eachDefaultSystem (system: let # ========================================================================================= # Define pkgs/stdenvs # ========================================================================================= pkgs = import nixpkgs { inherit system; config.allowUnfree = true; overlays = [ rust-overlay.overlays.default ]; }; # clangPkgs = import nixpkgs { # inherit system; # config.allowUnfree = true; # overlays = []; # # # Use this to change the compiler: # # - GCC: pkgs.stdenv # # - Clang: pkgs.clangStdenv # # NixOS packages are built using GCC by default. Using clang requires a full rebuild/redownload. # config.replaceStdenv = {pkgs}: pkgs.clangStdenv; # }; # Package set for cross-compilation # windowsPkgs = import nixpkgs { # inherit system; # crossSystem = { # config = "x86_64-w64-mingw32"; # }; # config.allowUnfree = true; # }; inherit (pkgs) lib stdenv; # ========================================================================================= # Define shell environment # ========================================================================================= # Setup the shell when entering the "nix develop" environment (bash script). shellHook = let # Add project-local fish abbrs here abbrs = { # Rust Bevy: build-release-windows = "CARGO_FEATURE_PURE=1 cargo xwin build --release --target x86_64-pc-windows-msvc"; }; eraseAbbr = name: value: ''abbr --erase ${name} 2>/dev/null''; createAbbr = name: value: ''abbr -a ${name} "${value}"''; # This will be sourced by the global fish config if INIT_PROJECT_SHELL gets unset unloadProjectShell = pkgs.writers.writeFish "unload-shell.fish" '' echo "Unloading \"${description}\" environment..." ${builtins.concatStringsSep "\n" (lib.mapAttrsToList eraseAbbr abbrs)} ''; # This will be sourced by the global fish config if INIT_PROJECT_SHELL gets set initProjectShell = pkgs.writers.writeFish "init-shell.fish" '' # Unload just in case, to not have redefinition errors source ${unloadProjectShell} echo "Sourcing \"${description}\" environment..." ${builtins.concatStringsSep "\n" (lib.mapAttrsToList createAbbr abbrs)} ''; in builtins.concatStringsSep "\n" [ # Launch into pure fish shell '' # Determine the project root, used e.g. in cmake scripts export FLAKE_PROJECT_ROOT="$(git rev-parse --show-toplevel)" # Can't do the "exec" with nix-direnv # - The "exec fish" would call direnv again => Infinite loop # - The shellHook is Bash/POSIX, so fish syntax doesn't work # Use this for "nix develop" without direnv # exec "$(type -p fish)" -C "source ${initProjectShell} && abbr -a menu '${pkgs.bat}/bin/bat "${initProjectShell}"'" # Use this for direnv without "nix develop" export INIT_PROJECT_SHELL="${initProjectShell}" export UNLOAD_PROJECT_SHELL="${unloadProjectShell}" '' # Qt: Launch into wrapped fish shell (direnv incompatible) # https://nixos.org/manual/nixpkgs/stable/#sec-language-qt # '' # fishdir=$(mktemp -d) # makeWrapper "$(type -p fish)" "$fishdir/fish" "''${qtWrapperArgs[@]}" # exec "$fishdir/fish" -C "source ${initProjectShell} && abbr -a menu '${pkgs.bat}/bin/bat "${initProjectShell}"'" # '' ]; # =========================================================================================== # Define custom dependencies # =========================================================================================== rust = pkgs.rust-bin.stable.latest.default.override { extensions = ["rust-src"]; # Include the Rust stdlib source (for IntelliJ) targets = ["x86_64-unknown-linux-gnu" "x86_64-pc-windows-msvc"]; }; # =========================================================================================== # Specify dependencies # https://nixos.org/manual/nixpkgs/stable/#ssec-stdenv-dependencies-overview # Just for a "nix develop" shell, buildInputs can be used for everything. # =========================================================================================== # Add dependencies to nativeBuildInputs if they are executed during the build: # - Those which are needed on $PATH during the build, for example cmake and pkg-config # - Setup hooks, for example makeWrapper # - Interpreters needed by patchShebangs for build scripts (with the --build flag), which can be the case for e.g. perl nativeBuildInputs = with pkgs; [ rust mold cargo-expand cargo-xwin pkg-config ]; # Add dependencies to buildInputs if they will end up copied or linked into the final output or otherwise used at runtime: # - Libraries used by compilers, for example zlib # - Interpreters needed by patchShebangs for scripts which are installed, which can be the case for e.g. perl buildInputs = with pkgs; [ udev alsa-lib vulkan-loader libxkbcommon wayland ]; # =========================================================================================== # Define buildable + installable packages # =========================================================================================== # package = stdenv.mkDerivation { # inherit nativeBuildInputs buildInputs; # pname = ""; # version = "1.0.0"; # src = ./.; # # installPhase = '' # runHook preInstall # # mkdir -p $out/bin # cp -rv ./${pname} $out/bin/ # # runHook postInstall # ''; # }; # windowsPackage = windowsPkgs.stdenv.mkDerivation rec { # pname = ""; # version = "1.0.0"; # src = ./.; # # # nativeBuildInputs must be from the build-platform (not cross) # # so we use "pkgs" here, not "windowsPkgs" # nativeBuildInputs = with pkgs; [ # cmake # ]; # # buildInputs = with windowsPkgs; []; # # cmakeFlags = [ # "-DCMAKE_SYSTEM_NAME=Windows" # ]; # # installPhase = '' # runHook preInstall # # mkdir -p $out/bin # cp ./${pname}.exe $out/bin/ # # runHook postInstall # ''; # }; in rec { # Provide package for "nix build" # packages = { # default = package; # windows = windowsPackage; # }; # apps = { # default = flake-utils.lib.mkApp {drv = package;}; # }; devShells = { # Provide default environment for "nix develop". # Other environments can be added below. default = pkgs.mkShell { inherit nativeBuildInputs buildInputs shellHook; name = description; # ========================================================================================= # Define environment variables # ========================================================================================= # Rust stdlib source: RUST_SRC_PATH = "${rust}/lib/rustlib/src/rust/library"; # Custom dynamic libraries: # LD_LIBRARY_PATH = builtins.concatStringsSep ":" [ # # Rust Bevy GUI app: # # "${pkgs.libx11}/lib" # # "${pkgs.libxcursor}/lib" # # "${pkgs.libxrandr}/lib" # # "${pkgs.libxi}/lib" # # "${pkgs.libGL}/lib" # # # JavaFX app: # # "${pkgs.libGL}/lib" # # "${pkgs.gtk3}/lib" # # "${pkgs.glib.out}/lib" # # "${pkgs.xorg.libXtst}/lib" # ]; # Dynamic libraries from buildinputs: LD_LIBRARY_PATH = nixpkgs.lib.makeLibraryPath buildInputs; # QT imports to use with "qmlls -E" # QML_IMPORT_PATH = "${pkgs.qt6.full}/lib/qt-6/qml"; # Set PYTHONPATH # PYTHONPATH = "."; # Set matplotlib backend # MPLBACKEND = "TkAgg"; }; # Provide environment with clang stdenv for "nix develop .#clang" # clang = # pkgs.mkShell.override { # stdenv = pkgs.clangStdenv; # } { # inherit shellHook; # name = description; # # # If not required, use pkgs instead of clangPkgs for a lighter build # nativeBuildInputs = with pkgs; []; # buildInputs = with pkgs; []; # # # ========================================================================================= # # Define environment variables # # ========================================================================================= # # # Dynamic libraries from buildinputs: # LD_LIBRARY_PATH = nixpkgs.lib.makeLibraryPath buildInputs; # }; }; }); }