Clone of https://github.com/NixOS/nixpkgs.git (to stress-test knotserver)
1{ lib, stdenv, buildPackages, buildHaskellPackages, ghc 2, jailbreak-cabal, hscolour, cpphs, nodejs 3, ghcWithHoogle, ghcWithPackages 4}: 5 6let 7 isCross = stdenv.buildPlatform != stdenv.hostPlatform; 8 inherit (buildPackages) 9 fetchurl removeReferencesTo 10 pkg-config coreutils gnugrep gnused glibcLocales; 11in 12 13{ pname 14, dontStrip ? (ghc.isGhcjs or false) 15, version, revision ? null 16, sha256 ? null 17, src ? fetchurl { url = "mirror://hackage/${pname}-${version}.tar.gz"; inherit sha256; } 18, buildDepends ? [], setupHaskellDepends ? [], libraryHaskellDepends ? [], executableHaskellDepends ? [] 19, buildTarget ? "" 20, buildTools ? [], libraryToolDepends ? [], executableToolDepends ? [], testToolDepends ? [], benchmarkToolDepends ? [] 21, configureFlags ? [] 22, buildFlags ? [] 23, haddockFlags ? [] 24, description ? null 25, doCheck ? !isCross && lib.versionOlder "7.4" ghc.version 26, doBenchmark ? false 27, doHoogle ? true 28, doHaddockQuickjump ? doHoogle && lib.versionAtLeast ghc.version "8.6" 29, editedCabalFile ? null 30# aarch64 outputs otherwise exceed 2GB limit 31, enableLibraryProfiling ? !(ghc.isGhcjs or stdenv.targetPlatform.isAarch64 or false) 32, enableExecutableProfiling ? false 33, profilingDetail ? "exported-functions" 34# TODO enable shared libs for cross-compiling 35, enableSharedExecutables ? false 36, enableSharedLibraries ? !stdenv.hostPlatform.isStatic && (ghc.enableShared or false) 37, enableDeadCodeElimination ? (!stdenv.isDarwin) # TODO: use -dead_strip for darwin 38, enableStaticLibraries ? !(stdenv.hostPlatform.isWindows or stdenv.hostPlatform.isWasm) 39, enableHsc2hsViaAsm ? stdenv.hostPlatform.isWindows && lib.versionAtLeast ghc.version "8.4" 40, extraLibraries ? [], librarySystemDepends ? [], executableSystemDepends ? [] 41# On macOS, statically linking against system frameworks is not supported; 42# see https://developer.apple.com/library/content/qa/qa1118/_index.html 43# They must be propagated to the environment of any executable linking with the library 44, libraryFrameworkDepends ? [], executableFrameworkDepends ? [] 45, homepage ? "https://hackage.haskell.org/package/${pname}" 46, platforms ? with lib.platforms; all # GHC can cross-compile 47, badPlatforms ? lib.platforms.none 48, hydraPlatforms ? null 49, hyperlinkSource ? true 50, isExecutable ? false, isLibrary ? !isExecutable 51, jailbreak ? false 52, license 53, enableParallelBuilding ? true 54, maintainers ? null 55, changelog ? null 56, mainProgram ? null 57, doCoverage ? false 58, doHaddock ? !(ghc.isHaLVM or false) && (ghc.hasHaddock or true) 59, doHaddockInterfaces ? doHaddock && lib.versionAtLeast ghc.version "9.0.1" 60, passthru ? {} 61, pkg-configDepends ? [], libraryPkgconfigDepends ? [], executablePkgconfigDepends ? [], testPkgconfigDepends ? [], benchmarkPkgconfigDepends ? [] 62, testDepends ? [], testHaskellDepends ? [], testSystemDepends ? [], testFrameworkDepends ? [] 63, benchmarkDepends ? [], benchmarkHaskellDepends ? [], benchmarkSystemDepends ? [], benchmarkFrameworkDepends ? [] 64, testTarget ? "", testFlags ? [] 65, broken ? false 66, preCompileBuildDriver ? null, postCompileBuildDriver ? null 67, preUnpack ? null, postUnpack ? null 68, patches ? null, patchPhase ? null, prePatch ? "", postPatch ? "" 69, preConfigure ? null, postConfigure ? null 70, preBuild ? null, postBuild ? null 71, preHaddock ? null, postHaddock ? null 72, installPhase ? null, preInstall ? null, postInstall ? null 73, checkPhase ? null, preCheck ? null, postCheck ? null 74, preFixup ? null, postFixup ? null 75, shellHook ? "" 76, coreSetup ? false # Use only core packages to build Setup.hs. 77, useCpphs ? false 78, hardeningDisable ? null 79, enableSeparateBinOutput ? false 80, enableSeparateDataOutput ? false 81, enableSeparateDocOutput ? doHaddock 82, # Don't fail at configure time if there are multiple versions of the 83 # same package in the (recursive) dependencies of the package being 84 # built. Will delay failures, if any, to compile time. 85 allowInconsistentDependencies ? false 86, maxBuildCores ? 16 # more cores usually don't improve performance: https://ghc.haskell.org/trac/ghc/ticket/9221 87, # If set to true, this builds a pre-linked .o file for this Haskell library. 88 # This can make it slightly faster to load this library into GHCi, but takes 89 # extra disk space and compile time. 90 enableLibraryForGhci ? false 91} @ args: 92 93assert editedCabalFile != null -> revision != null; 94 95# --enable-static does not work on windows. This is a bug in GHC. 96# --enable-static will pass -staticlib to ghc, which only works for mach-o and elf. 97assert stdenv.hostPlatform.isWindows -> enableStaticLibraries == false; 98assert stdenv.hostPlatform.isWasm -> enableStaticLibraries == false; 99 100let 101 102 inherit (lib) optional optionals optionalString versionOlder versionAtLeast 103 concatStringsSep enableFeature optionalAttrs; 104 105 isGhcjs = ghc.isGhcjs or false; 106 isHaLVM = ghc.isHaLVM or false; 107 packageDbFlag = if isGhcjs || isHaLVM || versionOlder "7.6" ghc.version 108 then "package-db" 109 else "package-conf"; 110 111 # GHC used for building Setup.hs 112 # 113 # Same as our GHC, unless we're cross, in which case it is native GHC with the 114 # same version, or ghcjs, in which case its the ghc used to build ghcjs. 115 nativeGhc = buildHaskellPackages.ghc; 116 nativePackageDbFlag = if versionOlder "7.6" nativeGhc.version 117 then "package-db" 118 else "package-conf"; 119 120 # the target dir for haddock documentation 121 docdir = docoutput: docoutput + "/share/doc/" + pname + "-" + version; 122 123 binDir = if enableSeparateBinOutput then "$bin/bin" else "$out/bin"; 124 125 newCabalFileUrl = "mirror://hackage/${pname}-${version}/revision/${revision}.cabal"; 126 newCabalFile = fetchurl { 127 url = newCabalFileUrl; 128 sha256 = editedCabalFile; 129 name = "${pname}-${version}-r${revision}.cabal"; 130 }; 131 132 defaultSetupHs = builtins.toFile "Setup.hs" '' 133 import Distribution.Simple 134 main = defaultMain 135 ''; 136 137 # This awk expression transforms a package conf file like 138 # 139 # author: John Doe <john-doe@example.com> 140 # description: 141 # The purpose of this library is to do 142 # foo and bar among other things 143 # 144 # into a more easily processeable form: 145 # 146 # author: John Doe <john-doe@example.com> 147 # description: The purpose of this library is to do foo and bar among other things 148 unprettyConf = builtins.toFile "unpretty-cabal-conf.awk" '' 149 /^[^ ]+:/ { 150 # When the line starts with a new field, terminate the previous one with a newline 151 if (started == 1) print "" 152 # to strip leading spaces 153 $1=$1 154 printf "%s", $0 155 started=1 156 } 157 158 /^ +/ { 159 # to strip leading spaces 160 $1=$1 161 printf " %s", $0 162 } 163 164 # Terminate the final field with a newline 165 END { print "" } 166 ''; 167 168 crossCabalFlags = [ 169 "--with-ghc=${ghcCommand}" 170 "--with-ghc-pkg=${ghc.targetPrefix}ghc-pkg" 171 # Pass the "wrong" C compiler rather than none at all so packages that just 172 # use the C preproccessor still work, see 173 # https://github.com/haskell/cabal/issues/6466 for details. 174 "--with-gcc=${(if stdenv.hasCC then stdenv else buildPackages.stdenv).cc.targetPrefix}cc" 175 ] ++ optionals stdenv.hasCC [ 176 "--with-ld=${stdenv.cc.bintools.targetPrefix}ld" 177 "--with-ar=${stdenv.cc.bintools.targetPrefix}ar" 178 # use the one that comes with the cross compiler. 179 "--with-hsc2hs=${ghc.targetPrefix}hsc2hs" 180 "--with-strip=${stdenv.cc.bintools.targetPrefix}strip" 181 ] ++ optionals (!isHaLVM) [ 182 "--hsc2hs-option=--cross-compile" 183 (optionalString enableHsc2hsViaAsm "--hsc2hs-option=--via-asm") 184 ] ++ optional (allPkgconfigDepends != []) 185 "--with-pkg-config=${pkg-config.targetPrefix}pkg-config"; 186 187 parallelBuildingFlags = "-j$NIX_BUILD_CORES" + optionalString stdenv.isLinux " +RTS -A64M -RTS"; 188 189 crossCabalFlagsString = 190 lib.optionalString isCross (" " + lib.concatStringsSep " " crossCabalFlags); 191 192 buildFlagsString = optionalString (buildFlags != []) (" " + concatStringsSep " " buildFlags); 193 194 defaultConfigureFlags = [ 195 "--verbose" 196 "--prefix=$out" 197 "--libdir=\\$prefix/lib/\\$compiler" 198 "--libsubdir=\\$abi/\\$libname" 199 (optionalString enableSeparateDataOutput "--datadir=$data/share/${ghcNameWithPrefix}") 200 (optionalString enableSeparateDocOutput "--docdir=${docdir "$doc"}") 201 ] ++ optionals stdenv.hasCC [ 202 "--with-gcc=$CC" # Clang won't work without that extra information. 203 ] ++ [ 204 "--package-db=$packageConfDir" 205 (optionalString (enableSharedExecutables && stdenv.isLinux) "--ghc-option=-optl=-Wl,-rpath=$out/lib/${ghcNameWithPrefix}/${pname}-${version}") 206 (optionalString (enableSharedExecutables && stdenv.isDarwin) "--ghc-option=-optl=-Wl,-headerpad_max_install_names") 207 (optionalString enableParallelBuilding "--ghc-options=${parallelBuildingFlags}") 208 (optionalString useCpphs "--with-cpphs=${cpphs}/bin/cpphs --ghc-options=-cpp --ghc-options=-pgmP${cpphs}/bin/cpphs --ghc-options=-optP--cpp") 209 (enableFeature (enableDeadCodeElimination && !stdenv.hostPlatform.isAarch32 && !stdenv.hostPlatform.isAarch64 && (versionAtLeast "8.0.1" ghc.version)) "split-objs") 210 (enableFeature enableLibraryProfiling "library-profiling") 211 (optionalString ((enableExecutableProfiling || enableLibraryProfiling) && versionOlder "8" ghc.version) "--profiling-detail=${profilingDetail}") 212 (enableFeature enableExecutableProfiling (if versionOlder ghc.version "8" then "executable-profiling" else "profiling")) 213 (enableFeature enableSharedLibraries "shared") 214 (optionalString (versionAtLeast ghc.version "7.10") (enableFeature doCoverage "coverage")) 215 (optionalString (versionOlder "8.4" ghc.version) (enableFeature enableStaticLibraries "static")) 216 (optionalString (isGhcjs || versionOlder "7.4" ghc.version) (enableFeature enableSharedExecutables "executable-dynamic")) 217 (optionalString (isGhcjs || versionOlder "7" ghc.version) (enableFeature doCheck "tests")) 218 (enableFeature doBenchmark "benchmarks") 219 "--enable-library-vanilla" # TODO: Should this be configurable? 220 (enableFeature enableLibraryForGhci "library-for-ghci") 221 ] ++ optionals (enableDeadCodeElimination && (lib.versionOlder "8.0.1" ghc.version)) [ 222 "--ghc-option=-split-sections" 223 ] ++ optionals dontStrip [ 224 "--disable-library-stripping" 225 "--disable-executable-stripping" 226 ] ++ optionals isGhcjs [ 227 "--ghcjs" 228 ] ++ optionals isCross ([ 229 "--configure-option=--host=${stdenv.hostPlatform.config}" 230 ] ++ crossCabalFlags 231 ) ++ optionals enableSeparateBinOutput [ 232 "--bindir=${binDir}" 233 ] ++ optionals (doHaddockInterfaces && isLibrary) [ 234 "--ghc-options=-haddock" 235 ]; 236 237 setupCompileFlags = [ 238 (optionalString (!coreSetup) "-${nativePackageDbFlag}=$setupPackageConfDir") 239 (optionalString enableParallelBuilding (parallelBuildingFlags)) 240 "-threaded" # https://github.com/haskell/cabal/issues/2398 241 "-rtsopts" # allow us to pass RTS flags to the generated Setup executable 242 ]; 243 244 isHaskellPkg = x: x ? isHaskellLibrary; 245 246 allPkgconfigDepends = pkg-configDepends ++ libraryPkgconfigDepends ++ executablePkgconfigDepends ++ 247 optionals doCheck testPkgconfigDepends ++ optionals doBenchmark benchmarkPkgconfigDepends; 248 249 depsBuildBuild = [ nativeGhc ]; 250 collectedToolDepends = 251 buildTools ++ libraryToolDepends ++ executableToolDepends ++ 252 optionals doCheck testToolDepends ++ 253 optionals doBenchmark benchmarkToolDepends; 254 nativeBuildInputs = 255 [ ghc removeReferencesTo ] ++ optional (allPkgconfigDepends != []) pkg-config ++ 256 setupHaskellDepends ++ collectedToolDepends; 257 propagatedBuildInputs = buildDepends ++ libraryHaskellDepends ++ executableHaskellDepends ++ libraryFrameworkDepends; 258 otherBuildInputsHaskell = 259 optionals doCheck (testDepends ++ testHaskellDepends) ++ 260 optionals doBenchmark (benchmarkDepends ++ benchmarkHaskellDepends); 261 otherBuildInputsSystem = 262 extraLibraries ++ librarySystemDepends ++ executableSystemDepends ++ executableFrameworkDepends ++ 263 allPkgconfigDepends ++ 264 optionals doCheck (testSystemDepends ++ testFrameworkDepends) ++ 265 optionals doBenchmark (benchmarkSystemDepends ++ benchmarkFrameworkDepends); 266 # TODO next rebuild just define as `otherBuildInputsHaskell ++ otherBuildInputsSystem` 267 otherBuildInputs = 268 extraLibraries ++ librarySystemDepends ++ executableSystemDepends ++ executableFrameworkDepends ++ 269 allPkgconfigDepends ++ 270 optionals doCheck (testDepends ++ testHaskellDepends ++ testSystemDepends ++ testFrameworkDepends) ++ 271 optionals doBenchmark (benchmarkDepends ++ benchmarkHaskellDepends ++ benchmarkSystemDepends ++ benchmarkFrameworkDepends); 272 273 setupCommand = "./Setup"; 274 275 ghcCommand' = if isGhcjs then "ghcjs" else "ghc"; 276 ghcCommand = "${ghc.targetPrefix}${ghcCommand'}"; 277 278 ghcNameWithPrefix = "${ghc.targetPrefix}${ghc.haskellCompilerName}"; 279 280 nativeGhcCommand = "${nativeGhc.targetPrefix}ghc"; 281 282 buildPkgDb = ghcName: packageConfDir: '' 283 # If this dependency has a package database, then copy the contents of it, 284 # unless it is one of our GHCs. These can appear in our dependencies when 285 # we are doing native builds, and they have package databases in them, but 286 # we do not want to copy them over. 287 # 288 # We don't need to, since those packages will be provided by the GHC when 289 # we compile with it, and doing so can result in having multiple copies of 290 # e.g. Cabal in the database with the same name and version, which is 291 # ambiguous. 292 if [ -d "$p/lib/${ghcName}/package.conf.d" ] && [ "$p" != "${ghc}" ] && [ "$p" != "${nativeGhc}" ]; then 293 cp -f "$p/lib/${ghcName}/package.conf.d/"*.conf ${packageConfDir}/ 294 continue 295 fi 296 ''; 297in lib.fix (drv: 298 299assert allPkgconfigDepends != [] -> pkg-config != null; 300 301stdenv.mkDerivation ({ 302 inherit pname version; 303 304 outputs = [ "out" ] 305 ++ (optional enableSeparateDataOutput "data") 306 ++ (optional enableSeparateDocOutput "doc") 307 ++ (optional enableSeparateBinOutput "bin"); 308 setOutputFlags = false; 309 310 pos = builtins.unsafeGetAttrPos "pname" args; 311 312 prePhases = ["setupCompilerEnvironmentPhase"]; 313 preConfigurePhases = ["compileBuildDriverPhase"]; 314 preInstallPhases = ["haddockPhase"]; 315 316 inherit src; 317 318 inherit depsBuildBuild nativeBuildInputs; 319 buildInputs = otherBuildInputs ++ optionals (!isLibrary) propagatedBuildInputs; 320 propagatedBuildInputs = optionals isLibrary propagatedBuildInputs; 321 322 LANG = "en_US.UTF-8"; # GHC needs the locale configured during the Haddock phase. 323 324 prePatch = optionalString (editedCabalFile != null) '' 325 echo "Replace Cabal file with edited version from ${newCabalFileUrl}." 326 cp ${newCabalFile} ${pname}.cabal 327 '' + prePatch; 328 329 postPatch = optionalString jailbreak '' 330 echo "Run jailbreak-cabal to lift version restrictions on build inputs." 331 ${jailbreak-cabal}/bin/jailbreak-cabal ${pname}.cabal 332 '' + postPatch; 333 334 setupCompilerEnvironmentPhase = '' 335 NIX_BUILD_CORES=$(( NIX_BUILD_CORES < ${toString maxBuildCores} ? NIX_BUILD_CORES : ${toString maxBuildCores} )) 336 runHook preSetupCompilerEnvironment 337 338 echo "Build with ${ghc}." 339 ${optionalString (isLibrary && hyperlinkSource) "export PATH=${hscolour}/bin:$PATH"} 340 341 builddir="$(mktemp -d)" 342 setupPackageConfDir="$builddir/setup-package.conf.d" 343 mkdir -p $setupPackageConfDir 344 packageConfDir="$builddir/package.conf.d" 345 mkdir -p $packageConfDir 346 347 setupCompileFlags="${concatStringsSep " " setupCompileFlags}" 348 configureFlags="${concatStringsSep " " defaultConfigureFlags} $configureFlags" 349 '' 350 # We build the Setup.hs on the *build* machine, and as such should only add 351 # dependencies for the build machine. 352 # 353 # pkgs* arrays defined in stdenv/setup.hs 354 + '' 355 for p in "''${pkgsBuildBuild[@]}" "''${pkgsBuildHost[@]}" "''${pkgsBuildTarget[@]}"; do 356 ${buildPkgDb "${nativeGhcCommand}-${nativeGhc.version}" "$setupPackageConfDir"} 357 done 358 ${nativeGhcCommand}-pkg --${nativePackageDbFlag}="$setupPackageConfDir" recache 359 '' 360 # For normal components 361 + '' 362 for p in "''${pkgsHostHost[@]}" "''${pkgsHostTarget[@]}"; do 363 ${buildPkgDb ghcNameWithPrefix "$packageConfDir"} 364 if [ -d "$p/include" ]; then 365 configureFlags+=" --extra-include-dirs=$p/include" 366 fi 367 if [ -d "$p/lib" ]; then 368 configureFlags+=" --extra-lib-dirs=$p/lib" 369 fi 370 '' 371 # It is not clear why --extra-framework-dirs does work fine on Linux 372 + optionalString (!stdenv.buildPlatform.isDarwin || versionAtLeast nativeGhc.version "8.0") '' 373 if [[ -d "$p/Library/Frameworks" ]]; then 374 configureFlags+=" --extra-framework-dirs=$p/Library/Frameworks" 375 fi 376 '' + '' 377 done 378 '' 379 # only use the links hack if we're actually building dylibs. otherwise, the 380 # "dynamic-library-dirs" point to nonexistent paths, and the ln command becomes 381 # "ln -s $out/lib/links", which tries to recreate the links dir and fails 382 + (optionalString (stdenv.isDarwin && (enableSharedLibraries || enableSharedExecutables)) '' 383 # Work around a limit in the macOS Sierra linker on the number of paths 384 # referenced by any one dynamic library: 385 # 386 # Create a local directory with symlinks of the *.dylib (macOS shared 387 # libraries) from all the dependencies. 388 local dynamicLinksDir="$out/lib/links" 389 mkdir -p $dynamicLinksDir 390 391 # Unprettify all package conf files before reading/writing them 392 for d in "$packageConfDir/"*; do 393 # gawk -i inplace seems to strip the last newline 394 gawk -f ${unprettyConf} "$d" > tmp 395 mv tmp "$d" 396 done 397 398 for d in $(grep '^dynamic-library-dirs:' "$packageConfDir"/* | cut -d' ' -f2- | tr ' ' '\n' | sort -u); do 399 for lib in "$d/"*.{dylib,so}; do 400 # Allow overwriting because C libs can be pulled in multiple times. 401 ln -sf "$lib" "$dynamicLinksDir" 402 done 403 done 404 # Edit the local package DB to reference the links directory. 405 for f in "$packageConfDir/"*.conf; do 406 sed -i "s,dynamic-library-dirs: .*,dynamic-library-dirs: $dynamicLinksDir," "$f" 407 done 408 '') + '' 409 ${ghcCommand}-pkg --${packageDbFlag}="$packageConfDir" recache 410 411 runHook postSetupCompilerEnvironment 412 ''; 413 414 compileBuildDriverPhase = '' 415 runHook preCompileBuildDriver 416 417 for i in Setup.hs Setup.lhs ${defaultSetupHs}; do 418 test -f $i && break 419 done 420 421 echo setupCompileFlags: $setupCompileFlags 422 ${nativeGhcCommand} $setupCompileFlags --make -o Setup -odir $builddir -hidir $builddir $i 423 424 runHook postCompileBuildDriver 425 ''; 426 427 # Cabal takes flags like `--configure-option=--host=...` instead 428 configurePlatforms = []; 429 inherit configureFlags; 430 431 # Note: the options here must be always added, regardless of whether the 432 # package specifies `hardeningDisable`. 433 hardeningDisable = lib.optionals (args ? hardeningDisable) hardeningDisable 434 ++ lib.optional (ghc.isHaLVM or false) "all" 435 # Static libraries (ie. all of pkgsStatic.haskellPackages) fail to build 436 # because by default Nix adds `-pie` to the linker flags: this 437 # conflicts with the `-r` and `-no-pie` flags added by GHC (see 438 # https://gitlab.haskell.org/ghc/ghc/-/issues/19580). hardeningDisable 439 # changes the default Nix behavior regarding adding "hardening" flags. 440 ++ lib.optional enableStaticLibraries "pie"; 441 442 configurePhase = '' 443 runHook preConfigure 444 445 unset GHC_PACKAGE_PATH # Cabal complains if this variable is set during configure. 446 447 echo configureFlags: $configureFlags 448 ${setupCommand} configure $configureFlags 2>&1 | ${coreutils}/bin/tee "$NIX_BUILD_TOP/cabal-configure.log" 449 ${lib.optionalString (!allowInconsistentDependencies) '' 450 if ${gnugrep}/bin/egrep -q -z 'Warning:.*depends on multiple versions' "$NIX_BUILD_TOP/cabal-configure.log"; then 451 echo >&2 "*** abort because of serious configure-time warning from Cabal" 452 exit 1 453 fi 454 ''} 455 export GHC_PACKAGE_PATH="$packageConfDir:" 456 457 runHook postConfigure 458 ''; 459 460 buildPhase = '' 461 runHook preBuild 462 ${setupCommand} build ${buildTarget}${crossCabalFlagsString}${buildFlagsString} 463 runHook postBuild 464 ''; 465 466 inherit doCheck; 467 468 # Run test suite(s) and pass `checkFlags` as well as `checkFlagsArray`. 469 # `testFlags` are added to `checkFlagsArray` each prefixed with 470 # `--test-option`, so Cabal passes it to the underlying test suite binary. 471 checkPhase = '' 472 runHook preCheck 473 checkFlagsArray+=( 474 "--show-details=streaming" 475 ${lib.escapeShellArgs (builtins.map (opt: "--test-option=${opt}") testFlags)} 476 ) 477 ${setupCommand} test ${testTarget} $checkFlags ''${checkFlagsArray:+"''${checkFlagsArray[@]}"} 478 runHook postCheck 479 ''; 480 481 haddockPhase = '' 482 runHook preHaddock 483 ${optionalString (doHaddock && isLibrary) '' 484 ${setupCommand} haddock --html \ 485 ${optionalString doHoogle "--hoogle"} \ 486 ${optionalString doHaddockQuickjump "--quickjump"} \ 487 ${optionalString (isLibrary && hyperlinkSource) "--hyperlink-source"} \ 488 ${lib.concatStringsSep " " haddockFlags} 489 ''} 490 runHook postHaddock 491 ''; 492 493 installPhase = '' 494 runHook preInstall 495 496 ${if !isLibrary && buildTarget == "" then "${setupCommand} install" 497 # ^^ if the project is not a library, and no build target is specified, we can just use "install". 498 else if !isLibrary then "${setupCommand} copy ${buildTarget}" 499 # ^^ if the project is not a library, and we have a build target, then use "copy" to install 500 # just the target specified; "install" will error here, since not all targets have been built. 501 else '' 502 ${setupCommand} copy ${buildTarget} 503 local packageConfDir="$out/lib/${ghcNameWithPrefix}/package.conf.d" 504 local packageConfFile="$packageConfDir/${pname}-${version}.conf" 505 mkdir -p "$packageConfDir" 506 ${setupCommand} register --gen-pkg-config=$packageConfFile 507 if [ -d "$packageConfFile" ]; then 508 mv "$packageConfFile/"* "$packageConfDir" 509 rmdir "$packageConfFile" 510 fi 511 for packageConfFile in "$packageConfDir/"*; do 512 local pkgId=$(gawk -f ${unprettyConf} "$packageConfFile" \ 513 | grep '^id:' | cut -d' ' -f2) 514 mv "$packageConfFile" "$packageConfDir/$pkgId.conf" 515 done 516 517 # delete confdir if there are no libraries 518 find $packageConfDir -maxdepth 0 -empty -delete; 519 ''} 520 ${optionalString isGhcjs '' 521 for exeDir in "${binDir}/"*.jsexe; do 522 exe="''${exeDir%.jsexe}" 523 printWords '#!${nodejs}/bin/node' > "$exe" 524 echo >> "$exe" 525 cat "$exeDir/all.js" >> "$exe" 526 chmod +x "$exe" 527 done 528 ''} 529 ${optionalString doCoverage "mkdir -p $out/share && cp -r dist/hpc $out/share"} 530 ${optionalString (enableSharedExecutables && isExecutable && !isGhcjs && stdenv.isDarwin && lib.versionOlder ghc.version "7.10") '' 531 for exe in "${binDir}/"* ; do 532 install_name_tool -add_rpath "$out/lib/ghc-${ghc.version}/${pname}-${version}" "$exe" 533 done 534 ''} 535 536 ${optionalString enableSeparateDocOutput '' 537 for x in ${docdir "$doc"}"/html/src/"*.html; do 538 remove-references-to -t $out $x 539 done 540 mkdir -p $doc 541 ''} 542 ${optionalString enableSeparateDataOutput "mkdir -p $data"} 543 544 runHook postInstall 545 ''; 546 547 passthru = passthru // rec { 548 549 inherit pname version; 550 551 compiler = ghc; 552 553 # All this information is intended just for `shellFor`. It should be 554 # considered unstable and indeed we knew how to keep it private we would. 555 getCabalDeps = { 556 inherit 557 buildDepends 558 buildTools 559 executableFrameworkDepends 560 executableHaskellDepends 561 executablePkgconfigDepends 562 executableSystemDepends 563 executableToolDepends 564 extraLibraries 565 libraryFrameworkDepends 566 libraryHaskellDepends 567 libraryPkgconfigDepends 568 librarySystemDepends 569 libraryToolDepends 570 pkg-configDepends 571 setupHaskellDepends 572 ; 573 } // lib.optionalAttrs doCheck { 574 inherit 575 testDepends 576 testFrameworkDepends 577 testHaskellDepends 578 testPkgconfigDepends 579 testSystemDepends 580 testToolDepends 581 ; 582 } // lib.optionalAttrs doBenchmark { 583 inherit 584 benchmarkDepends 585 benchmarkFrameworkDepends 586 benchmarkHaskellDepends 587 benchmarkPkgconfigDepends 588 benchmarkSystemDepends 589 benchmarkToolDepends 590 ; 591 }; 592 593 # Attributes for the old definition of `shellFor`. Should be removed but 594 # this predates the warning at the top of `getCabalDeps`. 595 getBuildInputs = rec { 596 inherit propagatedBuildInputs otherBuildInputs allPkgconfigDepends; 597 haskellBuildInputs = isHaskellPartition.right; 598 systemBuildInputs = isHaskellPartition.wrong; 599 isHaskellPartition = lib.partition 600 isHaskellPkg 601 (propagatedBuildInputs ++ otherBuildInputs ++ depsBuildBuild ++ nativeBuildInputs); 602 }; 603 604 isHaskellLibrary = isLibrary; 605 606 # TODO: ask why the split outputs are configurable at all? 607 # TODO: include tests for split if possible 608 # Given the haskell package, returns 609 # the directory containing the haddock documentation. 610 # `null' if no haddock documentation was built. 611 # TODO: fetch the self from the fixpoint instead 612 haddockDir = self: if doHaddock then "${docdir self.doc}/html" else null; 613 614 # Creates a derivation containing all of the necessary dependencies for building the 615 # parent derivation. The attribute set that it takes as input can be viewed as: 616 # 617 # { withHoogle } 618 # 619 # The derivation that it builds contains no outpaths because it is meant for use 620 # as an environment 621 # 622 # # Example use 623 # # Creates a shell with all of the dependencies required to build the "hello" package, 624 # # and with python: 625 # 626 # > nix-shell -E 'with (import <nixpkgs> {}); \ 627 # > haskell.packages.ghc865.hello.envFunc { buildInputs = [ python ]; }' 628 envFunc = { withHoogle ? false }: 629 let 630 name = "ghc-shell-for-${drv.name}"; 631 632 withPackages = if withHoogle then ghcWithHoogle else ghcWithPackages; 633 634 # We use the `ghcWithPackages` function from `buildHaskellPackages` if we 635 # want a shell for the sake of cross compiling a package. In the native case 636 # we don't use this at all, and instead put the setupDepends in the main 637 # `ghcWithPackages`. This way we don't have two wrapper scripts called `ghc` 638 # shadowing each other on the PATH. 639 ghcEnvForBuild = 640 assert isCross; 641 buildHaskellPackages.ghcWithPackages (_: setupHaskellDepends); 642 643 ghcEnv = withPackages (_: 644 otherBuildInputsHaskell ++ 645 propagatedBuildInputs ++ 646 lib.optionals (!isCross) setupHaskellDepends); 647 648 ghcCommandCaps = lib.toUpper ghcCommand'; 649 in stdenv.mkDerivation ({ 650 inherit name shellHook; 651 652 depsBuildBuild = lib.optional isCross ghcEnvForBuild; 653 nativeBuildInputs = 654 [ ghcEnv ] ++ optional (allPkgconfigDepends != []) pkg-config ++ 655 collectedToolDepends; 656 buildInputs = 657 otherBuildInputsSystem; 658 phases = ["installPhase"]; 659 installPhase = "echo $nativeBuildInputs $buildInputs > $out"; 660 LANG = "en_US.UTF-8"; 661 LOCALE_ARCHIVE = lib.optionalString (stdenv.hostPlatform.libc == "glibc") "${buildPackages.glibcLocales}/lib/locale/locale-archive"; 662 "NIX_${ghcCommandCaps}" = "${ghcEnv}/bin/${ghcCommand}"; 663 "NIX_${ghcCommandCaps}PKG" = "${ghcEnv}/bin/${ghcCommand}-pkg"; 664 # TODO: is this still valid? 665 "NIX_${ghcCommandCaps}_DOCDIR" = "${ghcEnv}/share/doc/ghc/html"; 666 "NIX_${ghcCommandCaps}_LIBDIR" = if ghc.isHaLVM or false 667 then "${ghcEnv}/lib/HaLVM-${ghc.version}" 668 else "${ghcEnv}/lib/${ghcCommand}-${ghc.version}"; 669 }); 670 671 env = envFunc { }; 672 673 }; 674 675 meta = { inherit homepage license platforms; } 676 // optionalAttrs (args ? broken) { inherit broken; } 677 // optionalAttrs (args ? description) { inherit description; } 678 // optionalAttrs (args ? maintainers) { inherit maintainers; } 679 // optionalAttrs (args ? hydraPlatforms) { inherit hydraPlatforms; } 680 // optionalAttrs (args ? badPlatforms) { inherit badPlatforms; } 681 // optionalAttrs (args ? changelog) { inherit changelog; } 682 // optionalAttrs (args ? mainProgram) { inherit mainProgram; } 683 ; 684 685} 686// optionalAttrs (args ? preCompileBuildDriver) { inherit preCompileBuildDriver; } 687// optionalAttrs (args ? postCompileBuildDriver) { inherit postCompileBuildDriver; } 688// optionalAttrs (args ? preUnpack) { inherit preUnpack; } 689// optionalAttrs (args ? postUnpack) { inherit postUnpack; } 690// optionalAttrs (args ? patches) { inherit patches; } 691// optionalAttrs (args ? patchPhase) { inherit patchPhase; } 692// optionalAttrs (args ? preConfigure) { inherit preConfigure; } 693// optionalAttrs (args ? postConfigure) { inherit postConfigure; } 694// optionalAttrs (args ? preBuild) { inherit preBuild; } 695// optionalAttrs (args ? postBuild) { inherit postBuild; } 696// optionalAttrs (args ? doBenchmark) { inherit doBenchmark; } 697// optionalAttrs (args ? checkPhase) { inherit checkPhase; } 698// optionalAttrs (args ? preCheck) { inherit preCheck; } 699// optionalAttrs (args ? postCheck) { inherit postCheck; } 700// optionalAttrs (args ? preHaddock) { inherit preHaddock; } 701// optionalAttrs (args ? postHaddock) { inherit postHaddock; } 702// optionalAttrs (args ? preInstall) { inherit preInstall; } 703// optionalAttrs (args ? installPhase) { inherit installPhase; } 704// optionalAttrs (args ? postInstall) { inherit postInstall; } 705// optionalAttrs (args ? preFixup) { inherit preFixup; } 706// optionalAttrs (args ? postFixup) { inherit postFixup; } 707// optionalAttrs (args ? dontStrip) { inherit dontStrip; } 708// optionalAttrs (stdenv.buildPlatform.libc == "glibc"){ LOCALE_ARCHIVE = "${glibcLocales}/lib/locale/locale-archive"; } 709) 710)