haskell.nix
haskell.nix copied to clipboard
Specifying configureFlags in does not recompute dependencies
Specifying something like:
modules = [{ packages.blah.components.library.configureFlags = [ "--flag blah" ]; }];
can potentially trigger a different conditional branch in cabal configurations and lead to a different set of dependencies for a package.
Currently, the dependencies don't seem to be recomputed in that case, leading to Setup: Encountered missing or private dependencies
error.
Adding the exact same flag to cabal.project
for the library leads to dependencies being recomputed and the build succeeding.
Incidentally, this makes it impossible to set flags for tools included in shellFor
.
Using the modules
option is mostly to override things that can't be specified properly with cabal, so cabal.project
(or even cabal.project.local -- for which haskell.nix has some way to generate one on the fly if you need as well), would be the preferred approach.
Incidentally, this makes it impossible to set flags for tools included in
shellFor
.
@ttuegel Can you expand on this?
modules
is too late to change the planed dependencies by setting cabal flags as cabal has already configured the project.
Instead of modules
pass a cabal.project
file for cabal to use when configuring the project.
cabalProject = ''
packages: .
package blah
flags: +blah
'';
If there is already a cabal.project
file use cabalProjectLocal
like this:
cabalProjectLocal = ''
package blah
flags: +blah
'';
For tools
we currently need to use cabalProject
not cabalProjectLocal
(I think that might be a bug really). To set the flag blah
for a tool
called blah
the shellFor
call could look like this:
project.shellFor {
tools.blah.cabalProject = ''
packages: .
package blah
flags: +blah
'';
}
Since "latest"
is the default for version
, this is just a shorter version of:
project.shellFor {
tools = {
blah = {
version = "latest";
cabalProject = ''
packages: .
package blah
flags: +blah
'';
};
};
}
Also worth a reminder that you can always replace tools
with an explicit hackage-project
call and customize whatever you want.
let blah = hackage-project {
name = "blah";
version = "whatever";
}
in shellFor {
buildInputs = [ blah.components.exes.blah-exe ];
...
}
And it is necessary when the package name is not the same as the exe name (although cabal
is handled as a special case).
However it needs to be hackage-package
(not hackage-project
) or use blah.hsPkgs.blah.components.exes.blah-exe
. It also requires the compiler-nix-name
to be passed in (shellFor
tools
default to the compiler used by the project).
So with the cabalProject
something like this should work:
let blah = pkgs.haskell-nix.hackage-package {
name = "blah";
version = "1.0.0.0";
compiler-nix-name = "ghc8107";
cabalProject = ''
packages: .
package blah
flags: +blah
'';
};
in project.shellFor {
buildInputs = [ blah.components.exes.blah-exe ];
...
}
Incidentally, this makes it impossible to set flags for tools included in
shellFor
.@ttuegel Can you expand on this?
@angerman Sorry for being a little vague. @hamishmack and @michaelpj picked up on what I needed. For the record, my specific use case is to build haskell-language-server
with some plugins disabled that I don't use.
Using the
modules
option is mostly to override things that can't be specified properly with cabal, socabal.project
(or even cabal.project.local -- for which haskell.nix has some way to generate one on the fly if you need as well), would be the preferred approach.
This is probably a good design principle, but I wasn't able to understand it from the documentation. Thanks for clarifying!
Instead of
modules
pass acabal.project
file for cabal to use when configuring the project.
@hamishmack Thanks! I couldn't find this in the documentation.
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.