on iko/ghcjs-patch-master help sign in
Split haddock out into its own derivation (#725)
1e3c130Hamish Mackenzie
builder/comp-builder.nix+68−71
@@ -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 (
3let self =
3let self =
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
48
49
@@ -70,10 +71,11 @@ let
70
71
71 fullName = "${nameOnly}-${package.identifier.version}";
72 fullName = "${nameOnly}-${package.identifier.version}";
72
73
74+ needsProfiling = enableExecutableProfiling || enableLibraryProfiling;
75+
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;
77 };
79 };
78
80
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);
91+
92+ commonConfigureFlags = ([
88 # GHC
93 # GHC
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";
156
160
157− # the target dir for haddock documentation
158− docdir = docoutput: docoutput + "/share/doc/" + componentId.cname;
159−
160− doHaddock' = doHaddock
161− && (haskellLib.isLibrary componentId)
162− && !haskellLib.isCrossHost;
163−
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}";
168
165
166+ # Attributes that are common to both the build and haddock derivations
167+ commonAttrs = {
168+ src = cleanSrc;
169+
170+ LANG = "en_US.UTF-8"; # GHC needs the locale configured during the Haddock phase.
171+ LC_ALL = "en_US.UTF-8";
172+
173+ enableParallelBuilding = true;
174+
175+ SETUP_HS = setup + /bin/Setup;
176+
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
181+ '';
182+ }
183+ # patches can (if they like) depend on the version and revision of the package.
184+ // lib.optionalAttrs (patches != []) {
185+ patches = map (p:
186+ if builtins.isFunction p
187+ then p { inherit (package.identifier) version; inherit revision; }
188+ else p
189+ ) patches;
190+ }
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;
194+ }
195+ // lib.optionalAttrs (stdenv.buildPlatform.libc == "glibc") {
196+ LOCALE_ARCHIVE = "${buildPackages.glibcLocales}/lib/locale/locale-archive";
197+ };
198+
199+in
200+
169−in stdenv.lib.fix (drv:
201+stdenv.lib.fix (drv:
202+
203+let
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;
170
209
210+ componentDrv = drv;
211+ };
212+in
213+
171−stdenv.mkDerivation ({
214+stdenv.mkDerivation (commonAttrs // {
172 pname = nameOnly;
215 pname = nameOnly;
173 inherit (package.identifier) version;
216 inherit (package.identifier) version;
174
217
175− src = cleanSrc;
176−
177 doCheck = false;
218 doCheck = false;
178 doCrossCheck = false;
219 doCrossCheck = false;
179
220
@@ -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;
187−
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) ({
230+ inherit haddock;
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;
235+ }
192− };
236+ );
193
237
194 meta = {
238 meta = {
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;
203 };
247 };
204
248
205− LANG = "en_US.UTF-8"; # GHC needs the locale configured during the Haddock phase.
206− LC_ALL = "en_US.UTF-8";
207−
208− enableParallelBuilding = true;
209−
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;
222
261
223− SETUP_HS = setup + /bin/Setup;
224−
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");
229
265
230− # Phases
231− preInstallPhases = lib.optional doHaddock' "haddockPhase";
232−
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
237− '';
238−
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 ({
259
286
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.";
261
288
262− haddockPhase = ''
263− runHook preHaddock
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"}"
267− mkdir -p "$docdir"
268−
269− $SETUP_HS haddock \
270− "--html" \
271− ${lib.optionalString doHoogle "--hoogle"} \
272− ${lib.optionalString hyperlinkSource "--hyperlink-source"} \
273− ${lib.concatStringsSep " " (setupHaddockFlags ++ setupGhcOptions)}
274−
275− html="dist/doc/html/${componentId.cname}"
276−
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
283− done
284−
285− cp -R "$html" "$docdir"/html
286− fi
287− }
288− runHook postHaddock
289− '';
290−
291 # Note: Cabal does *not* copy test executables during the `install` phase.
289 # Note: Cabal does *not* copy test executables during the `install` phase.
292 #
290 #
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}
375 '';
373 '';
376}
374}
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)
378+ inherit
381 preBuild postBuild
379 preBuild postBuild
382− preInstall postInstall preHaddock postHaddock;
380+ preInstall postInstall;
383}
381}
384−// lib.optionalAttrs (stdenv.buildPlatform.libc == "glibc"){ LOCALE_ARCHIVE = "${buildPackages.glibcLocales}/lib/locale/locale-archive"; }
385)); in self)
382)); in self)
builder/default.nix+6−2
@@ -3,7 +3,11 @@
3let
3let
4 # Builds a single component of a package.
4 # Builds a single component of a package.
5 comp-builder = haskellLib.weakCallPackage pkgs ./comp-builder.nix {
5 comp-builder = haskellLib.weakCallPackage pkgs ./comp-builder.nix {
6− inherit ghc haskellLib makeConfigFiles ghcForComponent hsPkgs;
6+ inherit ghc haskellLib makeConfigFiles haddockBuilder ghcForComponent hsPkgs;
7+ };
8+
9+ haddockBuilder = haskellLib.weakCallPackage pkgs ./haddock-builder.nix {
10+ inherit ghc ghcForComponent haskellLib makeConfigFiles nonReinstallablePkgs;
7 };
11 };
8
12
9 setup-builder = haskellLib.weakCallPackage pkgs ./setup-builder.nix {
13 setup-builder = haskellLib.weakCallPackage pkgs ./setup-builder.nix {
@@ -45,7 +49,7 @@ let
45 index-state = pkgs.haskell-nix.internalHackageIndexState;
49 index-state = pkgs.haskell-nix.internalHackageIndexState;
46 }
50 }
47 }:
51 }:
48− haskellLib.weakCallPackage pkgs nixpkgsHoogle {
52+ haskellLib.weakCallPackage pkgs nixpkgsHoogle {
49 # For musl we can use haddock from the buildGHC
53 # For musl we can use haddock from the buildGHC
50 ghc = if stdenv.hostPlatform.isLinux && stdenv.targetPlatform.isMusl && !haskellLib.isNativeMusl
54 ghc = if stdenv.hostPlatform.isLinux && stdenv.targetPlatform.isMusl && !haskellLib.isNativeMusl
51 then ghc.buildGHC
55 then ghc.buildGHC
builder/haddock-builder.nixnew file+144
@@ -0,0 +1,144 @@
1+{ stdenv, buildPackages, lib, haskellLib, ghc, ghcForComponent, nonReinstallablePkgs, runCommand, writeText, writeScript, makeConfigFiles }:
2+
3+{ componentId
4+, component
5+, package
6+, flags
7+, revision
8+, commonAttrs
9+, preHaddock
10+, postHaddock
11+, commonConfigureFlags
12+
13+, doHaddock
14+, doHoogle
15+, hyperlinkSource
16+, quickjump
17+, setupHaddockFlags
18+, setupGhcOptions
19+
20+, needsProfiling
21+, componentDrv
22+, configFiles # component config files
23+}:
24+
25+let
26+ doHaddock' = doHaddock
27+ && (haskellLib.isLibrary componentId)
28+ && !haskellLib.isCrossHost;
29+
30+ # the target dir for haddock documentation
31+ docdir = docoutput: docoutput + "/share/doc/" + componentId.cname;
32+
33+ packageCfgDir = configFiles.packageCfgDir;
34+
35+ fullName = "${componentDrv.name}-haddock";
36+
37+ # These config files are like the one used in the build derivation,
38+ # but `chooseDrv` will be used to map all the references to libraries
39+ # to their haddock derivation.
40+ docsConfigFiles = makeConfigFiles {
41+ inherit (package) identifier;
42+ inherit component fullName flags needsProfiling;
43+ chooseDrv = p: p.haddock;
44+ };
45+
46+ finalConfigureFlags = lib.concatStringsSep " " (
47+ [ "--prefix=${componentDrv}"
48+ "${haskellLib.componentTarget componentId}"
49+ "$(cat ${docsConfigFiles}/configure-flags)"
50+ ]
51+ ++ commonConfigureFlags
52+ ++ lib.optional doHaddock' " --docdir=${docdir "$doc"}");
53+
54+ shellWrappers = ghcForComponent {
55+ componentName = fullName;
56+ configFiles = docsConfigFiles;
57+ };
58+
59+in stdenv.lib.fix (drv: stdenv.mkDerivation (commonAttrs // {
60+ name = fullName;
61+
62+ passthru = {
63+ configFiles = docsConfigFiles;
64+
65+ # The directory containing the haddock documentation.
66+ haddockDir = if doHaddock' then "${docdir drv.doc}/html" else null;
67+ };
68+
69+ # `out` contains the `package.conf.d` files used for building the
70+ # haddock files.
71+ # `doc` contains just the haddock output files.
72+ outputs = ["out"]
73+ ++ lib.optional doHaddock' "doc";
74+
75+ nativeBuildInputs =
76+ [ shellWrappers buildPackages.removeReferencesTo ]
77+ ++ componentDrv.executableToolDepends;
78+
79+ configurePhase = ''
80+ echo Configure flags:
81+ printf "%q " ${finalConfigureFlags}
82+ echo
83+ $SETUP_HS configure ${finalConfigureFlags}
84+ '';
85+
86+ buildPhase = ''
87+ mkdir -p $out
88+ '' + lib.optionalString doHaddock' ''
89+ runHook preHaddock
90+ # If we don't have any source files, no need to run haddock
91+ [[ -n $(find . -name "*.hs" -o -name "*.lhs") ]] && {
92+
93+ $SETUP_HS haddock \
94+ "--html" \
95+ ${lib.optionalString doHoogle "--hoogle"} \
96+ ${lib.optionalString hyperlinkSource "--hyperlink-source"} \
97+ ${lib.optionalString quickjump "--quickjump"} \
98+ ${lib.concatStringsSep " " (setupHaddockFlags ++ setupGhcOptions)}
99+ }
100+ runHook postHaddock
101+ '';
102+
103+ installPhase =
104+ let
105+ target-pkg-and-db = "${ghc.targetPrefix}ghc-pkg -v0 --package-db $out/package.conf.d";
106+ in ''
107+ html="dist/doc/html/${package.identifier.name}"
108+
109+ if [ -d "$html" ]; then
110+ # Ensure that libraries are not pulled into the docs closure.
111+ # As an example, the prettified source code of a
112+ # Paths_package module will contain store paths of the library package.
113+ for x in "$html/src/"*.html; do
114+ remove-references-to -t $out $x
115+ remove-references-to -t ${componentDrv} $x
116+ done
117+
118+ docdir="${docdir "$doc"}"
119+ mkdir -p "$docdir"
120+
121+ cp -R "$html" "$docdir"/html
122+ fi
123+
124+ ${ghc.targetPrefix}ghc-pkg -v0 init $out/package.conf.d
125+
126+ for i in "${componentDrv}/package.conf.d"/*.conf; do
127+ # Copy the .conf files from the build derivation, but replace the `haddock-intefaces:`
128+ # field with correct location for haddocks (now it is known). This will insure that
129+ # the other haddock derivations build to reference this one will have the correct
130+ # working hyper links.
131+ pkg=$(basename "$i")
132+ sed -e "s|haddock-interfaces:.*|haddock-interfaces: $docdir/html/${componentId.cname}.haddock|" -e "s|haddock-html:.*|haddock-html: $docdir/html/|" "$i" > "$pkg"
133+ ${ghc.targetPrefix}ghc-pkg -v0 --package-db ${docsConfigFiles}/${configFiles.packageCfgDir} -f $out/package.conf.d register "$pkg"
134+ done
135+
136+ ln -s ${componentDrv}/exactDep $out/exactDep
137+ ln -s ${componentDrv}/envDep $out/envDep
138+ '';
139+}
140+// haskellLib.optionalHooks {
141+ inherit preHaddock postHaddock;
142+}
143+))
144+
builder/make-config-files.nix+14−11
@@ -1,5 +1,7 @@
1{ stdenv, lib, haskellLib, ghc, nonReinstallablePkgs, runCommand, writeText, writeScript }:
1{ stdenv, lib, haskellLib, ghc, nonReinstallablePkgs, runCommand, writeText, writeScript }:
2
2
3+{ identifier, component, fullName, flags ? {}, needsProfiling ? false, chooseDrv ? drv: drv }:
4+
3let
5let
4 flagsAndConfig = field: xs: lib.optionalString (xs != []) ''
6 flagsAndConfig = field: xs: lib.optionalString (xs != []) ''
5 echo ${lib.concatStringsSep " " (map (x: "--${field}=${x}") xs)} >> $out/configure-flags
7 echo ${lib.concatStringsSep " " (map (x: "--${field}=${x}") xs)} >> $out/configure-flags
@@ -41,20 +43,21 @@ let
41 libDir = "lib/${ghcCommand}-${ghc.version}";
43 libDir = "lib/${ghcCommand}-${ghc.version}";
42 packageCfgDir = "${libDir}/package.conf.d";
44 packageCfgDir = "${libDir}/package.conf.d";
43
45
44−in { identifier, component, fullName, flags ? {}, needsProfiling ? false }:
45 # Filters out only library packages that for this GHC target
46 # Filters out only library packages that for this GHC target
46 # TODO investigate why this is needed
47 # TODO investigate why this is needed
47 # TODO find out why p ? configFiles helps (for instance for `R1909.aarch64-unknown-linux-gnu.tests.cabal-22.run.x86_64-linux`)
48 # TODO find out why p ? configFiles helps (for instance for `R1909.aarch64-unknown-linux-gnu.tests.cabal-22.run.x86_64-linux`)
49+ libDeps = map chooseDrv (
48− let libDeps = (if needsProfiling then (x: map (p: p.profiled or p) x) else x: x)
50+ (if needsProfiling then (x: map (p: p.profiled or p) x) else x: x)
49− (lib.filter (p: (p ? configFiles) && p.configFiles.targetPrefix == ghc.targetPrefix)
51+ (lib.filter (p: (p ? configFiles) && p.configFiles.targetPrefix == ghc.targetPrefix)
50− (map getLibComponent component.depends));
52+ (map getLibComponent component.depends))
53+ );
51− cfgFiles =
54+ cfgFiles =
52− let xs = map
55+ let xs = map
53− (p: "${p.configFiles}")
56+ (p: "${p.configFiles}")
54− libDeps;
57+ libDeps;
55− in lib.concatStringsSep "\" \"" xs;
58+ in lib.concatStringsSep "\" \"" xs;
56− libs = lib.concatMapStringsSep "\" \"" (p: "${p}") libDeps;
59+ libs = lib.concatMapStringsSep "\" \"" (p: "${p}") libDeps;
57− in
60+in
58 runCommand "${ghc.targetPrefix}${fullName}-config" {
61 runCommand "${ghc.targetPrefix}${fullName}-config" {
59 nativeBuildInputs = [ghc];
62 nativeBuildInputs = [ghc];
60 passthru = {
63 passthru = {
changelog.md+6
@@ -1,6 +1,12 @@
1This file contains a summary of changes to Haskell.nix and `nix-tools`
1This file contains a summary of changes to Haskell.nix and `nix-tools`
2that will impact users.
2that will impact users.
3
3
4+## June 25, 2019
5+* Haddock docs are now built in their own derivation when needed (not as part
6+ of the component build).
7+ They should build automatically when something (such as `shellFor`) attempts
8+ to accesses the `.doc` attribute of component.
9+
4## December 27, 2019
10## December 27, 2019
5* Fix overlays/bootstrap.nix to provide LLVM 6, not LLVM 5, to ghc-8.6.X compilers.
11* Fix overlays/bootstrap.nix to provide LLVM 6, not LLVM 5, to ghc-8.6.X compilers.
6
12
modules/plan.nix+6−1
@@ -101,7 +101,12 @@ let
101 doHyperlinkSource = mkOption {
101 doHyperlinkSource = mkOption {
102 description = "Link documentation to the source code.";
102 description = "Link documentation to the source code.";
103 type = bool;
103 type = bool;
104− default = (def.doHoogle or true);
104+ default = (def.doHyperlinkSource or true);
105+ };
106+ doQuickjump = mkOption {
107+ description = "Generate an index for interactive documentation navigation.";
108+ type = bool;
109+ default = (def.doQuickjump or true);
105 };
110 };
106 dontPatchELF = mkOption {
111 dontPatchELF = mkOption {
107 description = "If set, the patchelf command is not used to remove unnecessary RPATH entries. Only applies to Linux.";
112 description = "If set, the patchelf command is not used to remove unnecessary RPATH entries. Only applies to Linux.";
test/default.nix+3
@@ -187,6 +187,9 @@ let
187 # This test makes a plan for building cabal 3.2 using index-states that will
187 # This test makes a plan for building cabal 3.2 using index-states that will
188 # never work with ghc 8.10.1
188 # never work with ghc 8.10.1
189 index-state = callTest ./index-state {};
189 index-state = callTest ./index-state {};
190+ } // lib.optionalAttrs (!pkgs.haskell-nix.haskellLib.isCrossHost) {
191+ # Haddock is not included with cross compilers currently
192+ sublib-docs = callTest ./sublib-docs { inherit util; };
190 };
193 };
191
194
192 # This is the same as allTests, but filter out all the key/vaules from the
195 # This is the same as allTests, but filter out all the key/vaules from the
test/sublib-docs/Setup.hsnew file+2
@@ -0,0 +1,2 @@
1+import Distribution.Simple
2+main = defaultMain
test/sublib-docs/default.nixnew file+63
@@ -0,0 +1,63 @@
1+# Test a package set
2+{ stdenv, util, cabalProject', haskellLib, recurseIntoAttrs, testSrc }:
3+
4+with stdenv.lib;
5+
6+let
7+ project = cabalProject' {
8+ src = testSrc "sublib-docs";
9+ };
10+
11+ packages = project.hsPkgs;
12+
13+in recurseIntoAttrs {
14+ ifdInputs = {
15+ inherit (project) plan-nix;
16+ };
17+ run = stdenv.mkDerivation {
18+ name = "sublib-docs-test";
19+
20+ buildCommand = ''
21+ exe="${packages.sublib-docs.components.exes.sublib-docs}/bin/sublib-docs${stdenv.hostPlatform.extensions.executable}"
22+
23+ size=$(command stat --format '%s' "$exe")
24+ printf "size of executable $exe is $size. \n" >& 2
25+
26+ # fixme: run on target platform when cross-compiled
27+ printf "checking whether executable runs... " >& 2
28+ cat ${haskellLib.check packages.sublib-docs.components.exes.sublib-docs}
29+
30+ '' +
31+ # Musl and Aarch are statically linked..
32+ optionalString (!stdenv.hostPlatform.isAarch32 && !stdenv.hostPlatform.isAarch64 && !stdenv.hostPlatform.isMusl) (''
33+ printf "checking that executable is dynamically linked to system libraries... " >& 2
34+ '' + optionalString (stdenv.isLinux && !stdenv.hostPlatform.isMusl) ''
35+ ldd $exe | grep libgmp
36+ '' + optionalString stdenv.isDarwin ''
37+ otool -L $exe |grep .dylib
38+ '') + ''
39+
40+ printf "Checking that \"all\" component has the programs... " >& 2
41+ all_exe="${packages.sublib-docs.components.all}/bin/sublib-docs${stdenv.hostPlatform.extensions.executable}"
42+ test -f "$all_exe"
43+ echo "$all_exe" >& 2
44+
45+ # Check that it looks like we have docs
46+ test -f "${packages.sublib-docs.components.library.doc}/share/doc/sublib-docs/html/Lib.html"
47+ test -f "${packages.sublib-docs.components.sublibs.slib.doc}/share/doc/slib/html/Slib.html"
48+
49+ touch $out
50+ '';
51+
52+ meta.platforms = platforms.all;
53+
54+ passthru = {
55+ # Used for debugging with nix repl
56+ inherit packages;
57+
58+ # Used for testing externally with nix-shell (../tests.sh).
59+ # This just adds cabal-install to the existing shells.
60+ test-shell = util.addCabalInstall packages.sublib-docs.components.all;
61+ };
62+ };
63+}
test/sublib-docs/lib/Lib.hsnew file+6
@@ -0,0 +1,6 @@
1+-- | Lib with haddocks
2+module Lib where
3+
4+-- | world string
5+world :: String
6+world = "world"
test/sublib-docs/slib/Slib.hsnew file+6
@@ -0,0 +1,6 @@
1+-- | sublib with haddocks
2+module Slib where
3+
4+-- | hello string
5+hello :: String
6+hello = "Hello"
test/sublib-docs/src/Main.hsnew file+4
@@ -0,0 +1,4 @@
1+module Main where
2+
3+main :: IO ()
4+main = putStrLn "Hello, Haskell!"
test/sublib-docs/sublib-docs.cabalnew file+47
@@ -0,0 +1,47 @@
1+cabal-version: 2.2
2+-- Initial package description 'cabal-simple.cabal' generated by 'cabal
3+-- init'. For further documentation, see
4+-- http://haskell.org/cabal/users-guide/
5+
6+name: sublib-docs
7+version: 0.1.0.0
8+-- synopsis:
9+-- description:
10+-- bug-reports:
11+license: MIT
12+author: Moritz Angermann
13+maintainer: moritz.angermann@iohk.io
14+-- category:
15+build-type: Simple
16+
17+library
18+ exposed-modules: Lib
19+ -- other-modules:
20+ -- other-extensions:
21+ build-depends: base
22+ , slib
23+ -- hs-source-dirs:
24+ default-language: Haskell2010
25+ hs-source-dirs: lib
26+
27+library slib
28+ exposed-modules: Slib
29+ build-depends: extra
30+ , safe
31+ , aeson
32+ , base
33+ default-language: Haskell2010
34+ hs-source-dirs: slib
35+
36+
37+executable sublib-docs
38+ main-is: Main.hs
39+ -- other-modules:
40+ -- other-extensions:
41+ build-depends: base
42+ , sublib-docs
43+ , extra
44+ , optparse-applicative
45+ hs-source-dirs: src
46+ -- hs-source-dirs:
47+ default-language: Haskell2010