Open arrterian opened 3 years ago
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 Awesome! Thank you for sharing.
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
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;
};
});
}
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'';
}
];
};
};
};
}
flake.nix for Haskell is the same to @jmatsushita 's
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.