I use this default.nix to build my package with nix-build and get the env with nix-shell
{ pkgs ? import <nixpkgs> {} }:
with pkgs;
with haskellPackages;
let
myPackage = callPackage ./myPackage.nix {};
in
if lib.inNixShell then myPackage.env else myPackage
myPackage.nix generated using cabal2nix . > myPackage.nix
{ mkDerivation, base, split, stdenv }:
mkDerivation {
pname = "myPackage";
version = "0.1.0.0";
src = ./.;
isLibrary = false;
isExecutable = true;
executableHaskellDepends = [ base split ];
license = stdenv.lib.licenses.bsd3;
}
This working fine for building but I want to add development helper tools while I working on it. I don't want to edit myPackage.nix. I want to re-run cabal2nix when I edit myPackage.cabal.
I try to use buildInputs of mkDerivation but did not seem to work.
let
myPackage = callPackage ./myPackage.nix {};
in
stdenv.mkDerivation {
name = myPackage.name;
buildInputs = [ myPackage hlint hasktags ];
}
Beside nix-build stop working, it also drop me in the shell with executable of myPackage but without myPackage's env.
I know this because ghc is not avaliable while it exists in myPackage's env when using default.nix above.
How can I add those tools to env generated from cabal2nix ?
The nix-shell commands builds all dependencies of a project, sets all environment variables to their respective derivation attribute values and sources (bash) $stdenv/setup. For more details, see the Nix manual about nix-shell.
So in your last example, if you run echo $buildInputs you'll see your built package as a build input. So that works, but it's not what you want.
Instead, you need to reuse the Haskell-specific environment derivation, myPackage.env. This dummy derivation for nix-shell has a GHC that is set up to discover only your dependencies etc.
pkgs.lib.overrideDerivation myPackage.env (old: {
buildInputs = old.buildInputs ++ [ pkgs.haskellPackages.hlint ];
})
Unsolicited advice ;)
In my projects, I use a shell.nix file for this. This also lets me avoid the lib.inNixShell value that breaks referential transparency.
If your project consists of more than a Haskell package, I recommend writing an overlay. It will make your project much more coherent.
shell.nix
# This imports the project + overlay. The overlay takes care of
# adding `myPackage` to `haskellPackages`, to make it available
# throughout the project.
attrs@{...}:
let pkgs = (import ../nix attrs);
# Adapt myPackage.env
in pkgs.lib.overrideDerivation pkgs.haskellPackages.myPackage.env (old: {
buildInputs = old.buildInputs ++ [ pkgs.haskellPackages.hlint ];
})
For an example of an overlay, see zimbatm's todomvc-nix.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With