Skip to content

Commit

Permalink
Merge pull request #48155 from ElvishJerricco/fix/haskell/shellFor/18.09
Browse files Browse the repository at this point in the history
Backport #46453
  • Loading branch information
basvandijk authored Oct 27, 2018
2 parents 6b60c06 + 2bafa93 commit cbcd5aa
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 92 deletions.
46 changes: 17 additions & 29 deletions pkgs/development/haskell-modules/generic-builder.nix
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{ stdenv, buildPackages, buildHaskellPackages, ghc
, jailbreak-cabal, hscolour, cpphs, nodejs
, jailbreak-cabal, hscolour, cpphs, nodejs, shellFor
}:

let
Expand Down Expand Up @@ -173,8 +173,7 @@ let
(optionalString (versionOlder "7.10" ghc.version && !isHaLVM) "-threaded")
];

isHaskellPkg = x: (x ? pname) && (x ? version) && (x ? env);
isSystemPkg = x: !isHaskellPkg x;
isHaskellPkg = x: x ? isHaskellLibrary;

allPkgconfigDepends = pkgconfigDepends ++ libraryPkgconfigDepends ++ executablePkgconfigDepends ++
optionals doCheck testPkgconfigDepends ++ optionals doBenchmark benchmarkPkgconfigDepends;
Expand All @@ -191,20 +190,15 @@ let
optionals doCheck (testDepends ++ testHaskellDepends ++ testSystemDepends ++ testFrameworkDepends) ++
optionals doBenchmark (benchmarkDepends ++ benchmarkHaskellDepends ++ benchmarkSystemDepends ++ benchmarkFrameworkDepends);

allBuildInputs = propagatedBuildInputs ++ otherBuildInputs;

haskellBuildInputs = stdenv.lib.filter isHaskellPkg allBuildInputs;
systemBuildInputs = stdenv.lib.filter isSystemPkg allBuildInputs;

# When not cross compiling, also include Setup.hs dependencies.
ghcEnv = ghc.withPackages (p:
haskellBuildInputs ++ stdenv.lib.optional (!isCross) setupHaskellDepends);
allBuildInputs = propagatedBuildInputs ++ otherBuildInputs ++ depsBuildBuild;
isHaskellPartition =
stdenv.lib.partition isHaskellPkg allBuildInputs;

setupCommand = "./Setup";

ghcCommand' = if isGhcjs then "ghcjs" else "ghc";
ghcCommand = "${ghc.targetPrefix}${ghcCommand'}";
ghcCommandCaps= toUpper ghcCommand';

nativeGhcCommand = "${nativeGhc.targetPrefix}ghc";

Expand All @@ -214,8 +208,7 @@ let
continue
fi
'';

in
in stdenv.lib.fix (drv:

assert allPkgconfigDepends != [] -> pkgconfig != null;

Expand Down Expand Up @@ -428,6 +421,13 @@ stdenv.mkDerivation ({

compiler = ghc;


getBuildInputs = {
inherit propagatedBuildInputs otherBuildInputs allPkgconfigDepends;
haskellBuildInputs = isHaskellPartition.right;
systemBuildInputs = isHaskellPartition.wrong;
};

isHaskellLibrary = isLibrary;

# TODO: ask why the split outputs are configurable at all?
Expand All @@ -438,23 +438,10 @@ stdenv.mkDerivation ({
# TODO: fetch the self from the fixpoint instead
haddockDir = self: if doHaddock then "${docdir self.doc}/html" else null;

env = stdenv.mkDerivation {
name = "interactive-${pname}-${version}-environment";
buildInputs = systemBuildInputs;
nativeBuildInputs = [ ghcEnv ] ++ nativeBuildInputs;
LANG = "en_US.UTF-8";
LOCALE_ARCHIVE = optionalString (stdenv.hostPlatform.libc == "glibc") "${glibcLocales}/lib/locale/locale-archive";
shellHook = ''
export NIX_${ghcCommandCaps}="${ghcEnv}/bin/${ghcCommand}"
export NIX_${ghcCommandCaps}PKG="${ghcEnv}/bin/${ghcCommand}-pkg"
# TODO: is this still valid?
export NIX_${ghcCommandCaps}_DOCDIR="${ghcEnv}/share/doc/ghc/html"
${if isHaLVM
then ''export NIX_${ghcCommandCaps}_LIBDIR="${ghcEnv}/lib/HaLVM-${ghc.version}"''
else ''export NIX_${ghcCommandCaps}_LIBDIR="${ghcEnv}/lib/${ghcCommand}-${ghc.version}"''}
${shellHook}
'';
env = shellFor {
packages = p: [ drv ];
};

};

meta = { inherit homepage license platforms; }
Expand Down Expand Up @@ -488,3 +475,4 @@ stdenv.mkDerivation ({
// optionalAttrs (hardeningDisable != []) { inherit hardeningDisable; }
// optionalAttrs (stdenv.buildPlatform.libc == "glibc"){ LOCALE_ARCHIVE = "${glibcLocales}/lib/locale/locale-archive"; }
)
)
56 changes: 1 addition & 55 deletions pkgs/development/haskell-modules/lib.nix
Original file line number Diff line number Diff line change
Expand Up @@ -299,12 +299,7 @@ rec {
overrideCabal drv (_: { inherit src version; editedCabalFile = null; });

# Get all of the build inputs of a haskell package, divided by category.
getBuildInputs = p:
(overrideCabal p (args: {
passthru = (args.passthru or {}) // {
_getBuildInputs = extractBuildInputs p.compiler args;
};
}))._getBuildInputs;
getBuildInputs = p: p.getBuildInputs;

# Extract the haskell build inputs of a haskell package.
# This is useful to build environments for developing on that
Expand Down Expand Up @@ -339,55 +334,6 @@ rec {
, ...
}: { inherit doCheck doBenchmark; };

# Divide the build inputs of the package into useful sets.
extractBuildInputs = ghc:
{ setupHaskellDepends ? [], extraLibraries ? []
, librarySystemDepends ? [], executableSystemDepends ? []
, pkgconfigDepends ? [], libraryPkgconfigDepends ? []
, executablePkgconfigDepends ? [], testPkgconfigDepends ? []
, benchmarkPkgconfigDepends ? [], testDepends ? []
, testHaskellDepends ? [], testSystemDepends ? []
, testToolDepends ? [], benchmarkDepends ? []
, benchmarkHaskellDepends ? [], benchmarkSystemDepends ? []
, benchmarkToolDepends ? [], buildDepends ? []
, libraryHaskellDepends ? [], executableHaskellDepends ? []
, ...
}@args:
let inherit (ghcInfo ghc) isGhcjs nativeGhc;
inherit (controlPhases ghc args) doCheck doBenchmark;
isHaskellPkg = x: x ? isHaskellLibrary;
allPkgconfigDepends =
pkgconfigDepends ++ libraryPkgconfigDepends ++
executablePkgconfigDepends ++
lib.optionals doCheck testPkgconfigDepends ++
lib.optionals doBenchmark benchmarkPkgconfigDepends;
otherBuildInputs =
setupHaskellDepends ++ extraLibraries ++
librarySystemDepends ++ executableSystemDepends ++
allPkgconfigDepends ++
lib.optionals doCheck ( testDepends ++ testHaskellDepends ++
testSystemDepends ++ testToolDepends
) ++
# ghcjs's hsc2hs calls out to the native hsc2hs
lib.optional isGhcjs nativeGhc ++
lib.optionals doBenchmark ( benchmarkDepends ++
benchmarkHaskellDepends ++
benchmarkSystemDepends ++
benchmarkToolDepends
);
propagatedBuildInputs =
buildDepends ++ libraryHaskellDepends ++
executableHaskellDepends;
allBuildInputs = propagatedBuildInputs ++ otherBuildInputs;
isHaskellPartition =
lib.partition isHaskellPkg allBuildInputs;
in
{ haskellBuildInputs = isHaskellPartition.right;
systemBuildInputs = isHaskellPartition.wrong;
inherit propagatedBuildInputs otherBuildInputs
allPkgconfigDepends;
};

# Utility to convert a directory full of `cabal2nix`-generated files into a
# package override set
#
Expand Down
42 changes: 34 additions & 8 deletions pkgs/development/haskell-modules/make-package-set.nix
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ let
mkDerivationImpl = pkgs.callPackage ./generic-builder.nix {
inherit stdenv;
nodejs = buildPackages.nodejs-slim;
inherit (self) buildHaskellPackages ghc;
inherit (self) buildHaskellPackages ghc shellFor;
inherit (self.buildHaskellPackages) jailbreak-cabal;
hscolour = overrideCabal self.buildHaskellPackages.hscolour (drv: {
isLibrary = false;
Expand Down Expand Up @@ -256,20 +256,46 @@ in package-set { inherit pkgs stdenv callPackage; } self // {
shellFor = { packages, withHoogle ? false, ... } @ args:
let
selected = packages self;
packageInputs = builtins.map getBuildInputs selected;
haskellInputs =
builtins.filter
(input: pkgs.lib.all (p: input.outPath != p.outPath) selected)
(pkgs.lib.concatMap (p: p.haskellBuildInputs) packageInputs);

packageInputs = map getBuildInputs selected;

name = if pkgs.lib.length selected == 1
then "ghc-shell-for-${(pkgs.lib.head selected).name}"
else "ghc-shell-for-packages";

# If `packages = [ a b ]` and `a` depends on `b`, don't build `b`,
# because cabal will end up ignoring that built version, assuming
# new-style commands.
haskellInputs = pkgs.lib.filter
(input: pkgs.lib.all (p: input.outPath != p.outPath) selected)
(pkgs.lib.concatMap (p: p.haskellBuildInputs) packageInputs);
systemInputs = pkgs.lib.concatMap (p: p.systemBuildInputs) packageInputs;

withPackages = if withHoogle then self.ghcWithHoogle else self.ghcWithPackages;
ghcEnv = withPackages (p: haskellInputs);
nativeBuildInputs = pkgs.lib.concatMap (p: p.nativeBuildInputs) selected;

ghcCommand' = if ghc.isGhcjs or false then "ghcjs" else "ghc";
ghcCommand = "${ghc.targetPrefix}${ghcCommand'}";
ghcCommandCaps= pkgs.lib.toUpper ghcCommand';

mkDrvArgs = builtins.removeAttrs args ["packages" "withHoogle"];
in pkgs.stdenv.mkDerivation (mkDrvArgs // {
name = "ghc-shell-for-packages";
nativeBuildInputs = [(withPackages (_: haskellInputs))] ++ mkDrvArgs.nativeBuildInputs or [];
name = mkDrvArgs.name or name;

buildInputs = systemInputs ++ mkDrvArgs.buildInputs or [];
nativeBuildInputs = [ ghcEnv ] ++ nativeBuildInputs ++ mkDrvArgs.nativeBuildInputs or [];
phases = ["installPhase"];
installPhase = "echo $nativeBuildInputs $buildInputs > $out";
LANG = "en_US.UTF-8";
LOCALE_ARCHIVE = pkgs.lib.optionalString (stdenv.hostPlatform.libc == "glibc") "${buildPackages.glibcLocales}/lib/locale/locale-archive";
"NIX_${ghcCommandCaps}" = "${ghcEnv}/bin/${ghcCommand}";
"NIX_${ghcCommandCaps}PKG" = "${ghcEnv}/bin/${ghcCommand}-pkg";
# TODO: is this still valid?
"NIX_${ghcCommandCaps}_DOCDIR" = "${ghcEnv}/share/doc/ghc/html";
"NIX_${ghcCommandCaps}_LIBDIR" = if ghc.isHaLVM or false
then "${ghcEnv}/lib/HaLVM-${ghc.version}"
else "${ghcEnv}/lib/${ghcCommand}-${ghc.version}";
});

ghc = ghc // {
Expand Down

0 comments on commit cbcd5aa

Please sign in to comment.