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