In my flake.nix
I define a shell like this
devShells.default = hsPkgs.shellFor {
packages = _: [ project ];
doBenchmark = true;
nativeBuildInputs = with hsPkgs; [
haskell-language-server
];
};
where project
is defined using developPackage
. AFAIU the doBenchmark = true;
should make my benchmark dependencies (the package criterion
) available in the devshell, but I don’t see it:
❯ ghc-pkg list | grep crit
❯
My Cabal file contains
benchmark redihs-bench
import: base
type: exitcode-stdio-1.0
hs-source-dirs: bench
main-is: Bench.hs
build-depends:
criterion,
rehsp,
Have I misunderstood how to use doBenchmark
?
From the docs:
This is a shortcut for enabling doBenchmark
via genericBuilderArgsModifier
where genericBuilderArgsModifier
:
This argument accepts a function allowing you to modify the arguments passed to mkDerivation
in order to create the development environment.
Now, this is maybe not super clear, but the way it works is this: shellFor
takes hsPkgs
and overrides them to use the changed mkDerivation
. The resulting overridden package set is then passed to the packages
function. Consequently you should never define your package independently of this package set, as you do in your code. You need to take developPackage
or any other helpers from the given package set fix point or shellFor
well behave unexpectedly or produce broken package environments.
It’s still not super clear. Do you mean that I should add my package to a package set based on hspkgs
, e.g. via an override
, and then use this new package set’s shellFor
and in packages
pick my added package?
I’ll try it, but I’m not sure that’s what you mean… maybe there’s an example somewhere of how to use it correctly?
All right, I think I’ve got it.
I add my package to the set with
hsPkgs = haskell.packages.ghc983.override (prevArgs: {
overrides = newpkgs: oldpkgs: {
rehsp = hsPkgs.developPackage {
root = lib.sourceFilesBySuffices ./. [ ".cabal" ".hs" "LICENSE" ];
name = "rehsp";
modifier = hl.doBenchmark;
};
};
});
and then I create the shell using
devShells.default = hsPkgs.shellFor {
packages = p: [ p.rehsp ];
doBenchmark = true;
nativeBuildInputs = with hsPkgs; [
cabal-install
haskell-language-server
];
};
I’m I understanding you correctly, @sternenseemann ?
Yes. You technically don’t need to add any packages to the base hsPkgs
. You are getting the package set fix point passed to your packages
function which allows you to do all sorts of things. In the simplest case you can do something like
haskellPackages.shellFor {
packages = p: [ (p.developPackage { … }) ];
# or even packages = p: [ (p.callCabal2nix ...) ];
}
If you need the derivation for something else as well, having it added to a package set you can work with is handy, of course.
Note that you are still being undisciplined about the fix point in your example in the overrides
argument you should only be using newpkgs
or oldpkgs
(if you are changing a package) to refer to packages / functions in the package set.
For the record, you could also just use developPackage
with the returnShellEnv
argument, but I guess you want additional dev tools?
1 Like