@@ -582,10 +582,72 @@ final: prev: {
582582
583583 projectCoverageReport = haskellLib.projectCoverageReport project (map (pkg: pkg.coverageReport) (final.lib.attrValues (haskellLib.selectProjectPackages hsPkgs)));
584584
585+ # `projectCross` is like `pkgsCross`, but for haskell.nix projects.
586+ # To get a cross platform version of the project use
587+ # `projectCross.<system>` where system is a member of nixpkgs lib.systems.examples.
588+ # See https://nixos.wiki/wiki/Cross_Compiling
585589 projectCross = (final.lib.mapAttrs (_: pkgs:
586590 rawProject.projectFunction pkgs.haskell-nix rawProject.projectModule
587591 ) final.pkgsCross) // { recurseForDerivations = false; };
588592
593+ # Add support for passing in `crossPlatforms` argument.
594+ # crossPlatforms is an easy way to include the inputs for a basic
595+ # cross platform shell in a native shell.
596+ #
597+ # For instance if `default.nix` is a project, then `shell.nix` can be:
598+ # (import ./. {}).shellFor {
599+ # tools.cabal = {};
600+ # crossPlatforms = p: [ p.ghcjs ];
601+ # }
602+ #
603+ # This adds support for compiling with ghcjs. To build use the cabal wrapper:
604+ # js-unknown-ghcjs-cabal build all
605+ #
606+ # ## How it Works
607+ #
608+ # The cross compilation shells are made using the `projectCross` attribute
609+ # to get the selected cross compilation projects (e.g. project.projectCross.ghcjs).
610+ #
611+ # The `shellFor` function for those projects is called with arguments based on the
612+ # ones used for the main shell (the `withHoogle` argument is set to `false`).
613+ #
614+ # These shells are added to the main shell using the `inputsFrom` argument.
615+ #
616+ # Without `crossPlatforms` the above example would be:
617+ # let project = import ./. {};
618+ # in project.shellFor {
619+ # tools.cabal = {};
620+ # inputsFrom = [
621+ # (project.platformCross.ghcjs.shellFor { withHoogle = false; })
622+ # ];
623+ # }
624+ #
625+ shellFor = shellArgs:
626+ let
627+ # These are the args we will pass to the main shell.
628+ args' = builtins.removeAttrs shellArgs [ "crossPlatforms" ];
629+ # These are the args we will pass to the shells for the corss compiler
630+ argsCross =
631+ # These things should match main shell
632+ final.lib.filterAttrs (n: _: builtins.elem n [
633+ "packages" "components" "additional" "exactDeps" "packageSetupDeps"
634+ ]) shellArgs // {
635+ # The main shell's hoogle will probably be faster to build.
636+ withHoogle = false;
637+ };
638+ # These are the cross compilation versions of the project we will include.
639+ selectedCrossProjects =
640+ if shellArgs ? crossPlatforms
641+ then shellArgs.crossPlatforms projectCross
642+ else [];
643+ # Shells for cross compilation
644+ crossShells = builtins.map (project: project.shellFor argsCross)
645+ selectedCrossProjects;
646+ in rawProject.hsPkgs.shellFor (args' // {
647+ # Add inputs from the cross compilation shells
648+ inputsFrom = args'.inputsFrom or [] ++ crossShells;
649+ });
650+
589651 # Like `.hsPkgs.${packageName}` but when compined with `getComponent` any
590652 # cabal configure errors are defered until the components derivation builds.
591653 getPackage = packageName:
@@ -681,7 +743,7 @@ final: prev: {
681743 (package.components.tests)
682744 ) packageNames);
683745 };
684− inherit (rawProject.hsPkgs) makeConfigFiles ghcWithHoogle ghcWithPackages shellFor;
746+ inherit (rawProject.hsPkgs) makeConfigFiles ghcWithHoogle ghcWithPackages;
685747 });
686748
687749 cabalProject = args: let p = cabalProject' args;