Something went wrong. Try again.
What happens if I push all of nixpkgs
Something went wrong. Try again.
42 kB · 1097 lines
Nix
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098{ lib, stdenv, buildPackages, buildHaskellPackages, ghc, jailbreak-cabal, hscolour, cpphs, runCommandCC, ghcWithHoogle, ghcWithPackages, nodejs, devShellTools,}:
let isCross = stdenv.buildPlatform != stdenv.hostPlatform;
# Note that ghc.isGhcjs != stdenv.hostPlatform.isGhcjs. # ghc.isGhcjs implies that we are using ghcjs, a project separate from GHC. # (mere) stdenv.hostPlatform.isGhcjs means that we are using GHC's JavaScript # backend. The latter is a normal cross compilation backend and needs little # special accommodation. outputsJS = ghc.isGhcjs or false || stdenv.hostPlatform.isGhcjs;
# Pass the "wrong" C compiler rather than none at all so packages that just # use the C preproccessor still work, see # https://github.com/haskell/cabal/issues/6466 for details. cc = if stdenv.hasCC then "$CC" else if stdenv.hostPlatform.isGhcjs then "${emscripten}/bin/emcc" else "$CC_FOR_BUILD";
inherit (buildPackages) fetchurl removeReferencesTo pkg-config coreutils glibcLocales emscripten ;
in
{ pname, dontStrip ? outputsJS, version, revision ? null, sha256 ? null, src ? fetchurl { url = "mirror://hackage/${pname}-${version}.tar.gz"; inherit sha256; }, sourceRoot ? null, setSourceRoot ? null, # Extra environment variables to set during the build. # See: `../../../doc/languages-frameworks/haskell.section.md` env ? { }, buildDepends ? [ ], setupHaskellDepends ? [ ], libraryHaskellDepends ? [ ], executableHaskellDepends ? [ ], buildTarget ? "", buildTools ? [ ], libraryToolDepends ? [ ], executableToolDepends ? [ ], testToolDepends ? [ ], benchmarkToolDepends ? [ ], configureFlags ? [ ], buildFlags ? [ ], haddockFlags ? [ ], description ? null, doCheck ? !isCross, doBenchmark ? false, doHoogle ? true, doHaddockQuickjump ? doHoogle, doInstallIntermediates ? false, editedCabalFile ? null, enableLibraryProfiling ? !outputsJS, enableExecutableProfiling ? false, profilingDetail ? "exported-functions", # TODO enable shared libs for cross-compiling enableSharedExecutables ? false, enableSharedLibraries ? !stdenv.hostPlatform.isStatic && (ghc.enableShared or false) && !stdenv.hostPlatform.useAndroidPrebuilt, enableDeadCodeElimination ? (!stdenv.hostPlatform.isDarwin), # TODO: use -dead_strip for darwin # Disabling this for ghcjs prevents this crash: https://gitlab.haskell.org/ghc/ghc/-/issues/23235 enableStaticLibraries ? !(stdenv.hostPlatform.isWindows || stdenv.hostPlatform.isWasm || stdenv.hostPlatform.isGhcjs), enableHsc2hsViaAsm ? stdenv.hostPlatform.isWindows, extraLibraries ? [ ], librarySystemDepends ? [ ], executableSystemDepends ? [ ], # On macOS, statically linking against system frameworks is not supported; # see https://developer.apple.com/library/content/qa/qa1118/_index.html # They must be propagated to the environment of any executable linking with the library libraryFrameworkDepends ? [ ], executableFrameworkDepends ? [ ], homepage ? "https://hackage.haskell.org/package/${pname}", platforms ? with lib.platforms; all, # GHC can cross-compile badPlatforms ? lib.platforms.none, hydraPlatforms ? null, hyperlinkSource ? true, isExecutable ? false, isLibrary ? !isExecutable, jailbreak ? false, license, enableParallelBuilding ? true, maintainers ? null, teams ? null, changelog ? null, mainProgram ? null, doCoverage ? false, doHaddock ? !(ghc.isHaLVM or false) && (ghc.hasHaddock or true), doHaddockInterfaces ? doHaddock && lib.versionAtLeast ghc.version "9.0.1", passthru ? { }, pkg-configDepends ? [ ], libraryPkgconfigDepends ? [ ], executablePkgconfigDepends ? [ ], testPkgconfigDepends ? [ ], benchmarkPkgconfigDepends ? [ ], testDepends ? [ ], testHaskellDepends ? [ ], testSystemDepends ? [ ], testFrameworkDepends ? [ ], benchmarkDepends ? [ ], benchmarkHaskellDepends ? [ ], benchmarkSystemDepends ? [ ], benchmarkFrameworkDepends ? [ ], # testTarget is deprecated. Use testTargets instead. testTarget ? "", testTargets ? lib.strings.splitString " " testTarget, testFlags ? [ ], broken ? false, preCompileBuildDriver ? null, postCompileBuildDriver ? null, preUnpack ? null, postUnpack ? null, patches ? null, patchPhase ? null, prePatch ? "", postPatch ? "", preConfigure ? null, postConfigure ? null, preBuild ? null, postBuild ? null, preHaddock ? null, postHaddock ? null, installPhase ? null, preInstall ? null, postInstall ? null, checkPhase ? null, preCheck ? null, postCheck ? null, preFixup ? null, postFixup ? null, shellHook ? "", coreSetup ? false, # Use only core packages to build Setup.hs. useCpphs ? false, hardeningDisable ? null, enableSeparateBinOutput ? false, enableSeparateDataOutput ? false, enableSeparateDocOutput ? doHaddock, enableSeparateIntermediatesOutput ? false, # Don't fail at configure time if there are multiple versions of the # same package in the (recursive) dependencies of the package being # built. Will delay failures, if any, to compile time. allowInconsistentDependencies ? false, maxBuildCores ? 16, # more cores usually don't improve performance: https://ghc.haskell.org/trac/ghc/ticket/9221 # If set to true, this builds a pre-linked .o file for this Haskell library. # This can make it slightly faster to load this library into GHCi, but takes # extra disk space and compile time. enableLibraryForGhci ? false, # Set this to a previous build of this same package to reuse the intermediate # build products from that prior build as a starting point for accelerating # this build previousIntermediates ? null, # References to these store paths are forbidden in the produced output. disallowedRequisites ? [ ], # Whether to allow the produced output to refer to `ghc`. # # This is used by `haskell.lib.justStaticExecutables` to help prevent static # Haskell binaries from having erroneous dependencies on GHC. # # See https://nixos.org/manual/nixpkgs/unstable/#haskell-packaging-helpers # or its source doc/languages-frameworks/haskell.section.md disallowGhcReference ? false, # Cabal 3.8 which is shipped by default for GHC >= 9.3 always calls # `pkg-config --libs --static` as part of the configure step. This requires # Requires.private dependencies of pkg-config dependencies to be present in # PKG_CONFIG_PATH which is normally not the case in nixpkgs (except in pkgsStatic). # Since there is no patch or upstream patch yet, we replicate the automatic # propagation of dependencies in pkgsStatic for allPkgConfigDepends for # GHC >= 9.3 by default. This option allows overriding this behavior manually # if mismatching Cabal and GHC versions are used. # See also <https://github.com/haskell/cabal/issues/8455>. __propagatePkgConfigDepends ? lib.versionAtLeast ghc.version "9.3", # Propagation can easily lead to the argv limit being exceeded in linker or C # compiler invocations. To work around this we can only propagate derivations # that are known to provide pkg-config modules, as indicated by the presence # of `meta.pkgConfigModules`. This option defaults to false for now, since # this metadata is far from complete in nixpkgs. __onlyPropagateKnownPkgConfigModules ? false,}@args:
assert editedCabalFile != null -> revision != null;
# --enable-static does not work on windows. This is a bug in GHC.# --enable-static will pass -staticlib to ghc, which only works for mach-o and elf.assert stdenv.hostPlatform.isWindows -> enableStaticLibraries == false;assert stdenv.hostPlatform.isWasm -> enableStaticLibraries == false;
let
inherit (lib) optional optionals optionalString versionAtLeast concatStringsSep enableFeature optionalAttrs ;
isGhcjs = ghc.isGhcjs or false; isHaLVM = ghc.isHaLVM or false;
# GHC used for building Setup.hs # # Same as our GHC, unless we're cross, in which case it is native GHC with the # same version, or ghcjs, in which case its the ghc used to build ghcjs. nativeGhc = buildHaskellPackages.ghc;
# the target dir for haddock documentation docdir = docoutput: docoutput + "/share/doc/" + pname + "-" + version;
binDir = if enableSeparateBinOutput then "$bin/bin" else "$out/bin";
newCabalFileUrl = "mirror://hackage/${pname}-${version}/revision/${revision}.cabal"; newCabalFile = fetchurl { url = newCabalFileUrl; sha256 = editedCabalFile; name = "${pname}-${version}-r${revision}.cabal"; };
defaultSetupHs = builtins.toFile "Setup.hs" '' import Distribution.Simple main = defaultMain '';
# This awk expression transforms a package conf file like # # author: John Doe <john-doe@example.com> # description: # The purpose of this library is to do # foo and bar among other things # # into a more easily processeable form: # # author: John Doe <john-doe@example.com> # description: The purpose of this library is to do foo and bar among other things unprettyConf = builtins.toFile "unpretty-cabal-conf.awk" '' /^[^ ]+:/ { # When the line starts with a new field, terminate the previous one with a newline if (started == 1) print "" # to strip leading spaces $1=$1 printf "%s", $0 started=1 }
/^ +/ { # to strip leading spaces $1=$1 printf " %s", $0 }
# Terminate the final field with a newline END { print "" } '';
crossCabalFlags = [ "--with-ghc=${ghcCommand}" "--with-ghc-pkg=${ghc.targetPrefix}ghc-pkg" "--with-gcc=${cc}" ] ++ optionals stdenv.hasCC [ "--with-ld=${stdenv.cc.bintools.targetPrefix}ld" "--with-ar=${stdenv.cc.bintools.targetPrefix}ar" # use the one that comes with the cross compiler. "--with-hsc2hs=${ghc.targetPrefix}hsc2hs" "--with-strip=${stdenv.cc.bintools.targetPrefix}strip" ] ++ optionals (!isHaLVM) [ "--hsc2hs-option=--cross-compile" (optionalString enableHsc2hsViaAsm "--hsc2hs-option=--via-asm") ] ++ optional (allPkgconfigDepends != [ ]) "--with-pkg-config=${pkg-config.targetPrefix}pkg-config";
makeGhcOptions = opts: lib.concatStringsSep " " (map (opt: "--ghc-option=${opt}") opts);
buildFlagsString = optionalString (buildFlags != [ ]) (" " + concatStringsSep " " buildFlags);
defaultConfigureFlags = [ "--verbose" "--prefix=$out" # Note: This must be kept in sync manually with mkGhcLibdir ("--libdir=\\$prefix/lib/\\$compiler" + lib.optionalString (ghc ? hadrian) "/lib") "--libsubdir=\\$abi/\\$libname" (optionalString enableSeparateDataOutput "--datadir=$data/share/${ghcNameWithPrefix}") (optionalString enableSeparateDocOutput "--docdir=${docdir "$doc"}") ] ++ optionals stdenv.hasCC [ "--with-gcc=$CC" # Clang won't work without that extra information. ] ++ [ "--package-db=$packageConfDir" (optionalString ( enableSharedExecutables && stdenv.hostPlatform.isLinux ) "--ghc-option=-optl=-Wl,-rpath=$out/${ghcLibdir}/${pname}-${version}") (optionalString ( enableSharedExecutables && stdenv.hostPlatform.isDarwin ) "--ghc-option=-optl=-Wl,-headerpad_max_install_names") (optionalString enableParallelBuilding (makeGhcOptions [ "-j$NIX_BUILD_CORES" "+RTS" "-A64M" "-RTS" ])) (optionalString useCpphs ( "--with-cpphs=${cpphs}/bin/cpphs " + (makeGhcOptions [ "-cpp" "-pgmP${cpphs}/bin/cpphs" "-optP--cpp" ]) )) (enableFeature enableLibraryProfiling "library-profiling") (optionalString ( enableExecutableProfiling || enableLibraryProfiling ) "--profiling-detail=${profilingDetail}") (enableFeature enableExecutableProfiling "profiling") (enableFeature enableSharedLibraries "shared") (enableFeature doCoverage "coverage") (enableFeature enableStaticLibraries "static") (enableFeature enableSharedExecutables "executable-dynamic") (enableFeature doCheck "tests") (enableFeature doBenchmark "benchmarks") "--enable-library-vanilla" # TODO: Should this be configurable? (enableFeature enableLibraryForGhci "library-for-ghci") (enableFeature enableDeadCodeElimination "split-sections") (enableFeature (!dontStrip) "library-stripping") (enableFeature (!dontStrip) "executable-stripping") ] ++ optionals isGhcjs [ "--ghcjs" ] ++ optionals isCross ( [ "--configure-option=--host=${stdenv.hostPlatform.config}" ] ++ crossCabalFlags ) ++ optionals enableSeparateBinOutput [ "--bindir=${binDir}" ] ++ optionals (doHaddockInterfaces && isLibrary) [ "--ghc-option=-haddock" ];
postPhases = optional doInstallIntermediates "installIntermediatesPhase";
setupCompileFlags = [ (optionalString (!coreSetup) "-package-db=$setupPackageConfDir") "-threaded" # https://github.com/haskell/cabal/issues/2398 ];
isHaskellPkg = x: x ? isHaskellLibrary;
# Work around a Cabal bug requiring pkg-config --static --libs to work even # when linking dynamically, affecting Cabal 3.8 and 3.9. # https://github.com/haskell/cabal/issues/8455 # # For this, we treat the runtime system/pkg-config dependencies of a Haskell # derivation as if they were propagated from their dependencies which allows # pkg-config --static to work in most cases. allPkgconfigDepends = let # If __onlyPropagateKnownPkgConfigModules is set, packages without # meta.pkgConfigModules will be filtered out, otherwise all packages in # buildInputs and propagatePlainBuildInputs are propagated. propagateValue = drv: lib.isDerivation drv && (__onlyPropagateKnownPkgConfigModules -> drv ? meta.pkgConfigModules);
# Take list of derivations and return list of the transitive dependency # closure, only taking into account buildInputs. Loosely based on # closePropagationFast. propagatePlainBuildInputs = drvs: builtins.map (i: i.val) ( builtins.genericClosure { startSet = builtins.map (drv: { key = drv.outPath; val = drv; }) (builtins.filter propagateValue drvs); operator = { val, ... }: builtins.concatMap ( drv: if propagateValue drv then [ { key = drv.outPath; val = drv; } ] else [ ] ) (val.buildInputs or [ ] ++ val.propagatedBuildInputs or [ ]); } ); in
if __propagatePkgConfigDepends then propagatePlainBuildInputs allPkgconfigDepends' else allPkgconfigDepends'; allPkgconfigDepends' = pkg-configDepends ++ libraryPkgconfigDepends ++ executablePkgconfigDepends ++ optionals doCheck testPkgconfigDepends ++ optionals doBenchmark benchmarkPkgconfigDepends;
depsBuildBuild = [ nativeGhc ] # CC_FOR_BUILD may be necessary if we have no C preprocessor for the host # platform. See crossCabalFlags above for more details. ++ lib.optionals (!stdenv.hasCC) [ buildPackages.stdenv.cc ]; collectedToolDepends = buildTools ++ libraryToolDepends ++ executableToolDepends ++ optionals doCheck testToolDepends ++ optionals doBenchmark benchmarkToolDepends; nativeBuildInputs = [ ghc removeReferencesTo ] ++ optional (allPkgconfigDepends != [ ]) ( assert pkg-config != null; pkg-config ) ++ setupHaskellDepends ++ collectedToolDepends ++ optional stdenv.hostPlatform.isGhcjs nodejs; propagatedBuildInputs = buildDepends ++ libraryHaskellDepends ++ executableHaskellDepends ++ libraryFrameworkDepends; 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";
ghcCommand' = if isGhcjs then "ghcjs" else "ghc"; ghcCommand = "${ghc.targetPrefix}${ghcCommand'}";
ghcNameWithPrefix = "${ghc.targetPrefix}${ghc.haskellCompilerName}"; mkGhcLibdir = ghc: "lib/${ghc.targetPrefix}${ghc.haskellCompilerName}" + lib.optionalString (ghc ? hadrian) "/lib"; ghcLibdir = mkGhcLibdir ghc;
nativeGhcCommand = "${nativeGhc.targetPrefix}ghc";
buildPkgDb = thisGhc: packageConfDir: '' # If this dependency has a package database, then copy the contents of it, # unless it is one of our GHCs. These can appear in our dependencies when # we are doing native builds, and they have package databases in them, but # we do not want to copy them over. # # We don't need to, since those packages will be provided by the GHC when # we compile with it, and doing so can result in having multiple copies of # e.g. Cabal in the database with the same name and version, which is # ambiguous. if [ -d "$p/${mkGhcLibdir thisGhc}/package.conf.d" ] && [ "$p" != "${ghc}" ] && [ "$p" != "${nativeGhc}" ]; then cp -f "$p/${mkGhcLibdir thisGhc}/package.conf.d/"*.conf ${packageConfDir}/ continue fi '';
intermediatesDir = "share/haskell/${ghc.version}/${pname}-${version}/dist";
# On old ghcjs, the jsexe directories are the output but on the js backend they seem to be treated as intermediates jsexe = rec { shouldUseNode = isGhcjs; shouldAdd = stdenv.hostPlatform.isGhcjs && isExecutable; shouldCopy = shouldAdd && !doInstallIntermediates; shouldSymlink = shouldAdd && doInstallIntermediates; };
# This is a script suitable for --test-wrapper of Setup.hs' test command # (https://cabal.readthedocs.io/en/3.12/setup-commands.html#cmdoption-runhaskell-Setup.hs-test-test-wrapper). # We use it to set some environment variables that the test suite may need, # e.g. GHC_PACKAGE_PATH to invoke GHC(i) at runtime with build dependencies # available. See the comment accompanying checkPhase below on how to customize # this behavior. We need to use a wrapper script since Cabal forbids setting # certain environment variables since they can alter GHC's behavior (e.g. # GHC_PACKAGE_PATH) and cause failures. While building, Cabal will set # GHC_ENVIRONMENT to make the packages picked at configure time available to # GHC, but unfortunately not at test time. The test wrapper script will be # executed after such environment checks, so we can take some liberties which # is unproblematic since we know our synthetic package db matches what Cabal # will see at configure time exactly. See also # <https://github.com/haskell/cabal/issues/7792>. testWrapperScript = buildPackages.writeShellScript "haskell-generic-builder-test-wrapper.sh" '' set -eu
# We expect this to be either empty or set by checkPhase if [[ -n "''${NIX_GHC_PACKAGE_PATH_FOR_TEST}" ]]; then export GHC_PACKAGE_PATH="''${NIX_GHC_PACKAGE_PATH_FOR_TEST}" fi
exec "$@" '';
testTargetsString = lib.warnIf (testTarget != "") "haskellPackages.mkDerivation: testTarget is deprecated. Use testTargets instead" (lib.concatStringsSep " " testTargets);
env' = { LANG = "en_US.UTF-8"; # GHC needs the locale configured during the Haddock phase. } // env # Implicit pointer to integer conversions are errors by default since clang 15. # Works around https://gitlab.haskell.org/ghc/ghc/-/issues/23456. // optionalAttrs (stdenv.hasCC && stdenv.cc.isClang) { NIX_CFLAGS_COMPILE = "-Wno-error=int-conversion" + lib.optionalString (env ? NIX_CFLAGS_COMPILE) (" " + env.NIX_CFLAGS_COMPILE); };
inlib.fix ( drv:
stdenv.mkDerivation ( { inherit pname version;
outputs = [ "out" ] ++ (optional enableSeparateDataOutput "data") ++ (optional enableSeparateDocOutput "doc") ++ (optional enableSeparateBinOutput "bin") ++ (optional enableSeparateIntermediatesOutput "intermediates");
setOutputFlags = false;
pos = builtins.unsafeGetAttrPos "pname" args;
prePhases = [ "setupCompilerEnvironmentPhase" ]; preConfigurePhases = [ "compileBuildDriverPhase" ]; preInstallPhases = [ "haddockPhase" ];
inherit src;
inherit depsBuildBuild nativeBuildInputs; buildInputs = otherBuildInputs ++ optionals (!isLibrary) propagatedBuildInputs # For patchShebangsAuto in fixupPhase ++ optionals stdenv.hostPlatform.isGhcjs [ nodejs ]; propagatedBuildInputs = optionals isLibrary propagatedBuildInputs;
env = optionalAttrs (stdenv.buildPlatform.libc == "glibc") { LOCALE_ARCHIVE = "${glibcLocales}/lib/locale/locale-archive"; } // env';
prePatch = optionalString (editedCabalFile != null) '' echo "Replace Cabal file with edited version from ${newCabalFileUrl}." cp ${newCabalFile} ${pname}.cabal '' + prePatch;
postPatch = optionalString jailbreak '' echo "Run jailbreak-cabal to lift version restrictions on build inputs." ${jailbreak-cabal}/bin/jailbreak-cabal ${pname}.cabal '' + postPatch;
setupCompilerEnvironmentPhase = '' NIX_BUILD_CORES=$(( NIX_BUILD_CORES < ${toString maxBuildCores} ? NIX_BUILD_CORES : ${toString maxBuildCores} )) runHook preSetupCompilerEnvironment
echo "Build with ${ghc}." ${optionalString (isLibrary && hyperlinkSource) "export PATH=${hscolour}/bin:$PATH"}
builddir="$(mktemp -d)" setupPackageConfDir="$builddir/setup-package.conf.d" mkdir -p $setupPackageConfDir packageConfDir="$builddir/package.conf.d" mkdir -p $packageConfDir
setupCompileFlags="${concatStringsSep " " setupCompileFlags}" configureFlags="${concatStringsSep " " defaultConfigureFlags} $configureFlags" '' # We build the Setup.hs on the *build* machine, and as such should only add # dependencies for the build machine. # # pkgs* arrays defined in stdenv/setup.hs + '' for p in "''${pkgsBuildBuild[@]}" "''${pkgsBuildHost[@]}" "''${pkgsBuildTarget[@]}"; do ${buildPkgDb nativeGhc "$setupPackageConfDir"} done ${nativeGhcCommand}-pkg --package-db="$setupPackageConfDir" recache '' # For normal components + '' for p in "''${pkgsHostHost[@]}" "''${pkgsHostTarget[@]}"; do ${buildPkgDb ghc "$packageConfDir"} if [ -d "$p/include" ]; then appendToVar configureFlags "--extra-include-dirs=$p/include" fi if [ -d "$p/lib" ]; then appendToVar configureFlags "--extra-lib-dirs=$p/lib" fi if [[ -d "$p/Library/Frameworks" ]]; then appendToVar configureFlags "--extra-framework-dirs=$p/Library/Frameworks" fi '' + '' done '' + (optionalString stdenv.hostPlatform.isGhcjs '' export EM_CACHE="$(realpath "$(mktemp -d emcache.XXXXXXXXXX)")" cp -Lr ${emscripten}/share/emscripten/cache/* "$EM_CACHE/" chmod u+rwX -R "$EM_CACHE" '') # only use the links hack if we're actually building dylibs. otherwise, the # "dynamic-library-dirs" point to nonexistent paths, and the ln command becomes # "ln -s $out/lib/links", which tries to recreate the links dir and fails # # Note: We need to disable this work-around when using intermediate build # products from a prior build because otherwise Nix will change permissions on # the `$out/lib/links` directory to read-only when the build is done after the # dist directory has already been exported, which triggers an unnecessary # rebuild of modules included in the exported dist directory. + (optionalString ( stdenv.hostPlatform.isDarwin && (enableSharedLibraries || enableSharedExecutables) && !enableSeparateIntermediatesOutput ) '' # Work around a limit in the macOS Sierra linker on the number of paths # referenced by any one dynamic library: # # Create a local directory with symlinks of the *.dylib (macOS shared # libraries) from all the dependencies. local dynamicLinksDir="$out/lib/links" mkdir -p $dynamicLinksDir
# Unprettify all package conf files before reading/writing them for d in "$packageConfDir/"*; do # gawk -i inplace seems to strip the last newline gawk -f ${unprettyConf} "$d" > tmp mv tmp "$d" done
for d in $(grep '^dynamic-library-dirs:' "$packageConfDir"/* | cut -d' ' -f2- | tr ' ' '\n' | sort -u); do for lib in "$d/"*.{dylib,so}; do # Allow overwriting because C libs can be pulled in multiple times. ln -sf "$lib" "$dynamicLinksDir" done done # Edit the local package DB to reference the links directory. for f in "$packageConfDir/"*.conf; do sed -i "s,dynamic-library-dirs: .*,dynamic-library-dirs: $dynamicLinksDir," "$f" done '' ) + '' ${ghcCommand}-pkg --package-db="$packageConfDir" recache
runHook postSetupCompilerEnvironment '';
compileBuildDriverPhase = '' runHook preCompileBuildDriver
for i in Setup.hs Setup.lhs ${defaultSetupHs}; do test -f $i && break done
echo setupCompileFlags: $setupCompileFlags ${nativeGhcCommand} $setupCompileFlags --make -o Setup -odir $builddir -hidir $builddir $i
runHook postCompileBuildDriver '';
# Cabal takes flags like `--configure-option=--host=...` instead configurePlatforms = [ ]; inherit configureFlags;
# Note: the options here must be always added, regardless of whether the # package specifies `hardeningDisable`. hardeningDisable = lib.optionals (args ? hardeningDisable) hardeningDisable ++ lib.optional (ghc.isHaLVM or false) "all" # Static libraries (ie. all of pkgsStatic.haskellPackages) fail to build # because by default Nix adds `-pie` to the linker flags: this # conflicts with the `-r` and `-no-pie` flags added by GHC (see # https://gitlab.haskell.org/ghc/ghc/-/issues/19580). hardeningDisable # changes the default Nix behavior regarding adding "hardening" flags. ++ lib.optional enableStaticLibraries "pie";
configurePhase = '' runHook preConfigure
echo configureFlags: $configureFlags ${setupCommand} configure $configureFlags 2>&1 | ${coreutils}/bin/tee "$NIX_BUILD_TOP/cabal-configure.log" ${lib.optionalString (!allowInconsistentDependencies) '' if grep -E -q -z 'Warning:.*depends on multiple versions' "$NIX_BUILD_TOP/cabal-configure.log"; then echo >&2 "*** abort because of serious configure-time warning from Cabal" exit 1 fi ''}
runHook postConfigure '';
buildPhase = '' runHook preBuild '' + lib.optionalString (previousIntermediates != null) '' mkdir -p dist; rm -r dist/build cp -r ${previousIntermediates}/${intermediatesDir}/build dist/build find dist/build -exec chmod u+w {} + find dist/build -exec touch -d '1970-01-01T00:00:00Z' {} + '' + '' ${setupCommand} build ${buildTarget}${buildFlagsString} runHook postBuild '';
inherit doCheck;
# Run test suite(s) and pass `checkFlags` as well as `checkFlagsArray`. # `testFlags` are added to `checkFlagsArray` each prefixed with # `--test-option`, so Cabal passes it to the underlying test suite binary. # # We also take care of setting GHC_PACKAGE_PATH during test suite execution, # so it can run GHC(i) with build dependencies available: # - If NIX_GHC_PACKAGE_PATH_FOR_TEST is set, it become the value of GHC_PACKAGE_PATH # while the test suite is executed. # - If it is empty, it'll be unset during test suite execution. # - Otherwise GHC_PACKAGE_PATH will have the package db used for configuring # plus GHC's core packages. checkPhase = '' runHook preCheck checkFlagsArray+=( "--show-details=streaming" "--test-wrapper=${testWrapperScript}" ${lib.escapeShellArgs (builtins.map (opt: "--test-option=${opt}") testFlags)} ) export NIX_GHC_PACKAGE_PATH_FOR_TEST="''${NIX_GHC_PACKAGE_PATH_FOR_TEST:-$packageConfDir:}" ${setupCommand} test ${testTargetsString} $checkFlags ''${checkFlagsArray:+"''${checkFlagsArray[@]}"} runHook postCheck '';
haddockPhase = '' runHook preHaddock ${optionalString (doHaddock && isLibrary) '' ${setupCommand} haddock --html \ ${optionalString doHoogle "--hoogle"} \ ${optionalString doHaddockQuickjump "--quickjump"} \ ${optionalString (isLibrary && hyperlinkSource) "--hyperlink-source"} \ ${lib.concatStringsSep " " haddockFlags} ''} runHook postHaddock '';
installPhase = '' runHook preInstall
${ if !isLibrary && buildTarget == "" then "${setupCommand} install" # ^^ if the project is not a library, and no build target is specified, we can just use "install". else if !isLibrary then "${setupCommand} copy ${buildTarget}" # ^^ if the project is not a library, and we have a build target, then use "copy" to install # just the target specified; "install" will error here, since not all targets have been built. else '' ${setupCommand} copy ${buildTarget} local packageConfDir="$out/${ghcLibdir}/package.conf.d" local packageConfFile="$packageConfDir/${pname}-${version}.conf" mkdir -p "$packageConfDir" ${setupCommand} register --gen-pkg-config=$packageConfFile if [ -d "$packageConfFile" ]; then mv "$packageConfFile/"* "$packageConfDir" rmdir "$packageConfFile" fi for packageConfFile in "$packageConfDir/"*; do local pkgId=$(gawk -f ${unprettyConf} "$packageConfFile" \ | grep '^id:' | cut -d' ' -f2) mv "$packageConfFile" "$packageConfDir/$pkgId.conf" done
# delete confdir if there are no libraries find $packageConfDir -maxdepth 0 -empty -delete; '' }
${optionalString jsexe.shouldUseNode '' for exeDir in "${binDir}/"*.jsexe; do exe="''${exeDir%.jsexe}" printWords '#!${nodejs}/bin/node' > "$exe" echo >> "$exe" cat "$exeDir/all.js" >> "$exe" chmod +x "$exe" done ''} ${optionalString doCoverage "mkdir -p $out/share && cp -r dist/hpc $out/share"}
${optionalString jsexe.shouldCopy '' for jsexeDir in dist/build/*/*.jsexe; do bn=$(basename $jsexeDir) exe="''${bn%.jsexe}" cp -r dist/build/$exe/$exe.jsexe ${binDir} done ''}
${optionalString enableSeparateDocOutput '' for x in ${docdir "$doc"}"/html/src/"*.html; do remove-references-to -t $out $x done mkdir -p $doc ''} ${optionalString enableSeparateDataOutput "mkdir -p $data"}
runHook postInstall '';
${if doInstallIntermediates then "installIntermediatesPhase" else null} = '' runHook preInstallIntermediates intermediatesOutput=${if enableSeparateIntermediatesOutput then "$intermediates" else "$out"} installIntermediatesDir="$intermediatesOutput/${intermediatesDir}" mkdir -p "$installIntermediatesDir" cp -r dist/build "$installIntermediatesDir" runHook postInstallIntermediates
${optionalString jsexe.shouldSymlink '' for jsexeDir in $installIntermediatesDir/build/*/*.jsexe; do bn=$(basename $jsexeDir) exe="''${bn%.jsexe}" (cd ${binDir} && ln -s $installIntermediatesDir/build/$exe/$exe.jsexe) done ''} '';
passthru = passthru // rec {
inherit pname version disallowGhcReference;
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 pkg-configDepends setupHaskellDepends ; } // lib.optionalAttrs doCheck { inherit testDepends testFrameworkDepends testHaskellDepends testPkgconfigDepends testSystemDepends testToolDepends ; } // lib.optionalAttrs doBenchmark { inherit benchmarkDepends benchmarkFrameworkDepends benchmarkHaskellDepends benchmarkPkgconfigDepends benchmarkSystemDepends benchmarkToolDepends ; };
# 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 = lib.partition isHaskellPkg ( propagatedBuildInputs ++ otherBuildInputs ++ depsBuildBuild ++ nativeBuildInputs ); };
isHaskellLibrary = isLibrary;
# TODO: ask why the split outputs are configurable at all? # TODO: include tests for split if possible # Given the haskell package, returns # the directory containing the haddock documentation. # `null' if no haddock documentation was built. # TODO: fetch the self from the fixpoint instead haddockDir = self: if doHaddock then "${docdir self.doc}/html" else null;
# 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 ++ lib.optionals (!isCross) setupHaskellDepends );
ghcCommandCaps = lib.toUpper ghcCommand'; in runCommandCC name { inherit shellHook;
depsBuildBuild = lib.optional isCross ghcEnvForBuild; nativeBuildInputs = [ ghcEnv ] ++ optional (allPkgconfigDepends != [ ]) pkg-config ++ collectedToolDepends; buildInputs = otherBuildInputsSystem;
env = { "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}/${ghcLibdir}"; } // optionalAttrs (stdenv.buildPlatform.libc == "glibc") { # TODO: Why is this written in terms of `buildPackages`, unlike # the outer `env`? # # According to @sternenseemann [1]: # # > The condition is based on `buildPlatform`, so it needs to # > match. `LOCALE_ARCHIVE` is set to accompany `LANG` which # > concerns things we execute on the build platform like # > `haddock`. # > # > Arguably the outer non `buildPackages` one is incorrect and # > probably works by accident in most cases since the locale # > archive is not platform specific (the trouble is that it # > may sometimes be impossible to cross-compile). At least # > that would be my assumption. # # [1]: https://github.com/NixOS/nixpkgs/pull/424368#discussion_r2202683378 LOCALE_ARCHIVE = "${buildPackages.glibcLocales}/lib/locale/locale-archive"; } // env'; } "echo $nativeBuildInputs $buildInputs > $out";
# Specialise the devShell attribute, so we get our improved shell. devShell = env.devShell; env = envFunc { };
};
meta = { inherit homepage license platforms; } // optionalAttrs (args ? broken) { inherit broken; } // optionalAttrs (args ? description) { inherit description; } // optionalAttrs (args ? maintainers) { inherit maintainers; } // optionalAttrs (args ? teams) { inherit teams; } // optionalAttrs (args ? hydraPlatforms) { inherit hydraPlatforms; } // optionalAttrs (args ? badPlatforms) { inherit badPlatforms; } // optionalAttrs (args ? changelog) { inherit changelog; } // optionalAttrs (args ? mainProgram) { inherit mainProgram; };
} // optionalAttrs (args ? sourceRoot) { inherit sourceRoot; } // optionalAttrs (args ? setSourceRoot) { inherit setSourceRoot; } // optionalAttrs (args ? preCompileBuildDriver) { inherit preCompileBuildDriver; } // optionalAttrs (args ? postCompileBuildDriver) { inherit postCompileBuildDriver; } // optionalAttrs (args ? preUnpack) { inherit preUnpack; } // optionalAttrs (args ? postUnpack) { inherit postUnpack; } // optionalAttrs (args ? patches) { inherit patches; } // optionalAttrs (args ? patchPhase) { inherit patchPhase; } // optionalAttrs (args ? preConfigure) { inherit preConfigure; } // optionalAttrs (args ? postConfigure) { inherit postConfigure; } // optionalAttrs (args ? preBuild) { inherit preBuild; } // optionalAttrs (args ? postBuild) { inherit postBuild; } // optionalAttrs (args ? doBenchmark) { inherit doBenchmark; } // optionalAttrs (args ? checkPhase) { inherit checkPhase; } // optionalAttrs (args ? preCheck) { inherit preCheck; } // optionalAttrs (args ? postCheck) { inherit postCheck; } // optionalAttrs (args ? preHaddock) { inherit preHaddock; } // optionalAttrs (args ? postHaddock) { inherit postHaddock; } // optionalAttrs (args ? preInstall) { inherit preInstall; } // optionalAttrs (args ? installPhase) { inherit installPhase; } // optionalAttrs (args ? postInstall) { inherit postInstall; } // optionalAttrs (args ? preFixup) { inherit preFixup; } // optionalAttrs (args ? postFixup) { inherit postFixup; } // optionalAttrs (args ? dontStrip) { inherit dontStrip; } // optionalAttrs (postPhases != [ ]) { inherit postPhases; } // optionalAttrs (disallowedRequisites != [ ] || disallowGhcReference) { disallowedRequisites = disallowedRequisites ++ (if disallowGhcReference then [ ghc ] else [ ]); } ))