aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Bauer <mjbauer95@gmail.com>2020-01-17 18:00:27 -0500
committerMatthew Bauer <mjbauer95@gmail.com>2020-01-17 18:00:27 -0500
commit07db0b248c4c0d5404a54c01d61b0c07f744a859 (patch)
treefbe06b854d78ff802b3cf79e00f2cfd8da1b5dfd
parentac65998957255aa4b67f771e9889534dcfe2298d (diff)
parentcb46b97ae93b0c26af5ab65ee7f2f9b291027f43 (diff)
Merge remote-tracking branch 'obsidiansystems/work-on-multi-shellFor'
-rw-r--r--pkgs/development/haskell-modules/generic-builder.nix148
-rw-r--r--pkgs/development/haskell-modules/make-package-set.nix82
-rw-r--r--pkgs/test/default.nix2
-rw-r--r--pkgs/test/haskell-shellFor/default.nix24
-rw-r--r--pkgs/top-level/release.nix2
5 files changed, 194 insertions, 64 deletions
diff --git a/pkgs/development/haskell-modules/generic-builder.nix b/pkgs/development/haskell-modules/generic-builder.nix
index 5410fccf0bb4..c93fc5b7e451 100644
--- a/pkgs/development/haskell-modules/generic-builder.nix
+++ b/pkgs/development/haskell-modules/generic-builder.nix
@@ -1,5 +1,6 @@
{ stdenv, buildPackages, buildHaskellPackages, ghc
-, jailbreak-cabal, hscolour, cpphs, nodejs, shellFor
+, jailbreak-cabal, hscolour, cpphs, nodejs
+, ghcWithHoogle, ghcWithPackages
}:
let
@@ -206,21 +207,28 @@ let
optionals doCheck testPkgconfigDepends ++ optionals doBenchmark benchmarkPkgconfigDepends;
depsBuildBuild = [ nativeGhc ];
- nativeBuildInputs = [ ghc removeReferencesTo ] ++ optional (allPkgconfigDepends != []) pkgconfig ++
- setupHaskellDepends ++
- buildTools ++ libraryToolDepends ++ executableToolDepends ++
- optionals doCheck testToolDepends ++
- optionals doBenchmark benchmarkToolDepends;
+ collectedToolDepends =
+ buildTools ++ libraryToolDepends ++ executableToolDepends ++
+ optionals doCheck testToolDepends ++
+ optionals doBenchmark benchmarkToolDepends;
+ nativeBuildInputs =
+ [ ghc removeReferencesTo ] ++ optional (allPkgconfigDepends != []) pkgconfig ++
+ setupHaskellDepends ++ collectedToolDepends;
propagatedBuildInputs = buildDepends ++ libraryHaskellDepends ++ executableHaskellDepends ++ libraryFrameworkDepends;
- otherBuildInputs = extraLibraries ++ librarySystemDepends ++ executableSystemDepends ++ executableFrameworkDepends ++
- allPkgconfigDepends ++
- optionals doCheck (testDepends ++ testHaskellDepends ++ testSystemDepends ++ testFrameworkDepends) ++
- optionals doBenchmark (benchmarkDepends ++ benchmarkHaskellDepends ++ benchmarkSystemDepends ++ benchmarkFrameworkDepends);
-
-
- allBuildInputs = propagatedBuildInputs ++ otherBuildInputs ++ depsBuildBuild ++ nativeBuildInputs;
- isHaskellPartition =
- stdenv.lib.partition isHaskellPkg allBuildInputs;
+ otherBuildInputsHaskell =
+ optionals doCheck (testDepends ++ testHaskellDepends) ++
+ optionals doBenchmark (benchmarkDepends ++ benchmarkHaskellDepends);
+ otherBuildInputsSystem =
+ extraLibraries ++ librarySystemDepends ++ executableSystemDepends ++ executableFrameworkDepends ++
+ allPkgconfigDepends ++
+ optionals doCheck (testSystemDepends ++ testFrameworkDepends) ++
+ optionals doBenchmark (benchmarkSystemDepends ++ benchmarkFrameworkDepends);
+ # TODO next rebuild just define as `otherBuildInputsHaskell ++ otherBuildInputsSystem`
+ otherBuildInputs =
+ extraLibraries ++ librarySystemDepends ++ executableSystemDepends ++ executableFrameworkDepends ++
+ allPkgconfigDepends ++
+ optionals doCheck (testDepends ++ testHaskellDepends ++ testSystemDepends ++ testFrameworkDepends) ++
+ optionals doBenchmark (benchmarkDepends ++ benchmarkHaskellDepends ++ benchmarkSystemDepends ++ benchmarkFrameworkDepends);
setupCommand = "./Setup";
@@ -462,17 +470,61 @@ stdenv.mkDerivation ({
runHook postInstall
'';
- passthru = passthru // {
+ passthru = passthru // rec {
inherit pname version;
compiler = ghc;
+ # All this information is intended just for `shellFor`. It should be
+ # considered unstable and indeed we knew how to keep it private we would.
+ getCabalDeps = {
+ inherit
+ buildDepends
+ buildTools
+ executableFrameworkDepends
+ executableHaskellDepends
+ executablePkgconfigDepends
+ executableSystemDepends
+ executableToolDepends
+ extraLibraries
+ libraryFrameworkDepends
+ libraryHaskellDepends
+ libraryPkgconfigDepends
+ librarySystemDepends
+ libraryToolDepends
+ pkgconfigDepends
+ setupHaskellDepends
+ ;
+ } // stdenv.lib.optionalAttrs doCheck {
+ inherit
+ testDepends
+ testFrameworkDepends
+ testHaskellDepends
+ testPkgconfigDepends
+ testSystemDepends
+ testToolDepends
+ ;
+ } // stdenv.lib.optionalAttrs doBenchmark {
+ inherit
+ benchmarkDepends
+ benchmarkFrameworkDepends
+ benchmarkHaskellDepends
+ benchmarkPkgconfigDepends
+ benchmarkSystemDepends
+ benchmarkToolDepends
+ ;
+ };
- getBuildInputs = {
+ # Attributes for the old definition of `shellFor`. Should be removed but
+ # this predates the warning at the top of `getCabalDeps`.
+ getBuildInputs = rec {
inherit propagatedBuildInputs otherBuildInputs allPkgconfigDepends;
haskellBuildInputs = isHaskellPartition.right;
systemBuildInputs = isHaskellPartition.wrong;
+ isHaskellPartition = stdenv.lib.partition
+ isHaskellPkg
+ (propagatedBuildInputs ++ otherBuildInputs ++ depsBuildBuild ++ nativeBuildInputs);
};
isHaskellLibrary = isLibrary;
@@ -485,10 +537,64 @@ stdenv.mkDerivation ({
# TODO: fetch the self from the fixpoint instead
haddockDir = self: if doHaddock then "${docdir self.doc}/html" else null;
- env = shellFor {
- packages = p: [ drv ];
- inherit shellHook;
- };
+ # Creates a derivation containing all of the necessary dependencies for building the
+ # parent derivation. The attribute set that it takes as input can be viewed as:
+ #
+ # { withHoogle }
+ #
+ # The derivation that it builds contains no outpaths because it is meant for use
+ # as an environment
+ #
+ # # Example use
+ # # Creates a shell with all of the dependencies required to build the "hello" package,
+ # # and with python:
+ #
+ # > nix-shell -E 'with (import <nixpkgs> {}); \
+ # > haskell.packages.ghc865.hello.envFunc { buildInputs = [ python ]; }'
+ envFunc = { withHoogle ? false }:
+ let
+ name = "ghc-shell-for-${drv.name}";
+
+ withPackages = if withHoogle then ghcWithHoogle else ghcWithPackages;
+
+ # We use the `ghcWithPackages` function from `buildHaskellPackages` if we
+ # want a shell for the sake of cross compiling a package. In the native case
+ # we don't use this at all, and instead put the setupDepends in the main
+ # `ghcWithPackages`. This way we don't have two wrapper scripts called `ghc`
+ # shadowing each other on the PATH.
+ ghcEnvForBuild =
+ assert isCross;
+ buildHaskellPackages.ghcWithPackages (_: setupHaskellDepends);
+
+ ghcEnv = withPackages (_:
+ otherBuildInputsHaskell ++
+ propagatedBuildInputs ++
+ stdenv.lib.optionals (!isCross) setupHaskellDepends);
+
+ ghcCommandCaps = stdenv.lib.toUpper ghcCommand';
+ in stdenv.mkDerivation ({
+ inherit name shellHook;
+
+ depsBuildBuild = stdenv.lib.optional isCross ghcEnvForBuild;
+ nativeBuildInputs =
+ [ ghcEnv ] ++ optional (allPkgconfigDepends != []) pkgconfig ++
+ collectedToolDepends;
+ buildInputs =
+ otherBuildInputsSystem;
+ phases = ["installPhase"];
+ installPhase = "echo $nativeBuildInputs $buildInputs > $out";
+ LANG = "en_US.UTF-8";
+ LOCALE_ARCHIVE = stdenv.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}";
+ });
+
+ env = envFunc { };
};
diff --git a/pkgs/development/haskell-modules/make-package-set.nix b/pkgs/development/haskell-modules/make-package-set.nix
index e2d01c5798f9..9ba25e09db93 100644
--- a/pkgs/development/haskell-modules/make-package-set.nix
+++ b/pkgs/development/haskell-modules/make-package-set.nix
@@ -38,12 +38,12 @@ let
inherit (stdenv) buildPlatform hostPlatform;
inherit (stdenv.lib) fix' extends makeOverridable;
- inherit (haskellLib) overrideCabal getBuildInputs;
+ inherit (haskellLib) overrideCabal;
mkDerivationImpl = pkgs.callPackage ./generic-builder.nix {
inherit stdenv;
nodejs = buildPackages.nodejs-slim;
- inherit (self) buildHaskellPackages ghc shellFor;
+ inherit (self) buildHaskellPackages ghc ghcWithHoogle ghcWithPackages;
inherit (self.buildHaskellPackages) jailbreak-cabal;
hscolour = overrideCabal self.buildHaskellPackages.hscolour (drv: {
isLibrary = false;
@@ -258,6 +258,8 @@ in package-set { inherit pkgs stdenv callPackage; } self // {
# packages themselves. Using nix-shell on this derivation will
# give you an environment suitable for developing the listed
# packages with an incremental tool like cabal-install.
+ # In addition to the "packages" arg and "withHoogle" arg, anything that
+ # can be passed into stdenv.mkDerivation can be included in the input attrset
#
# # default.nix
# with import <nixpkgs> {};
@@ -268,9 +270,11 @@ in package-set { inherit pkgs stdenv callPackage; } self // {
# })
#
# # shell.nix
+ # let pkgs = import <nixpkgs> {} in
# (import ./.).shellFor {
# packages = p: [p.frontend p.backend p.common];
# withHoogle = true;
+ # buildInputs = [ pkgs.python ];
# }
#
# -- cabal.project
@@ -280,49 +284,41 @@ in package-set { inherit pkgs stdenv callPackage; } self // {
# common/
#
# bash$ nix-shell --run "cabal new-build all"
+ # bash$ nix-shell --run "python"
shellFor = { packages, withHoogle ? false, ... } @ args:
let
- selected = packages self;
-
- 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 = 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}";
+ combinedPackageFor = packages:
+ let
+ selected = packages self;
+
+ pname = if pkgs.lib.length selected == 1
+ then (pkgs.lib.head selected).name
+ else "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.
+ combinedPackages = pkgs.lib.filter
+ (input: pkgs.lib.all (p: input.outPath or null != p.outPath) selected);
+
+ # Returns an attrset containing a combined list packages' inputs for each
+ # stage of the build process
+ packageInputs = pkgs.lib.zipAttrsWith
+ (_: pkgs.lib.concatMap combinedPackages)
+ (map (p: p.getCabalDeps) selected);
+
+ genericBuilderArgs = {
+ inherit pname;
+ version = "0";
+ license = null;
+ } // packageInputs;
+
+ in self.mkDerivation genericBuilderArgs;
+
+ envFuncArgs = builtins.removeAttrs args [ "packages" ];
+ in (combinedPackageFor packages).env.overrideAttrs (old: envFuncArgs // {
+ nativeBuildInputs = old.nativeBuildInputs ++ envFuncArgs.nativeBuildInputs or [];
+ buildInputs = old.buildInputs ++ envFuncArgs.buildInputs or [];
});
ghc = ghc // {
diff --git a/pkgs/test/default.nix b/pkgs/test/default.nix
index eb0711b88857..f62d208d22da 100644
--- a/pkgs/test/default.nix
+++ b/pkgs/test/default.nix
@@ -26,6 +26,8 @@ with pkgs;
cc-wrapper-libcxx-9 = callPackage ./cc-wrapper { stdenv = llvmPackages_9.libcxxStdenv; };
stdenv-inputs = callPackage ./stdenv-inputs { };
+ haskell-shellFor = callPackage ./haskell-shellFor { };
+
cc-multilib-gcc = callPackage ./cc-wrapper/multilib.nix { stdenv = gccMultiStdenv; };
cc-multilib-clang = callPackage ./cc-wrapper/multilib.nix { stdenv = clangMultiStdenv; };
diff --git a/pkgs/test/haskell-shellFor/default.nix b/pkgs/test/haskell-shellFor/default.nix
new file mode 100644
index 000000000000..1b3de999d228
--- /dev/null
+++ b/pkgs/test/haskell-shellFor/default.nix
@@ -0,0 +1,24 @@
+{ stdenv, haskellPackages, cabal-install }:
+
+haskellPackages.shellFor {
+ packages = p: [ p.database-id-class p.constraints-extras ];
+ nativeBuildInputs = [ cabal-install ];
+ phases = [ "unpackPhase" "buildPhase" "installPhase" ];
+ unpackPhase = ''
+ sourceRoot=$(pwd)/scratch
+ mkdir -p "$sourceRoot"
+ cd "$sourceRoot"
+ tar -xf ${haskellPackages.database-id-class.src}
+ tar -xf ${haskellPackages.constraints-extras.src}
+ cp ${builtins.toFile "cabal.project" "packages: database-id-class* constraints-extras*"} cabal.project
+ '';
+ buildPhase = ''
+ export HOME=$(mktemp -d)
+ mkdir -p $HOME/.cabal
+ touch $HOME/.cabal/config
+ cabal v2-build --offline --verbose database-id-class constraints-extras --ghc-options="-O0 -j$NIX_BUILD_CORES"
+ '';
+ installPhase = ''
+ touch $out
+ '';
+}
diff --git a/pkgs/top-level/release.nix b/pkgs/top-level/release.nix
index e39b40be662d..6ada2ca6d184 100644
--- a/pkgs/top-level/release.nix
+++ b/pkgs/top-level/release.nix
@@ -191,6 +191,8 @@ let
haskellPackages = packagePlatforms pkgs.haskellPackages;
idrisPackages = packagePlatforms pkgs.idrisPackages;
+ tests = packagePlatforms pkgs.tests;
+
# Language packages disabled in https://github.com/NixOS/nixpkgs/commit/ccd1029f58a3bb9eca32d81bf3f33cb4be25cc66
#emacsPackages = packagePlatforms pkgs.emacsPackages;