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