nix-env-selector icon indicating copy to clipboard operation
nix-env-selector copied to clipboard

[HELP]: Share your .nix usage propose

Open arrterian opened this issue 3 years ago • 6 comments

Hi guys 👋 I have a plan to create a docs site for the extension. In one of the chapters, I would write about how to use the extension and nix for creating a development environment for different languages and platforms.

Could you guys share with me your nix configs for different cases that using in your real projects? It'll be good to have examples for Haskell, Rust, Go, Java, etc.

arrterian avatar Feb 15 '21 11:02 arrterian

The way I personally use nix for development envs is rather basic but it may suffice for basic documentation.

I only install the language binaries and tooling via nix and then let the languages own build system (cargo, npm, maven) handle building the actual project.

I think for development environments this is an ok practice.

Here's a basic template for an elm development environment.

let
  # pin nixpkgs to a particular commit
  nixpkgsRev = "e924a8823325472a42c06bb519cc59d4c8bda614";
  # a nix function to fetch a tar ball from github
  githubTarball = owner: repo: rev:
    builtins.fetchTarball { url = "https://github.com/${owner}/${repo}/archive/${rev}.tar.gz"; };

  # import set of packages from nixpkgs github repo at a particular revision with the config specified below
  pkgs = import (githubTarball "nixos" "nixpkgs" nixpkgsRev) { };
in
{
  inherit pkgs;
  shell = pkgs.mkShell {
    name = "elm-dev";
    buildInputs = [
      pkgs.elmPackages.elm
      pkgs.elmPackages.elm-format
      pkgs.elmPackages.elm-test
      pkgs.nodejs-15_x
    ];
    shellHook = ''
      echo "start using elm"
    '';
  };
}

Here's one for an old node js project

let
  nixpkgsRev = "1d55adbce8af68fee04f42b562f5376be5a6026c";
  githubTarball = owner: repo: rev:
    builtins.fetchTarball { url = "https://github.com/${owner}/${repo}/archive/${rev}.tar.gz"; };
  pkgs = import (githubTarball "nixos" "nixpkgs" nixpkgsRev) { };
in
with pkgs;{
  shell = mkShell {
    name = "dev env";
    buildInputs = [
      nodejs-10_x
      (yarn.override { nodejs = nodejs-10_x; })
      libpng12
    ];
    LD_LIBRARY_PATH="${pkgs.libpng12}/lib";
    shellHook = ''
      echo "Start working";
      echo "Run yarn serve to run the app";
    '';
  };
}

Mostly the template remains the same except for buildInputs which contains different tools for the language

aszenz avatar Feb 25 '21 16:02 aszenz

@aszenz Awesome! Thank you for sharing.

arrterian avatar Feb 27 '21 17:02 arrterian

There you go, I use flakes with the following flakes.nix for a haskell project:

{
  description = "Package build for gstreamer project";
  inputs.haskellNix.url = "github:input-output-hk/haskell.nix";
  inputs.nixpkgs.follows = "haskellNix/nixpkgs-unstable";
  inputs.flake-utils.url = "github:numtide/flake-utils";
  outputs = { self, haskellNix, nixpkgs, flake-utils }: 
    flake-utils.lib.eachSystem [ "x86_64-linux" "x86_64-darwin" ] (system:
    let
      overlays = [ haskellNix.overlay
        (final: prev: {
          # This overlay adds our project to pkgs
          streamlineProject =
            final.haskell-nix.project' {
              src = ./.;
              compiler-nix-name = "ghc8104";
              # projectFileName = "stack.yaml";
              modules = [{
              # Replace `extra-libraries` dependencies
                packages.cuda.components.library.libs = pkgs.lib.mkForce 
                  [ pkgs.cudatoolkit_10_2 ];
                packages.cuda.components.library.pkgconfig = pkgs.lib.mkForce 
                 [ [ pkgs.cudatoolkit_10_2 ] ];
              }];
            };
          # Maps haskell library names to nixpkgs library names
          "gstreamer-1.0" = pkgs.gst_all_1.gstreamer;
          "gstreamer-plugins-bad-1.0" = pkgs.gst_all_1.gst-plugins-bad;
          "gstreamer-plugins-good-1.0" = pkgs.gst_all_1.gst-plugins-good;
          "gstreamer-plugins-base-1.0" = pkgs.gst_all_1.gst-plugins-base;
          cuda = prev.cudatoolkit_10_2;
        })
      ];
      pkgs = import nixpkgs { inherit system overlays; config.allowUnfree = true; };
      flake = pkgs.streamlineProject.flake {};
      in flake // {
        # Built by `nix build .`
        defaultPackage = flake.packages."streamline:exe:streamline";

        # This is used by `nix develop .` to open a shell for use with
        # `cabal`, `hlint` and `haskell-language-server`
        devShell = pkgs.streamlineProject.shellFor {
          tools = {
            cabal = "latest";
            ghcid = "latest";
            hlint = "latest";
            haskell-language-server = "latest";
          };
        };
      });
}

UPDATE: This works with a shell.nix compatibility layer as described here: https://github.com/arrterian/nix-env-selector/issues/53

jmatsushita avatar Mar 13 '21 16:03 jmatsushita

This is my flake.nix for a rust project I am currently working on.

{
  	inputs = {
		utils.url = "github:numtide/flake-utils";
		naersk.url = "github:nmattia/naersk";
		fenix.url = "github:nix-community/fenix";
  	};

  	outputs = { self, nixpkgs, utils, naersk, fenix }:
	utils.lib.eachDefaultSystem (system: let
		pkgs = nixpkgs.legacyPackages."${system}";
		# Specify Rust Toolchain
		# Use Stable (Default)
		# naersk-lib = naersk.lib."${system}";
		# Use Nightly (provided by fenix)
		naersk-lib = naersk.lib."${system}".override {
			# Use Fenix to get nightly rust
			inherit (fenix.packages.${system}.minimal) cargo rustc;
		};
	in rec {
		# `nix build`
		packages.nixman = naersk-lib.buildPackage {
			pname = "nixman";
			root = ./.;
			nativeBuildInputs = with pkgs; [
				pkg-config
			];
			buildInputs = with pkgs; [
				ncurses
				openssl
			];
		};
		defaultPackage = packages.nixman;

		# `nix run`
		apps.nixman = utils.lib.mkApp {
			drv = packages.nixman;
		};
		defaultApp = apps.nixman;

		# `nix develop`
		devShell = pkgs.mkShell {
			nativeBuildInputs = packages.nixman.nativeBuildInputs;
			buildInputs = packages.nixman.buildInputs;
		};
	});
}

zyansheep avatar Apr 01 '21 23:04 zyansheep

I use https://github.com/yusdacra/nix-cargo-integration in my projects. How it looks in one of my Rust projects' flake.nix:

{
  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
    nixCargoIntegration = {
      url = "github:yusdacra/nix-cargo-integration";
      inputs.nixpkgs.follows = "nixpkgs";
    };
    flakeCompat = {
      url = "github:edolstra/flake-compat";
      flake = false;
    };
  };

  outputs = inputs: inputs.nixCargoIntegration.lib.makeOutputs {
    root = ./.;
    buildPlatform = "crate2nix";
    overrides = {
      shell = common: prev: {
        packages = prev.packages ++ [ common.pkgs.musl.dev ];
        commands = prev.commands ++ [
          {
            name = "generate-cert";
            command = ''
              mkcert localhost 127.0.0.1 ::1
              mv localhost+2.pem cert.pem
              mv localhost+2-key.pem key.pem
            '';
          }
          {
            name = "run-with-console";
            command = ''RUSTFLAGS="--cfg tokio_unstable" cargo r --features console'';
          }
        ];
      };
    };
  };
}

yusdacra avatar Sep 11 '21 10:09 yusdacra

flake.nix for Haskell is the same to @jmatsushita 's

lsap avatar Mar 11 '24 10:03 lsap