@@ -16,6 +16,7 @@
1616, preBuild ? null, postBuild ? null
1717, preCheck ? null, postCheck ? null
1818, preInstall ? null, postInstall ? null
19+, preHaddock ? null, postHaddock ? null
1920, shellHook ? null
2021
2122, doCheck ? component.doCheck || haskellLib.isTest componentId
@@ -25,6 +26,11 @@
2526
2627, static ? stdenv.hostPlatform.isMusl
2728, deadCodeElimination ? true
29+
30+# Options for Haddock generation
31+, doHaddock ? component.doHaddock # Enable haddock and hoogle generation
32+, doHoogle ? true # Also build a hoogle index
33+, hyperlinkSource ? true # Link documentation to the source code
2834}:
2935
3036let
@@ -164,7 +170,8 @@ let
164170 # other flags
165171 "--enable-executable-stripping"
166172 "--enable-library-stripping"
167− ] ++ lib.optional (deadCodeElimination && stdenv.hostPlatform.isLinux) "--enable-split-sections"
173+ ] ++ lib.optional doHaddock' "--docdir=${docdir "$doc"}"
174+ ++ lib.optional (deadCodeElimination && stdenv.hostPlatform.isLinux) "--enable-split-sections"
168175 ++ lib.optional (static) "--enable-static"
169176 ++ lib.optionals (stdenv.hostPlatform != stdenv.buildPlatform) (
170177 map (arg: "--hsc2hs-option=" + arg) ["--cross-compile" "--via-asm"]
@@ -182,7 +189,14 @@ let
182189 inherit package configFiles;
183190 };
184191
185−in stdenv.mkDerivation ({
192+ # the target dir for haddock documentation
193+ docdir = docoutput: docoutput + "/share/doc/" + componentId.cname;
194+
195+ doHaddock' = doHaddock && (haskellLib.isLibrary componentId);
196+
197+in stdenv.lib.fix (drv:
198+
199+stdenv.mkDerivation ({
186200 name = fullName;
187201
188202 inherit src doCheck doCrossCheck dontPatchELF dontStrip;
@@ -192,6 +206,10 @@ in stdenv.mkDerivation ({
192206 config = component;
193207 inherit configFiles;
194208 env = shellWrappers;
209+
210+ # The directory containing the haddock documentation.
211+ # `null' if no haddock documentation was built.
212+ haddockDir = if doHaddock' then "${docdir drv.doc}/html" else null;
195213 };
196214
197215 meta = {
@@ -216,13 +234,17 @@ in stdenv.mkDerivation ({
216234 ++ component.pkgconfig;
217235
218236 nativeBuildInputs =
219− [ghc]
237+ [ghc buildPackages.removeReferencesTo]
220238 ++ lib.optional (component.pkgconfig != []) pkgconfig
221239 ++ executableToolDepends;
222240
223241 SETUP_HS = setup + /bin/Setup;
224242
243+ outputs = ["out" ] ++ (lib.optional doHaddock' "doc");
244+
225245 # Phases
246+ preInstallPhases = lib.optional doHaddock' "haddockPhase";
247+
226248 prePatch = lib.optionalString (cabalFile != null) ''
227249 cat ${cabalFile} > ${package.identifier.name}.cabal
228250 '';
@@ -250,6 +272,32 @@ in stdenv.mkDerivation ({
250272 runHook postCheck
251273 '';
252274
275+ haddockPhase = ''
276+ runHook preHaddock
277+ docdir="${docdir "$doc"}"
278+ mkdir -p "$docdir"
279+
280+ $SETUP_HS haddock \
281+ "--html" \
282+ ${lib.optionalString doHoogle "--hoogle"} \
283+ ${lib.optionalString hyperlinkSource "--hyperlink-source"} \
284+ ${lib.concatStringsSep " " component.setupHaddockFlags}
285+
286+ html="dist/doc/html/${componentId.cname}"
287+
288+ if [ -d "$html" ]; then
289+ # Ensure that libraries are not pulled into the docs closure.
290+ # As an example, the prettified source code of a
291+ # Paths_package module will contain store paths of the library package.
292+ for x in "$html/src/"*.html; do
293+ remove-references-to -t $out $x
294+ done
295+
296+ cp -R "$html" "$docdir"/html
297+ fi
298+ runHook postHaddock
299+ '';
300+
253301 # Note: Cabal does *not* copy test executables during the `install` phase.
254302 installPhase = ''
255303 runHook preInstall
@@ -278,15 +326,10 @@ in stdenv.mkDerivation ({
278326}
279327# patches can (if they like) depend on the version and revision of the package.
280328// lib.optionalAttrs (patches != []) { patches = map (p: if builtins.isFunction p then p { inherit (package.identifier) version; inherit revision; } else p) patches; }
281−// lib.optionalAttrs (preUnpack != "") { inherit preUnpack; }
282−// lib.optionalAttrs (postUnpack != "") { inherit postUnpack; }
283−// lib.optionalAttrs (preConfigure != "") { inherit preConfigure; }
284−// lib.optionalAttrs (postConfigure != "") { inherit postConfigure; }
285−// lib.optionalAttrs (preBuild != "") { inherit preBuild; }
286−// lib.optionalAttrs (postBuild != "") { inherit postBuild; }
287−// lib.optionalAttrs (preCheck != "") { inherit preCheck; }
288−// lib.optionalAttrs (postCheck != "") { inherit postCheck; }
289−// lib.optionalAttrs (preInstall != "") { inherit preInstall; }
290−// lib.optionalAttrs (postInstall != "") { inherit postInstall; }
329+// haskellLib.optionalHooks {
330+ inherit preUnpack postUnpack preConfigure postConfigure
331+ preBuild postBuild preCheck postCheck
332+ preInstall postInstall preHaddock postHaddock;
333+}
291334// lib.optionalAttrs (stdenv.buildPlatform.libc == "glibc"){ LOCALE_ARCHIVE = "${buildPackages.glibcLocales}/lib/locale/locale-archive"; }
292−)
335+))