rec { description = ""; 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"; clj-nix.url = "github:jlesquembre/clj-nix"; clj-nix.inputs.nixpkgs.follows = "nixpkgs"; }; outputs = { self, nixpkgs, flake-utils, rust-overlay, clj-nix, }: # 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 mkCmakeScript = type: let typeLower = lib.toLower type; in pkgs.writers.writeFish "cmake-${typeLower}.fish" '' cd $FLAKE_PROJECT_ROOT echo "Removing build directory ./cmake-build-${typeLower}/" rm -rf ./cmake-build-${typeLower} echo "Creating build directory" mkdir cmake-build-${typeLower} cd cmake-build-${typeLower} echo "Running cmake" cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE="${type}" -DCMAKE_EXPORT_COMPILE_COMMANDS="On" .. echo "Linking compile_commands.json" cd .. ln -sf ./cmake-build-${typeLower}/compile_commands.json ./compile_commands.json ''; cmakeDebug = mkCmakeScript "Debug"; cmakeRelease = mkCmakeScript "Release"; mkBuildScript = type: let typeLower = lib.toLower type; in pkgs.writers.writeFish "cmake-build.fish" '' cd $FLAKE_PROJECT_ROOT/cmake-build-${typeLower} echo "Running cmake" cmake --build . ''; buildDebug = mkBuildScript "Debug"; buildRelease = mkBuildScript "Release"; # Use this to specify commands that should be ran after entering fish shell initProjectShell = pkgs.writers.writeFish "init-shell.fish" '' echo "Entering \"${description}\" environment..." # Determine the project root, used e.g. in cmake scripts set -g -x FLAKE_PROJECT_ROOT (git rev-parse --show-toplevel) # Rust Bevy: # abbr -a build-release-windows "CARGO_FEATURE_PURE=1 cargo xwin build --release --target x86_64-pc-windows-msvc" # C/C++: # abbr -a cmake-debug "${cmakeDebug}" # abbr -a cmake-release "${cmakeRelease}" # abbr -a build-debug "${buildDebug}" # abbr -a build-release "${buildRelease}" # Clojure: # abbr -a clojure-deps "deps-lock --lein" # Python: # abbr -a run "python ./app/main.py" # abbr -a profile "py-spy record -o profile.svg -- python ./app/main.py && firefox profile.svg" # abbr -a ptop "py-spy top -- python ./app/main.py" ''; in builtins.concatStringsSep "\n" [ # Launch into pure fish shell '' exec "$(type -p fish)" -C "source ${initProjectShell} && abbr -a menu '${pkgs.bat}/bin/bat "${initProjectShell}"'" '' # Qt: Launch into wrapped fish shell # 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 # =========================================================================================== # Python package example # typed-ffmpeg = pkgs.python313Packages.buildPythonPackage rec { # pname = "typed_ffmpeg"; # version = "3.6"; # # src = pkgs.python313Packages.fetchPypi { # inherit pname version; # hash = "sha256-YPspq/lqI/jx/9FCQntmQPw4lrPIsdxtHTUg0F0QbrM="; # }; # # pyproject = true; # build-system = [ # pkgs.python313Packages.setuptools # pkgs.python313Packages.setuptools-scm # ]; # }; # python = pkgs.python313.withPackages (p: # with p; [ # # numpy # # matplotlib # # typed-ffmpeg # # pyside6 # ]); # rust = pkgs.rust-bin.stable.latest.default.override { # extensions = ["rust-src"]; # Include the Rust stdlib source (for IntelliJ) # }; # 64 bit C/C++ compilers that don't collide (use the same libc) # bintools = pkgs.wrapBintoolsWith { # bintools = pkgs.bintools.bintools; # Unwrapped bintools # libc = pkgs.glibc; # }; # gcc = lib.hiPrio (pkgs.wrapCCWith { # cc = pkgs.gcc.cc; # Unwrapped gcc # libc = pkgs.glibc; # bintools = bintools; # }); # clang = pkgs.wrapCCWith { # cc = pkgs.clang.cc; # Unwrapped clang # libc = pkgs.glibc; # bintools = bintools; # }; # Multilib C/C++ compilers that don't collide (use the same libc) # bintools_multilib = pkgs.wrapBintoolsWith { # bintools = pkgs.bintools.bintools; # Unwrapped bintools # libc = pkgs.glibc_multi; # }; # gcc_multilib = lib.hiPrio (pkgs.wrapCCWith { # cc = pkgs.gcc.cc; # Unwrapped gcc # libc = pkgs.glibc_multi; # bintools = bintools_multilib; # }); # clang_multilib = pkgs.wrapCCWith { # cc = pkgs.clang.cc; # Unwrapped clang # libc = pkgs.glibc_multi; # bintools = bintools_multilib; # }; # =========================================================================================== # 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; [ # Languages: # python # rust # bintools # gcc # clang # bintools_multilib # gcc_multilib # clang_multilib # clojure # jdk # C/C++: # pkg-config # cmake # gnumake # ninja # gdb # valgrind # kdePackages.kcachegrind # perf # hotspot # Clojure: # leiningen # clj-nix.packages.${system}.deps-lock # Java: # gradle # Python: # hatch # py-spy # Qt: # qt6.wrapQtAppsHook # For the shellHook ]; # 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; [ # C/C++: # boost # sfml # raylib # backward-cpp # Qt: # qt6.qtbase # qt6.full ]; # =========================================================================================== # 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 # ''; # }; # package = clj-nix.lib.mkCljApp { # inherit pkgs; # modules = [ # # Option list: https://jlesquembre.github.io/clj-nix/options/ # { # name = ""; # version = "1.0.0"; # main-ns = ""; # projectSrc = ./.; # withLeiningen = true; # buildCommand = "lein uberjar"; # Requires "withLeiningen = true;" # jdk = pkgs.jdk; # Default is pkgs.jdk_headless # # customJdk.enable = true; # # nativeImage.enable = true; # } # ]; # }; 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; # }; }; }); }