haskell.nix icon indicating copy to clipboard operation
haskell.nix copied to clipboard

Specifying configureFlags in does not recompute dependencies

Open ilyakooo0 opened this issue 3 years ago • 6 comments

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.

ilyakooo0 avatar Jul 11 '21 16:07 ilyakooo0

Incidentally, this makes it impossible to set flags for tools included in shellFor.

ttuegel avatar Mar 29 '22 21:03 ttuegel

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?

angerman avatar Mar 30 '22 03:03 angerman

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
      '';
    };
  }; 
} 

hamishmack avatar Mar 30 '22 03:03 hamishmack

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 ];
   ...
}

michaelpj avatar Mar 30 '22 10:03 michaelpj

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 ];
   ...
}

hamishmack avatar Mar 30 '22 11:03 hamishmack

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, 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.

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 a cabal.project file for cabal to use when configuring the project.

@hamishmack Thanks! I couldn't find this in the documentation.

ttuegel avatar Mar 30 '22 13:03 ttuegel

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.

stale[bot] avatar Sep 28 '22 14:09 stale[bot]