This adds a way to specify the `evalSystem` or `evalPackages` explicitly when calling the `project` functions.
Currently if we want to make a `flake` that supports multiple systems we have few options:
* Require builders for all the supported systems (even just for `nix flake show`).
* Pass `--impure` so that haskell.nix can see `builtins.currentSystem` to set up `pkgs.evalPackages` to use that. Unfortunately this prevents nix from caching some of the work it does and often results in it recalculating for each supported system when it would otherwise be cached and take no time at all.
* Add an overlay to replace `evalPackages`. This works, but it is not straight forward.
* Materialize the nix files for the project.
This change allows `evalSystem = "x86_64-linux";` to be passed telling `haskell.nix` to run `cabal` and `nix-tools` on that system. The user will have to have a builder for that system, but does not need to have builders for the others (unless building outputs for them).
* Improve support for external Hackage repositories
This change builds #535. `repository` blocks in `cabal.project` parsed and `cabal` is used to automatically downloaded them. Then `hackage-to-nix` is used to produce the nix required.
To make it work with restricted eval (on hydra for instance) we need to include a sha256 like this:
```
repository ghcjs-overlay
url: https://input-output-hk.github.io/hackage-overlay-ghcjs
secure: True
root-keys:
key-threshold: 0
--sha256: sha256-EPlLYPmIGtxeahlOspRzwJv+60N5mqrNC2BY4jZKceE=
```
To find the correct `sha256` put in an invalid one and attempt a build.
There are now 4 project modules used to check the arguments passed to the various project functions:
* `project-common.nix` - Arguments used by all the project functions
* `stack-project.nix` - Used by the `stackProject` and `stackProject'` functions
* `cabal-project.nix` - Used by the `cabalProject` and `cabalProject'` functions
* `project.nix` - Just the `projectFileName` argument that is used by `project` and `project'` functions to determine whether to call `stackProject` or `cabalProject` function.
This also includes the `rawProject.args` that was mistakenly left out of #1141 causing #1142 and improvements for the docs for the use of the `shell` argument in `flake.nix` files.
The default shell `devShell` works by adding a default `shell` to all projects. You can pass the shell arguments to the project function using the new `shell` argument:
```
let myProject = haskell-nix.project {
src = ./.;
shell.tools = { cabal = {}; };
shell.crossPlatforms = p: [ p.cross ];
};
```
This will include js-unknown-ghcjs-cabal in the `devShell`.
To add cross compiled outputs to the flake pass `crossPlatforms` to the `flake` function.
```
myProject.flake { crossPlatforms = p: [ p.cross ]; }
```
To cross compile a component include the platforms `config` string to the output name like this
```
nix build .#js-unknown-ghcjs:pkg-name:lib:pkg-name
```
* Use nix module system to check project arguments
This change uses the nix module system for the arguments to:
* `cabalProject'`
* `cabalProject`
* `stackProject'`
* `stackProject`
This will:
* Give an error when the name or type of an argument is incorrect
(currently misnamed args are quietly ignored).
* Fixes a problem with `projectCross` not having a way to pass different args to `cabalProject`
for different platforms. We can now use:
`({pkgs, ...}: { cabalProjectLocal = if pkgs.stdenv.hostPlatform.isX then ... })`