Clone of https://github.com/NixOS/nixpkgs.git (to stress-test knotserver)
at release-18.03 433 lines 18 kB view raw
1{ stdenv, buildPackages, buildHaskellPackages, ghc 2, jailbreak-cabal, hscolour, cpphs, nodejs 3, buildPlatform, hostPlatform 4}: 5 6let 7 isCross = buildPlatform != hostPlatform; 8 inherit (buildPackages) 9 fetchurl removeReferencesTo 10 pkgconfig 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, description ? "" 23, doCheck ? !isCross && (stdenv.lib.versionOlder "7.4" ghc.version) 24, doBenchmark ? false 25, doHoogle ? true 26, editedCabalFile ? null 27, enableLibraryProfiling ? false 28, enableExecutableProfiling ? false 29# TODO enable shared libs for cross-compiling 30, enableSharedExecutables ? ((ghc.isGhcjs or false) || stdenv.lib.versionOlder "7.7" ghc.version) 31, enableSharedLibraries ? ((ghc.isGhcjs or false) || stdenv.lib.versionOlder "7.7" ghc.version) 32, enableSplitObjs ? null # OBSOLETE, use enableDeadCodeElimination 33, enableDeadCodeElimination ? (!stdenv.isDarwin) # TODO: use -dead_strip for darwin 34, enableStaticLibraries ? true 35, extraLibraries ? [], librarySystemDepends ? [], executableSystemDepends ? [] 36, homepage ? "http://hackage.haskell.org/package/${pname}" 37, platforms ? with stdenv.lib.platforms; unix ++ windows # GHC can cross-compile 38, hydraPlatforms ? null 39, hyperlinkSource ? true 40, isExecutable ? false, isLibrary ? !isExecutable 41, jailbreak ? false 42, license 43, maintainers ? [] 44, doCoverage ? false 45, doHaddock ? !(ghc.isHaLVM or false) 46, passthru ? {} 47, pkgconfigDepends ? [], libraryPkgconfigDepends ? [], executablePkgconfigDepends ? [], testPkgconfigDepends ? [], benchmarkPkgconfigDepends ? [] 48, testDepends ? [], testHaskellDepends ? [], testSystemDepends ? [] 49, benchmarkDepends ? [], benchmarkHaskellDepends ? [], benchmarkSystemDepends ? [] 50, testTarget ? "" 51, broken ? false 52, preCompileBuildDriver ? "", postCompileBuildDriver ? "" 53, preUnpack ? "", postUnpack ? "" 54, patches ? [], patchPhase ? "", prePatch ? "", postPatch ? "" 55, preConfigure ? "", postConfigure ? "" 56, preBuild ? "", postBuild ? "" 57, installPhase ? "", preInstall ? "", postInstall ? "" 58, checkPhase ? "", preCheck ? "", postCheck ? "" 59, preFixup ? "", postFixup ? "" 60, shellHook ? "" 61, coreSetup ? false # Use only core packages to build Setup.hs. 62, useCpphs ? false 63, hardeningDisable ? stdenv.lib.optional (ghc.isHaLVM or false) "all" 64, enableSeparateDataOutput ? false 65, enableSeparateDocOutput ? doHaddock 66} @ args: 67 68assert editedCabalFile != null -> revision != null; 69# OBSOLETE, use enableDeadCodeElimination 70assert enableSplitObjs == null; 71 72let 73 74 inherit (stdenv.lib) optional optionals optionalString versionOlder versionAtLeast 75 concatStringsSep enableFeature optionalAttrs toUpper; 76 77 isGhcjs = ghc.isGhcjs or false; 78 isHaLVM = ghc.isHaLVM or false; 79 packageDbFlag = if isGhcjs || isHaLVM || versionOlder "7.6" ghc.version 80 then "package-db" 81 else "package-conf"; 82 83 # GHC used for building Setup.hs 84 # 85 # Same as our GHC, unless we're cross, in which case it is native GHC with the 86 # same version, or ghcjs, in which case its the ghc used to build ghcjs. 87 nativeGhc = buildHaskellPackages.ghc; 88 nativePackageDbFlag = if versionOlder "7.6" nativeGhc.version 89 then "package-db" 90 else "package-conf"; 91 92 # the target dir for haddock documentation 93 docdir = docoutput: docoutput + "/share/doc"; 94 95 newCabalFileUrl = "http://hackage.haskell.org/package/${pname}-${version}/revision/${revision}.cabal"; 96 newCabalFile = fetchurl { 97 url = newCabalFileUrl; 98 sha256 = editedCabalFile; 99 name = "${pname}-${version}-r${revision}.cabal"; 100 }; 101 102 defaultSetupHs = builtins.toFile "Setup.hs" '' 103 import Distribution.Simple 104 main = defaultMain 105 ''; 106 107 hasActiveLibrary = isLibrary && (enableStaticLibraries || enableSharedLibraries || enableLibraryProfiling); 108 109 # We cannot enable -j<n> parallelism for libraries because GHC is far more 110 # likely to generate a non-determistic library ID in that case. Further 111 # details are at <https://github.com/peti/ghc-library-id-bug>. 112 enableParallelBuilding = (versionOlder "7.8" ghc.version && !hasActiveLibrary) || versionOlder "8.0.1" ghc.version; 113 114 crossCabalFlags = [ 115 "--with-ghc=${ghc.targetPrefix}ghc" 116 "--with-ghc-pkg=${ghc.targetPrefix}ghc-pkg" 117 "--with-gcc=${stdenv.cc.targetPrefix}cc" 118 "--with-ld=${stdenv.cc.bintools.targetPrefix}ld" 119 "--with-hsc2hs=${nativeGhc}/bin/hsc2hs" # not cross one 120 "--with-strip=${stdenv.cc.bintools.targetPrefix}strip" 121 ] ++ (if isHaLVM then [] else ["--hsc2hs-options=--cross-compile"]); 122 123 crossCabalFlagsString = 124 stdenv.lib.optionalString isCross (" " + stdenv.lib.concatStringsSep " " crossCabalFlags); 125 126 defaultConfigureFlags = [ 127 "--verbose" "--prefix=$out" "--libdir=\\$prefix/lib/\\$compiler" "--libsubdir=\\$pkgid" 128 (optionalString enableSeparateDataOutput "--datadir=$data/share/${ghc.name}") 129 (optionalString enableSeparateDocOutput "--docdir=${docdir "$doc"}") 130 "--with-gcc=$CC" # Clang won't work without that extra information. 131 "--package-db=$packageConfDir" 132 (optionalString (enableSharedExecutables && stdenv.isLinux) "--ghc-option=-optl=-Wl,-rpath=$out/lib/${ghc.name}/${pname}-${version}") 133 (optionalString (enableSharedExecutables && stdenv.isDarwin) "--ghc-option=-optl=-Wl,-headerpad_max_install_names") 134 (optionalString enableParallelBuilding "--ghc-option=-j$NIX_BUILD_CORES") 135 (optionalString useCpphs "--with-cpphs=${cpphs}/bin/cpphs --ghc-options=-cpp --ghc-options=-pgmP${cpphs}/bin/cpphs --ghc-options=-optP--cpp") 136 (enableFeature (enableDeadCodeElimination && !hostPlatform.isAarch32 && !hostPlatform.isAarch64 && (versionAtLeast "8.0.1" ghc.version)) "split-objs") 137 (enableFeature enableLibraryProfiling "library-profiling") 138 (enableFeature enableExecutableProfiling (if versionOlder ghc.version "8" then "executable-profiling" else "profiling")) 139 (enableFeature enableSharedLibraries "shared") 140 (optionalString (versionAtLeast ghc.version "7.10") (enableFeature doCoverage "coverage")) 141 (optionalString (isGhcjs || versionOlder "7" ghc.version) (enableFeature enableStaticLibraries "library-vanilla")) 142 (optionalString (isGhcjs || versionOlder "7.4" ghc.version) (enableFeature enableSharedExecutables "executable-dynamic")) 143 (optionalString (isGhcjs || versionOlder "7" ghc.version) (enableFeature doCheck "tests")) 144 ] ++ optionals (enableDeadCodeElimination && (stdenv.lib.versionOlder "8.0.1" ghc.version)) [ 145 "--ghc-option=-split-sections" 146 ] ++ optionals isGhcjs [ 147 "--ghcjs" 148 ] ++ optionals isCross ([ 149 "--configure-option=--host=${hostPlatform.config}" 150 ] ++ crossCabalFlags); 151 152 setupCompileFlags = [ 153 (optionalString (!coreSetup) "-${nativePackageDbFlag}=$packageConfDir") 154 (optionalString (isGhcjs || isHaLVM || versionOlder "7.8" ghc.version) "-j$NIX_BUILD_CORES") 155 # https://github.com/haskell/cabal/issues/2398 156 (optionalString (versionOlder "7.10" ghc.version && !isHaLVM) "-threaded") 157 ]; 158 159 isHaskellPkg = x: (x ? pname) && (x ? version) && (x ? env); 160 isSystemPkg = x: !isHaskellPkg x; 161 162 allPkgconfigDepends = pkgconfigDepends ++ libraryPkgconfigDepends ++ executablePkgconfigDepends ++ 163 optionals doCheck testPkgconfigDepends ++ optionals doBenchmark benchmarkPkgconfigDepends; 164 165 nativeBuildInputs = [ ghc nativeGhc removeReferencesTo ] ++ optional (allPkgconfigDepends != []) pkgconfig ++ 166 buildTools ++ libraryToolDepends ++ executableToolDepends; 167 propagatedBuildInputs = buildDepends ++ libraryHaskellDepends ++ executableHaskellDepends; 168 otherBuildInputs = setupHaskellDepends ++ extraLibraries ++ librarySystemDepends ++ executableSystemDepends ++ 169 optionals (allPkgconfigDepends != []) allPkgconfigDepends ++ 170 optionals doCheck (testDepends ++ testHaskellDepends ++ testSystemDepends ++ testToolDepends) ++ 171 optionals doBenchmark (benchmarkDepends ++ benchmarkHaskellDepends ++ benchmarkSystemDepends ++ benchmarkToolDepends); 172 allBuildInputs = propagatedBuildInputs ++ otherBuildInputs; 173 174 haskellBuildInputs = stdenv.lib.filter isHaskellPkg allBuildInputs; 175 systemBuildInputs = stdenv.lib.filter isSystemPkg allBuildInputs; 176 177 ghcEnv = ghc.withPackages (p: haskellBuildInputs); 178 179 setupCommand = "./Setup"; 180 181 ghcCommand' = if isGhcjs then "ghcjs" else "ghc"; 182 ghcCommand = "${ghc.targetPrefix}${ghcCommand'}"; 183 ghcCommandCaps= toUpper ghcCommand'; 184 185 nativeGhcCommand = "${nativeGhc.targetPrefix}ghc"; 186 187in 188 189assert allPkgconfigDepends != [] -> pkgconfig != null; 190 191stdenv.mkDerivation ({ 192 name = "${pname}-${version}"; 193 194 outputs = [ "out" ] ++ (optional enableSeparateDataOutput "data") ++ (optional enableSeparateDocOutput "doc"); 195 setOutputFlags = false; 196 197 pos = builtins.unsafeGetAttrPos "pname" args; 198 199 prePhases = ["setupCompilerEnvironmentPhase"]; 200 preConfigurePhases = ["compileBuildDriverPhase"]; 201 preInstallPhases = ["haddockPhase"]; 202 203 inherit src; 204 205 inherit nativeBuildInputs; 206 buildInputs = otherBuildInputs ++ optionals (!hasActiveLibrary) propagatedBuildInputs; 207 propagatedBuildInputs = optionals hasActiveLibrary propagatedBuildInputs; 208 209 LANG = "en_US.UTF-8"; # GHC needs the locale configured during the Haddock phase. 210 211 prePatch = optionalString (editedCabalFile != null) '' 212 echo "Replace Cabal file with edited version from ${newCabalFileUrl}." 213 cp ${newCabalFile} ${pname}.cabal 214 '' + prePatch; 215 216 postPatch = optionalString jailbreak '' 217 echo "Run jailbreak-cabal to lift version restrictions on build inputs." 218 ${jailbreak-cabal}/bin/jailbreak-cabal ${pname}.cabal 219 '' + postPatch; 220 221 setupCompilerEnvironmentPhase = '' 222 runHook preSetupCompilerEnvironment 223 224 echo "Build with ${ghc}." 225 ${optionalString (hasActiveLibrary && hyperlinkSource) "export PATH=${hscolour}/bin:$PATH"} 226 227 packageConfDir="$TMPDIR/package.conf.d" 228 mkdir -p $packageConfDir 229 230 setupCompileFlags="${concatStringsSep " " setupCompileFlags}" 231 configureFlags="${concatStringsSep " " defaultConfigureFlags} $configureFlags" 232 233 # host.*Pkgs defined in stdenv/setup.hs 234 for p in "''${pkgsHostHost[@]}" "''${pkgsHostTarget[@]}"; do 235 if [ -d "$p/lib/${ghc.name}/package.conf.d" ]; then 236 cp -f "$p/lib/${ghc.name}/package.conf.d/"*.conf $packageConfDir/ 237 continue 238 fi 239 if [ -d "$p/include" ]; then 240 configureFlags+=" --extra-include-dirs=$p/include" 241 fi 242 if [ -d "$p/lib" ]; then 243 configureFlags+=" --extra-lib-dirs=$p/lib" 244 fi 245 done 246 '' + (optionalString stdenv.isDarwin '' 247 # Work around a limit in the macOS Sierra linker on the number of paths 248 # referenced by any one dynamic library: 249 # 250 # Create a local directory with symlinks of the *.dylib (macOS shared 251 # libraries) from all the dependencies. 252 local dynamicLinksDir="$out/lib/links" 253 mkdir -p $dynamicLinksDir 254 for d in $(grep dynamic-library-dirs "$packageConfDir/"*|awk '{print $2}'|sort -u); do 255 ln -s "$d/"*.dylib $dynamicLinksDir 256 done 257 # Edit the local package DB to reference the links directory. 258 for f in "$packageConfDir/"*.conf; do 259 sed -i "s,dynamic-library-dirs: .*,dynamic-library-dirs: $dynamicLinksDir," $f 260 done 261 '') + '' 262 ${ghcCommand}-pkg --${packageDbFlag}="$packageConfDir" recache 263 264 runHook postSetupCompilerEnvironment 265 ''; 266 267 compileBuildDriverPhase = '' 268 runHook preCompileBuildDriver 269 270 for i in Setup.hs Setup.lhs ${defaultSetupHs}; do 271 test -f $i && break 272 done 273 274 echo setupCompileFlags: $setupCompileFlags 275 ${nativeGhcCommand} $setupCompileFlags --make -o Setup -odir $TMPDIR -hidir $TMPDIR $i 276 277 runHook postCompileBuildDriver 278 ''; 279 280 # Cabal takes flags like `--configure-option=--host=...` instead 281 configurePlatforms = []; 282 inherit configureFlags; 283 284 configurePhase = '' 285 runHook preConfigure 286 287 unset GHC_PACKAGE_PATH # Cabal complains if this variable is set during configure. 288 289 echo configureFlags: $configureFlags 290 ${setupCommand} configure $configureFlags 2>&1 | ${coreutils}/bin/tee "$NIX_BUILD_TOP/cabal-configure.log" 291 if ${gnugrep}/bin/egrep -q -z 'Warning:.*depends on multiple versions' "$NIX_BUILD_TOP/cabal-configure.log"; then 292 echo >&2 "*** abort because of serious configure-time warning from Cabal" 293 exit 1 294 fi 295 296 export GHC_PACKAGE_PATH="$packageConfDir:" 297 298 runHook postConfigure 299 ''; 300 301 buildPhase = '' 302 runHook preBuild 303 ${setupCommand} build ${buildTarget}${crossCabalFlagsString} 304 runHook postBuild 305 ''; 306 307 checkPhase = '' 308 runHook preCheck 309 ${setupCommand} test ${testTarget} 310 runHook postCheck 311 ''; 312 313 haddockPhase = '' 314 runHook preHaddock 315 ${optionalString (doHaddock && hasActiveLibrary) '' 316 ${setupCommand} haddock --html \ 317 ${optionalString doHoogle "--hoogle"} \ 318 ${optionalString (hasActiveLibrary && hyperlinkSource) "--hyperlink-source"} 319 ''} 320 runHook postHaddock 321 ''; 322 323 installPhase = '' 324 runHook preInstall 325 326 ${if !hasActiveLibrary then "${setupCommand} install" else '' 327 ${setupCommand} copy 328 local packageConfDir="$out/lib/${ghc.name}/package.conf.d" 329 local packageConfFile="$packageConfDir/${pname}-${version}.conf" 330 mkdir -p "$packageConfDir" 331 ${setupCommand} register --gen-pkg-config=$packageConfFile 332 if [ -d "$packageConfFile" ]; then 333 mv "$packageConfFile/"* "$packageConfDir" 334 rmdir "$packageConfFile" 335 fi 336 for packageConfFile in "$packageConfDir/"*; do 337 local pkgId=$( ${gnused}/bin/sed -n -e 's|^id: ||p' $packageConfFile ) 338 mv $packageConfFile $packageConfDir/$pkgId.conf 339 done 340 ''} 341 ${optionalString isGhcjs '' 342 for exeDir in "$out/bin/"*.jsexe; do 343 exe="''${exeDir%.jsexe}" 344 printWords '#!${nodejs}/bin/node' > "$exe" 345 cat "$exeDir/all.js" >> "$exe" 346 chmod +x "$exe" 347 done 348 ''} 349 ${optionalString doCoverage "mkdir -p $out/share && cp -r dist/hpc $out/share"} 350 ${optionalString (enableSharedExecutables && isExecutable && !isGhcjs && stdenv.isDarwin && stdenv.lib.versionOlder ghc.version "7.10") '' 351 for exe in "$out/bin/"* ; do 352 install_name_tool -add_rpath "$out/lib/ghc-${ghc.version}/${pname}-${version}" "$exe" 353 done 354 ''} 355 356 ${optionalString enableSeparateDocOutput '' 357 for x in ${docdir "$doc"}"/html/src/"*.html; do 358 remove-references-to -t $out $x 359 done 360 mkdir -p $doc 361 ''} 362 ${optionalString enableSeparateDataOutput "mkdir -p $data"} 363 364 runHook postInstall 365 ''; 366 367 passthru = passthru // { 368 369 inherit pname version; 370 371 compiler = ghc; 372 373 isHaskellLibrary = hasActiveLibrary; 374 375 # TODO: ask why the split outputs are configurable at all? 376 # TODO: include tests for split if possible 377 # Given the haskell package, returns 378 # the directory containing the haddock documentation. 379 # `null' if no haddock documentation was built. 380 # TODO: fetch the self from the fixpoint instead 381 haddockDir = self: if doHaddock then "${docdir self.doc}/html" else null; 382 383 env = stdenv.mkDerivation { 384 name = "interactive-${pname}-${version}-environment"; 385 buildInputs = systemBuildInputs; 386 nativeBuildInputs = [ ghcEnv ] ++ nativeBuildInputs; 387 LANG = "en_US.UTF-8"; 388 LOCALE_ARCHIVE = optionalString stdenv.isLinux "${glibcLocales}/lib/locale/locale-archive"; 389 shellHook = '' 390 export NIX_${ghcCommandCaps}="${ghcEnv}/bin/${ghcCommand}" 391 export NIX_${ghcCommandCaps}PKG="${ghcEnv}/bin/${ghcCommand}-pkg" 392 # TODO: is this still valid? 393 export NIX_${ghcCommandCaps}_DOCDIR="${ghcEnv}/share/doc/ghc/html" 394 ${if isHaLVM 395 then ''export NIX_${ghcCommandCaps}_LIBDIR="${ghcEnv}/lib/HaLVM-${ghc.version}"'' 396 else ''export NIX_${ghcCommandCaps}_LIBDIR="${ghcEnv}/lib/${ghcCommand}-${ghc.version}"''} 397 ${shellHook} 398 ''; 399 }; 400 }; 401 402 meta = { inherit homepage license platforms; } 403 // optionalAttrs broken { inherit broken; } 404 // optionalAttrs (description != "") { inherit description; } 405 // optionalAttrs (maintainers != []) { inherit maintainers; } 406 // optionalAttrs (hydraPlatforms != null) { inherit hydraPlatforms; } 407 ; 408 409} 410// optionalAttrs (preCompileBuildDriver != "") { inherit preCompileBuildDriver; } 411// optionalAttrs (postCompileBuildDriver != "") { inherit postCompileBuildDriver; } 412// optionalAttrs (preUnpack != "") { inherit preUnpack; } 413// optionalAttrs (postUnpack != "") { inherit postUnpack; } 414// optionalAttrs (patches != []) { inherit patches; } 415// optionalAttrs (patchPhase != "") { inherit patchPhase; } 416// optionalAttrs (preConfigure != "") { inherit preConfigure; } 417// optionalAttrs (postConfigure != "") { inherit postConfigure; } 418// optionalAttrs (preBuild != "") { inherit preBuild; } 419// optionalAttrs (postBuild != "") { inherit postBuild; } 420// optionalAttrs (doCheck) { inherit doCheck; } 421// optionalAttrs (doBenchmark) { inherit doBenchmark; } 422// optionalAttrs (checkPhase != "") { inherit checkPhase; } 423// optionalAttrs (preCheck != "") { inherit preCheck; } 424// optionalAttrs (postCheck != "") { inherit postCheck; } 425// optionalAttrs (preInstall != "") { inherit preInstall; } 426// optionalAttrs (installPhase != "") { inherit installPhase; } 427// optionalAttrs (postInstall != "") { inherit postInstall; } 428// optionalAttrs (preFixup != "") { inherit preFixup; } 429// optionalAttrs (postFixup != "") { inherit postFixup; } 430// optionalAttrs (dontStrip) { inherit dontStrip; } 431// optionalAttrs (hardeningDisable != []) { inherit hardeningDisable; } 432// optionalAttrs (buildPlatform.isLinux){ LOCALE_ARCHIVE = "${glibcLocales}/lib/locale/locale-archive"; } 433)