@@ -1,4 +1,4 @@
1−{ stdenv, buildPackages, ghc, lib, gobject-introspection ? null, haskellLib, makeConfigFiles, ghcForComponent, hsPkgs, runCommand, libffi, gmp, zlib, ncurses, numactl, nodejs }:
1+{ stdenv, buildPackages, ghc, lib, gobject-introspection ? null, haskellLib, makeConfigFiles, haddockBuilder, ghcForComponent, hsPkgs, runCommand, libffi, gmp, zlib, ncurses, numactl, nodejs }:
2lib.makeOverridable (
2lib.makeOverridable (
4{ componentId
4{ componentId
@@ -43,6 +43,7 @@ let self =
43, doHaddock ? component.doHaddock # Enable haddock and hoogle generation
43, doHaddock ? component.doHaddock # Enable haddock and hoogle generation
44, doHoogle ? component.doHoogle # Also build a hoogle index
44, doHoogle ? component.doHoogle # Also build a hoogle index
45, hyperlinkSource ? component.doHyperlinkSource # Link documentation to the source code
45, hyperlinkSource ? component.doHyperlinkSource # Link documentation to the source code
46+, quickjump ? component.doQuickjump # Generate an index for interactive documentation navigation
46, keepSource ? component.keepSource # Build from `source` output in the store then delete `dist`
47, keepSource ? component.keepSource # Build from `source` output in the store then delete `dist`
47, setupHaddockFlags ? component.setupHaddockFlags
48, setupHaddockFlags ? component.setupHaddockFlags
@@ -70,10 +71,11 @@ let
71 fullName = "${nameOnly}-${package.identifier.version}";
72 fullName = "${nameOnly}-${package.identifier.version}";
74+ needsProfiling = enableExecutableProfiling || enableLibraryProfiling;
73 configFiles = makeConfigFiles {
76 configFiles = makeConfigFiles {
74 inherit (package) identifier;
77 inherit (package) identifier;
75− inherit component fullName flags;
78+ inherit component fullName flags needsProfiling;
76− needsProfiling = enableExecutableProfiling || enableLibraryProfiling;
79 enableFeature = enable: feature:
81 enableFeature = enable: feature:
@@ -85,6 +87,9 @@ let
85 [ "--prefix=$out"
87 [ "--prefix=$out"
86 "${haskellLib.componentTarget componentId}"
88 "${haskellLib.componentTarget componentId}"
87 "$(cat ${configFiles}/configure-flags)"
89 "$(cat ${configFiles}/configure-flags)"
90+ ] ++ commonConfigureFlags);
92+ commonConfigureFlags = ([
89 "--with-ghc=${ghc.targetPrefix}ghc"
94 "--with-ghc=${ghc.targetPrefix}ghc"
90 "--with-ghc-pkg=${ghc.targetPrefix}ghc-pkg"
95 "--with-ghc-pkg=${ghc.targetPrefix}ghc-pkg"
@@ -123,7 +128,6 @@ let
123 "--ghc-option=-optl=-pthread"
128 "--ghc-option=-optl=-pthread"
124 "--ghc-option=-optl=-static"
129 "--ghc-option=-optl=-static"
125 ] ++ lib.optional enableSeparateDataOutput "--datadir=$data/share/${ghc.name}"
130 ] ++ lib.optional enableSeparateDataOutput "--datadir=$data/share/${ghc.name}"
126− ++ lib.optional doHaddock' "--docdir=${docdir "$doc"}"
127 ++ lib.optional (enableLibraryProfiling || enableExecutableProfiling) "--profiling-detail=${profilingDetail}"
131 ++ lib.optional (enableLibraryProfiling || enableExecutableProfiling) "--profiling-detail=${profilingDetail}"
128 ++ lib.optional stdenv.hostPlatform.isLinux (enableFeature enableDeadCodeElimination "split-sections")
132 ++ lib.optional stdenv.hostPlatform.isLinux (enableFeature enableDeadCodeElimination "split-sections")
129 ++ lib.optionals haskellLib.isCrossHost (
133 ++ lib.optionals haskellLib.isCrossHost (
@@ -154,26 +158,63 @@ let
154 if builtins.isFunction shellHook then shellHook { inherit package shellWrappers; }
158 if builtins.isFunction shellHook then shellHook { inherit package shellWrappers; }
155 else abort "shellHook should be a string or a function";
159 else abort "shellHook should be a string or a function";
157− # the target dir for haddock documentation
158− docdir = docoutput: docoutput + "/share/doc/" + componentId.cname;
160− doHaddock' = doHaddock
161− && (haskellLib.isLibrary componentId)
162− && !haskellLib.isCrossHost;
164 exeExt = if stdenv.hostPlatform.isGhcjs then ".jsexe/all.js" else
161 exeExt = if stdenv.hostPlatform.isGhcjs then ".jsexe/all.js" else
165 if stdenv.hostPlatform.isWindows then ".exe" else "";
162 if stdenv.hostPlatform.isWindows then ".exe" else "";
166 exeName = componentId.cname + exeExt;
163 exeName = componentId.cname + exeExt;
167 testExecutable = "dist/build/${componentId.cname}/${exeName}";
164 testExecutable = "dist/build/${componentId.cname}/${exeName}";
166+ # Attributes that are common to both the build and haddock derivations
170+ LANG = "en_US.UTF-8"; # GHC needs the locale configured during the Haddock phase.
171+ LC_ALL = "en_US.UTF-8";
173+ enableParallelBuilding = true;
175+ SETUP_HS = setup + /bin/Setup;
177+ prePatch = if (cabalFile != null)
178+ then ''cat ${cabalFile} > ${package.identifier.name}.cabal''
179+ else lib.optionalString (cabal-generator == "hpack") ''
180+ ${buildPackages.haskell-nix.haskellPackages.hpack.components.exes.hpack}/bin/hpack
183+ # patches can (if they like) depend on the version and revision of the package.
184+ // lib.optionalAttrs (patches != []) {
186+ if builtins.isFunction p
187+ then p { inherit (package.identifier) version; inherit revision; }
191+ // haskellLib.optionalHooks {
192+ # These are hooks are needed to set up the source for building and running haddock
193+ inherit preUnpack postUnpack preConfigure postConfigure;
195+ // lib.optionalAttrs (stdenv.buildPlatform.libc == "glibc") {
196+ LOCALE_ARCHIVE = "${buildPackages.glibcLocales}/lib/locale/locale-archive";
169−in stdenv.lib.fix (drv:
201+stdenv.lib.fix (drv:
204+ haddock = haddockBuilder {
205+ inherit componentId component package flags commonConfigureFlags
206+ commonAttrs revision setupGhcOptions doHaddock
207+ doHoogle hyperlinkSource quickjump setupHaddockFlags
208+ needsProfiling configFiles preHaddock postHaddock;
171−stdenv.mkDerivation ({
214+stdenv.mkDerivation (commonAttrs // {
172 pname = nameOnly;
215 pname = nameOnly;
173 inherit (package.identifier) version;
216 inherit (package.identifier) version;
177 doCheck = false;
218 doCheck = false;
178 doCrossCheck = false;
219 doCrossCheck = false;
@@ -184,12 +225,15 @@ stdenv.mkDerivation ({
184 config = component;
225 config = component;
185 inherit configFiles executableToolDepends cleanSrc exeName;
226 inherit configFiles executableToolDepends cleanSrc exeName;
186 env = shellWrappers;
227 env = shellWrappers;
188− # The directory containing the haddock documentation.
189− # `null' if no haddock documentation was built.
190− haddockDir = if doHaddock' then "${docdir drv.doc}/html" else null;
191 profiled = self (drvArgs // { enableLibraryProfiling = true; });
228 profiled = self (drvArgs // { enableLibraryProfiling = true; });
229+ } // lib.optionalAttrs (haskellLib.isLibrary componentId) ({
231+ inherit (haddock) haddockDir; # This is null if `doHaddock = false`
232+ } // lib.optionalAttrs (haddock ? doc) {
233+ # `doHaddock = false` turns the doc of haddock output off
234+ inherit (haddock) doc;
195 homepage = package.homepage;
239 homepage = package.homepage;
@@ -202,11 +246,6 @@ stdenv.mkDerivation ({
202 platforms = if platforms == null then stdenv.lib.platforms.all else platforms;
246 platforms = if platforms == null then stdenv.lib.platforms.all else platforms;
205− LANG = "en_US.UTF-8"; # GHC needs the locale configured during the Haddock phase.
206− LC_ALL = "en_US.UTF-8";
208− enableParallelBuilding = true;
210 propagatedBuildInputs =
249 propagatedBuildInputs =
211 frameworks # Frameworks will be needed at link time
250 frameworks # Frameworks will be needed at link time
212 # Not sure why pkgconfig needs to be propagatedBuildInputs but
251 # Not sure why pkgconfig needs to be propagatedBuildInputs but
@@ -220,22 +259,10 @@ stdenv.mkDerivation ({
220 [shellWrappers buildPackages.removeReferencesTo]
259 [shellWrappers buildPackages.removeReferencesTo]
221 ++ executableToolDepends;
260 ++ executableToolDepends;
223− SETUP_HS = setup + /bin/Setup;
225 outputs = ["out" ]
262 outputs = ["out" ]
226 ++ (lib.optional enableSeparateDataOutput "data")
263 ++ (lib.optional enableSeparateDataOutput "data")
227− ++ (lib.optional doHaddock' "doc")
228 ++ (lib.optional keepSource "source");
264 ++ (lib.optional keepSource "source");
231− preInstallPhases = lib.optional doHaddock' "haddockPhase";
233− prePatch = if (cabalFile != null)
234− then ''cat ${cabalFile} > ${package.identifier.name}.cabal''
235− else lib.optionalString (cabal-generator == "hpack") ''
236− ${buildPackages.haskell-nix.haskellPackages.hpack.components.exes.hpack}/bin/hpack
239 configurePhase =
266 configurePhase =
240 (lib.optionalString keepSource ''
267 (lib.optionalString keepSource ''
241 cp -r . $source
268 cp -r . $source
@@ -259,35 +286,6 @@ stdenv.mkDerivation ({
260 checkPhase = "notice: Tests are only executed by building the .run sub-derivation of this component.";
287 checkPhase = "notice: Tests are only executed by building the .run sub-derivation of this component.";
264− # If we don't have any source files, no need to run haddock
265− [[ -n $(find . -name "*.hs" -o -name "*.lhs") ]] && {
266− docdir="${docdir "$doc"}"
271− ${lib.optionalString doHoogle "--hoogle"} \
272− ${lib.optionalString hyperlinkSource "--hyperlink-source"} \
273− ${lib.concatStringsSep " " (setupHaddockFlags ++ setupGhcOptions)}
275− html="dist/doc/html/${componentId.cname}"
277− if [ -d "$html" ]; then
278− # Ensure that libraries are not pulled into the docs closure.
279− # As an example, the prettified source code of a
280− # Paths_package module will contain store paths of the library package.
281− for x in "$html/src/"*.html; do
282− remove-references-to -t $out $x
285− cp -R "$html" "$docdir"/html
291 # Note: Cabal does *not* copy test executables during the `install` phase.
289 # Note: Cabal does *not* copy test executables during the `install` phase.
293 # Note 2: if a package contains multiple libs (lib + sublibs) SETUP register will generate a
291 # Note 2: if a package contains multiple libs (lib + sublibs) SETUP register will generate a
@@ -374,12 +372,11 @@ stdenv.mkDerivation ({
374 ${shellHookApplied}
372 ${shellHookApplied}
377−# patches can (if they like) depend on the version and revision of the package.
378−// lib.optionalAttrs (patches != []) { patches = map (p: if builtins.isFunction p then p { inherit (package.identifier) version; inherit revision; } else p) patches; }
379// haskellLib.optionalHooks {
375// haskellLib.optionalHooks {
380− inherit preUnpack postUnpack preConfigure postConfigure
376+ # These are the hooks that are not needed by haddock (see commonAttrs for the ones that
377+ # are shared with the haddock derivation)
381 preBuild postBuild
379 preBuild postBuild
382− preInstall postInstall preHaddock postHaddock;
380+ preInstall postInstall;
384−// lib.optionalAttrs (stdenv.buildPlatform.libc == "glibc"){ LOCALE_ARCHIVE = "${buildPackages.glibcLocales}/lib/locale/locale-archive"; }
385)); in self)
382)); in self)