1{ stdenv, buildPackages, ghc, lib, gobject-introspection ? null, haskellLib, makeConfigFiles, haddockBuilder, ghcForComponent, hsPkgs, compiler, runCommand, libffi, gmp, zlib, ncurses, numactl, nodejs }:
7, name # This is the package name
16, preUnpack ? component.preUnpack, postUnpack ? component.postUnpack
17, configureFlags ? component.configureFlags
18, preConfigure ? component.preConfigure, postConfigure ? component.postConfigure
19, setupBuildFlags ? component.setupBuildFlags
20, preBuild ? component.preBuild , postBuild ? component.postBuild
21, preCheck ? component.preCheck , postCheck ? component.postCheck
22, setupInstallFlags ? component.setupInstallFlags
23, preInstall ? component.preInstall , postInstall ? component.postInstall
24, preHaddock ? component.preHaddock , postHaddock ? component.postHaddock
27, build-tools ? component.build-tools
28, pkgconfig ? component.pkgconfig
29, platforms ? component.platforms
30, frameworks ? component.frameworks
32, dontPatchELF ? component.dontPatchELF
33, dontStrip ? component.dontStrip
34, hardeningDisable ? component.hardeningDisable
36, enableStatic ? component.enableStatic
37, enableShared ? ghc.enableShared && component.enableShared && !haskellLib.isCrossHost
38 # on x86 we'll use shared libraries, even with musl m(
39 # ghc's internal linker seems to be broken on x86.
40 && !(stdenv.hostPlatform.isMusl && !stdenv.hostPlatform.isx86)
41, enableDeadCodeElimination ? component.enableDeadCodeElimination
43# Options for Haddock generation
44, doHaddock ? component.doHaddock # Enable haddock and hoogle generation
45, doHoogle ? component.doHoogle # Also build a hoogle index
46, hyperlinkSource ? component.doHyperlinkSource # Link documentation to the source code
47, quickjump ? component.doQuickjump # Generate an index for interactive documentation navigation
48, keepSource ? component.keepSource # Build from `source` output in the store then delete `dist`
49, setupHaddockFlags ? component.setupHaddockFlags
52, enableLibraryProfiling ? component.enableLibraryProfiling
53, enableExecutableProfiling ? component.enableExecutableProfiling
54, profilingDetail ? component.profilingDetail
57, doCoverage ? component.doCoverage
60, enableSeparateDataOutput ? component.enableSeparateDataOutput
62# Prelinked ghci libraries; will make iserv faster; especially for static builds.
63, enableLibraryForGhci ? true
66, enableDebugRTS ? false
69# This will only work with a custom TSan way enabled custom compiler
70, enableTSanRTS ? false
73, useLLVM ? ghc.useLLVM
78 # TODO fix cabal wildcard support so hpack wildcards can be mapped to cabal wildcards
79 cleanSrc = if cabal-generator == "hpack" && !(package.cleanHpack or false)
80 then builtins.trace ("Cleaning component source not supported for hpack package: " + name) src
81 else haskellLib.cleanCabalComponent package component src;
83 nameOnly = "${package.identifier.name}-${componentId.ctype}-${componentId.cname}";
85 fullName = "${nameOnly}-${package.identifier.version}";
87 needsProfiling = enableExecutableProfiling || enableLibraryProfiling;
89 configFiles = makeConfigFiles {
90 inherit (package) identifier;
91 inherit component fullName flags needsProfiling;
94 enableFeature = enable: feature:
95 (if enable then "--enable-" else "--disable-") + feature;
97 disableFeature = disable: enableFeature (!disable);
99 finalConfigureFlags = lib.concatStringsSep " " (
101 "${haskellLib.componentTarget componentId}"
102 "$(cat ${configFiles}/configure-flags)"
103 ] ++ commonConfigureFlags);
105 # From nixpkgs 20.09, the pkg-config exe has a prefix matching the ghc one
106 pkgConfigHasPrefix = builtins.compareVersions lib.version "20.09pre" >= 0;
108 commonConfigureFlags = ([
110 "--with-ghc=${ghc.targetPrefix}ghc"
111 "--with-ghc-pkg=${ghc.targetPrefix}ghc-pkg"
112 "--with-hsc2hs=${ghc.targetPrefix}hsc2hs"
113 ] ++ lib.optional (pkgConfigHasPrefix && pkgconfig != [])
114 "--with-pkg-config=${ghc.targetPrefix}pkg-config"
115 ++ lib.optionals (stdenv.hasCC or (stdenv.cc != null))
117 [ "--with-gcc=${stdenv.cc.targetPrefix}cc"
120 (if stdenv.hostPlatform.isLinux
121 # use gold as the linker on linux to improve link times
123 "--with-ld=${stdenv.cc.bintools.targetPrefix}ld.gold"
124 "--ghc-option=-optl-fuse-ld=gold"
125 "--ld-option=-fuse-ld=gold"
127 "--with-ld=${stdenv.cc.bintools.targetPrefix}ld"
130 "--with-ar=${stdenv.cc.bintools.targetPrefix}ar"
131 "--with-strip=${stdenv.cc.bintools.targetPrefix}strip"
134 (disableFeature dontStrip "executable-stripping")
135 (disableFeature dontStrip "library-stripping")
136 (enableFeature enableLibraryProfiling "library-profiling")
137 (enableFeature enableExecutableProfiling "executable-profiling")
138 (enableFeature enableStatic "static")
139 (enableFeature enableShared "shared")
140 (enableFeature doCoverage "coverage")
141 (enableFeature enableLibraryForGhci "library-for-ghci")
142 ] ++ lib.optionals (stdenv.hostPlatform.isMusl && (haskellLib.isExecutableType componentId)) [
143 # These flags will make sure the resulting executable is statically linked.
144 # If it uses other libraries it may be necessary for to add more
145 # `--ghc-option=-optl=-L` options to the `configurationFlags` of the
147 "--disable-executable-dynamic"
148 "--ghc-option=-optl=-pthread"
149 "--ghc-option=-optl=-static"
150 ] ++ lib.optional enableSeparateDataOutput "--datadir=$data/share/${ghc.name}"
151 ++ lib.optional (enableLibraryProfiling || enableExecutableProfiling) "--profiling-detail=${profilingDetail}"
152 ++ lib.optional stdenv.hostPlatform.isLinux (enableFeature enableDeadCodeElimination "split-sections")
153 ++ lib.optionals haskellLib.isCrossHost (
154 map (arg: "--hsc2hs-option=" + arg) (["--cross-compile"] ++ lib.optionals (stdenv.hostPlatform.isWindows) ["--via-asm"])
155 ++ lib.optional (package.buildType == "Configure") "--configure-option=--host=${stdenv.hostPlatform.config}" )
157 ++ (ghc.extraConfigureFlags or [])
158 ++ lib.optional enableDebugRTS "--ghc-option=-debug"
159 ++ lib.optional enableTSanRTS "--ghc-option=-tsan"
160 ++ lib.optional enableDWARF "--ghc-option=-g"
161 ++ lib.optionals useLLVM [
162 "--ghc-option=-fPIC" "--gcc-option=-fPIC"
166 setupGhcOptions = lib.optional (package.ghcOptions != null) '' --ghc-options="${package.ghcOptions}"'';
168 executableToolDepends =
169 (lib.concatMap (c: if c.isHaskell or false
170 then builtins.attrValues (c.components.exes or {})
171 else [c]) build-tools) ++
172 lib.optional (pkgconfig != []) buildPackages.pkgconfig;
174 # Unfortunately, we need to wrap ghc commands for cabal builds to
175 # work in the nix-shell. See ../doc/removing-with-package-wrapper.md.
176 shellWrappers = ghcForComponent {
177 componentName = fullName;
181 # In order to let shell hooks make package-specific things like Hoogle databases
182 shellHookApplied = if builtins.isString shellHook then shellHook else
183 if builtins.isFunction shellHook then shellHook { inherit package shellWrappers; }
184 else abort "shellHook should be a string or a function";
186 exeExt = if stdenv.hostPlatform.isGhcjs then ".jsexe/all.js" else
187 if stdenv.hostPlatform.isWindows then ".exe" else "";
188 exeName = componentId.cname + exeExt;
189 testExecutable = "dist/build/${componentId.cname}/${exeName}";
191 # Attributes that are common to both the build and haddock derivations
195 LANG = "en_US.UTF-8"; # GHC needs the locale configured during the Haddock phase.
196 LC_ALL = "en_US.UTF-8";
198 enableParallelBuilding = true;
200 SETUP_HS = setup + /bin/Setup;
202 prePatch = if (cabalFile != null)
203 then ''cat ${cabalFile} > ${package.identifier.name}.cabal''
205 # When building hpack package we use the internal nix-tools
206 # (compiled with a fixed GHC version)
207 lib.optionalString (cabal-generator == "hpack") ''
208 ${buildPackages.haskell-nix.internal-nix-tools}/bin/hpack
211 # patches can (if they like) depend on the version and revision of the package.
212 // lib.optionalAttrs (patches != []) {
214 if builtins.isFunction p
215 then p { inherit (package.identifier) version; inherit revision; }
219 // haskellLib.optionalHooks {
220 # These are hooks are needed to set up the source for building and running haddock
221 inherit preUnpack postUnpack preConfigure postConfigure;
223 // lib.optionalAttrs (stdenv.buildPlatform.libc == "glibc") {
224 LOCALE_ARCHIVE = "${buildPackages.glibcLocales}/lib/locale/locale-archive";
227 haddock = haddockBuilder {
228 inherit componentId component package flags commonConfigureFlags
229 commonAttrs revision setupGhcOptions doHaddock
230 doHoogle hyperlinkSource quickjump setupHaddockFlags
231 needsProfiling configFiles preHaddock postHaddock pkgconfig;
236 drv = stdenv.mkDerivation (commonAttrs // {
238 inherit (package.identifier) version;
241 doCrossCheck = false;
243 inherit dontPatchELF dontStrip;
246 inherit (package) identifier;
248 inherit configFiles executableToolDepends cleanSrc exeName;
250 profiled = self (drvArgs // { enableLibraryProfiling = true; });
251 } // lib.optionalAttrs (haskellLib.isLibrary componentId) ({
253 inherit (haddock) haddockDir; # This is null if `doHaddock = false`
254 } // lib.optionalAttrs (haddock ? doc) {
255 # `doHaddock = false` turns the doc of haddock output off
256 inherit (haddock) doc;
261 homepage = package.homepage or "";
262 description = package.synopsis or "";
265 license-map = import ../lib/cabal-licenses.nix lib;
266 in license-map.${package.license} or
267 (builtins.trace "WARNING: license \"${package.license}\" not found" license-map.LicenseRef-OtherLicense);
268 platforms = if platforms == null then stdenv.lib.platforms.all else platforms;
271 propagatedBuildInputs =
272 frameworks # Frameworks will be needed at link time
273 # Not sure why pkgconfig needs to be propagatedBuildInputs but
274 # for gi-gtk-hs it seems to help.
275 ++ builtins.concatLists pkgconfig;
277 buildInputs = component.libs
278 ++ map (d: d.components.library or d) component.depends;
281 [shellWrappers buildPackages.removeReferencesTo]
282 ++ executableToolDepends;
285 ++ (lib.optional enableSeparateDataOutput "data")
286 ++ (lib.optional keepSource "source");
289 (lib.optionalString keepSource ''
295 echo Configure flags:
296 printf "%q " ${finalConfigureFlags}
298 $SETUP_HS configure ${finalConfigureFlags}
299 runHook postConfigure
304 # https://gitlab.haskell.org/ghc/ghc/issues/9221
305 $SETUP_HS build ${haskellLib.componentTarget componentId} -j$(($NIX_BUILD_CORES > 4 ? 4 : $NIX_BUILD_CORES)) ${lib.concatStringsSep " " (setupBuildFlags ++ setupGhcOptions)}
309 # Note: Cabal does *not* copy test executables during the `install` phase.
311 # Note 2: if a package contains multiple libs (lib + sublibs) SETUP register will generate a
312 # folder instead of a file for the configuration. Therefore if the result is a folder,
313 # we need to register each and every element of that folder.
315 # Note 3: if a package has no libs SETUP will not generate anything. This can
316 # happen when building the `all` component of a package.
318 target-pkg-and-db = "${ghc.targetPrefix}ghc-pkg -v0 --package-db $out/package.conf.d";
321 $SETUP_HS copy ${lib.concatStringsSep " " setupInstallFlags}
322 ${lib.optionalString (haskellLib.isLibrary componentId) ''
323 $SETUP_HS register --gen-pkg-config=${name}.conf
324 ${ghc.targetPrefix}ghc-pkg -v0 init $out/package.conf.d
325 if [ -d "${name}.conf" ]; then
326 for pkg in ${name}.conf/*; do
327 ${ghc.targetPrefix}ghc-pkg -v0 --package-db ${configFiles}/${configFiles.packageCfgDir} -f $out/package.conf.d register "$pkg"
329 elif [ -e "${name}.conf" ]; then
330 ${ghc.targetPrefix}ghc-pkg -v0 --package-db ${configFiles}/${configFiles.packageCfgDir} -f $out/package.conf.d register ${name}.conf
333 mkdir -p $out/exactDep
334 touch $out/exactDep/configure-flags
335 touch $out/exactDep/cabal.config
338 if id=$(${target-pkg-and-db} field ${package.identifier.name} id --simple-output); then
339 echo "--dependency=${package.identifier.name}=$id" >> $out/exactDep/configure-flags
340 echo "package-id $id" >> $out/envDep
341 elif id=$(${target-pkg-and-db} field "z-${package.identifier.name}-z-*" id --simple-output); then
342 name=$(${target-pkg-and-db} field "z-${package.identifier.name}-z-*" name --simple-output)
343 # so we are dealing with a sublib. As we build sublibs separately, the above
344 # query should be safe.
345 echo "--dependency=''${name#z-${package.identifier.name}-z-}=$id" >> $out/exactDep/configure-flags
347 echo 'ERROR: ${package.identifier.name} id could not be found with ${target-pkg-and-db}'
350 if ver=$(${target-pkg-and-db} field ${package.identifier.name} version --simple-output); then
351 echo "constraint: ${package.identifier.name} == $ver" >> $out/exactDep/cabal.config
352 echo "constraint: ${package.identifier.name} installed" >> $out/exactDep/cabal.config
354 echo 'ERROR: ${package.identifier.name} version could not be found with ${target-pkg-and-db}'
358 ${(lib.optionalString (haskellLib.isTest componentId || haskellLib.isBenchmark componentId) ''
360 if [ -f ${testExecutable} ]; then
361 mkdir -p $(dirname $out/bin/${exeName})
362 ${if stdenv.hostPlatform.isGhcjs then ''
363 cat <(echo \#!${lib.getBin buildPackages.nodejs}/bin/node) ${testExecutable} >| $out/bin/${exeName}
364 chmod +x $out/bin/${exeName}
366 cp -r ${testExecutable} $(dirname $out/bin/${exeName})
370 # In case `setup copy` did not create this
371 + (lib.optionalString enableSeparateDataOutput "mkdir -p $data")
372 + (lib.optionalString (stdenv.hostPlatform.isWindows && (haskellLib.mayHaveExecutable componentId)) ''
373 echo "Symlink libffi and gmp .dlls ..."
374 for p in ${lib.concatStringsSep " " [ libffi gmp ]}; do
375 find "$p" -iname '*.dll' -exec ln -s {} $out/bin \;
377 # symlink all .dlls into the local directory.
378 # we ask ghc-pkg for *all* dynamic-library-dirs and then iterate over the unique set
379 # to symlink over dlls as needed.
380 echo "Symlink library dependencies..."
381 for libdir in $(x86_64-pc-mingw32-ghc-pkg --package-db=$packageConfDir field "*" dynamic-library-dirs --simple-output|xargs|sed 's/ /\n/g'|sort -u); do
382 if [ -d "$libdir" ]; then
383 find "$libdir" -iname '*.dll' -exec ln -s {} $out/bin \;
387 + (lib.optionalString doCoverage ''
389 cp -r dist/hpc $out/share
390 cp dist/setup-config $out/
394 '' + (lib.optionalString keepSource ''
396 '') + (lib.optionalString (haskellLib.isTest componentId) ''
397 echo The test ${package.identifier.name}.components.tests.${componentId.cname} was built. To run the test build ${package.identifier.name}.checks.${componentId.cname}.
401 export PATH="${shellWrappers}/bin:$PATH"
405 // haskellLib.optionalHooks {
406 # These are the hooks that are not needed by haddock (see commonAttrs for the ones that
407 # are shared with the haddock derivation)
410 preInstall postInstall;
412 // lib.optionalAttrs (hardeningDisable != []) {
413 inherit hardeningDisable;
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list