on iko/ghcjs-patch-master help sign in
Replace lib.fix with recursive let in builders (#730)
commit128dbef1334728d16d0013fe6b53e81e8d2f7312 authorHamish Mackenzie <Hamish.Mackenzie@iohk.io> dateSat 27 Jun 2020, 22:31 (6 years ago) parent1ce2318
3 files changed+245−252
builder/comp-builder.nix+164−170 builder/haddock-builder.nix+78−79 builder/setup-builder.nix+3−3
builder/comp-builder.nix+164−170
@@ -196,11 +196,6 @@ let
196196 LOCALE_ARCHIVE = "${buildPackages.glibcLocales}/lib/locale/locale-archive";
197197 };
198198
199−in
200−
201−stdenv.lib.fix (drv:
202−
203−let
204199 haddock = haddockBuilder {
205200 inherit componentId component package flags commonConfigureFlags
206201 commonAttrs revision setupGhcOptions doHaddock
@@ -209,174 +204,173 @@ let
209204
210205 componentDrv = drv;
211206 };
212−in
213207
214−stdenv.mkDerivation (commonAttrs // {
215− pname = nameOnly;
216− inherit (package.identifier) version;
208+ drv = stdenv.mkDerivation (commonAttrs // {
209+ pname = nameOnly;
210+ inherit (package.identifier) version;
211+
212+ doCheck = false;
213+ doCrossCheck = false;
214+
215+ inherit dontPatchELF dontStrip;
216+
217+ passthru = {
218+ inherit (package) identifier;
219+ config = component;
220+ inherit configFiles executableToolDepends cleanSrc exeName;
221+ env = shellWrappers;
222+ profiled = self (drvArgs // { enableLibraryProfiling = true; });
223+ } // lib.optionalAttrs (haskellLib.isLibrary componentId) ({
224+ inherit haddock;
225+ inherit (haddock) haddockDir; # This is null if `doHaddock = false`
226+ } // lib.optionalAttrs (haddock ? doc) {
227+ # `doHaddock = false` turns the doc of haddock output off
228+ inherit (haddock) doc;
229+ }
230+ );
217231
218− doCheck = false;
219− doCrossCheck = false;
232+ meta = {
233+ homepage = package.homepage;
234+ description = package.synopsis;
235+ license =
236+ let
237+ license-map = import ../lib/cabal-licenses.nix lib;
238+ in license-map.${package.license} or
239+ (builtins.trace "WARNING: license \"${package.license}\" not found" license-map.LicenseRef-OtherLicense);
240+ platforms = if platforms == null then stdenv.lib.platforms.all else platforms;
241+ };
220242
221− inherit dontPatchELF dontStrip;
243+ propagatedBuildInputs =
244+ frameworks # Frameworks will be needed at link time
245+ # Not sure why pkgconfig needs to be propagatedBuildInputs but
246+ # for gi-gtk-hs it seems to help.
247+ ++ builtins.concatLists pkgconfig;
248+
249+ buildInputs = component.libs
250+ ++ map (d: d.components.library or d) component.depends;
251+
252+ nativeBuildInputs =
253+ [shellWrappers buildPackages.removeReferencesTo]
254+ ++ executableToolDepends;
255+
256+ outputs = ["out" ]
257+ ++ (lib.optional enableSeparateDataOutput "data")
258+ ++ (lib.optional keepSource "source");
259+
260+ configurePhase =
261+ (lib.optionalString keepSource ''
262+ cp -r . $source
263+ cd $source
264+ chmod -R +w .
265+ '') + ''
266+ runHook preConfigure
267+ echo Configure flags:
268+ printf "%q " ${finalConfigureFlags}
269+ echo
270+ $SETUP_HS configure ${finalConfigureFlags}
271+ runHook postConfigure
272+ '';
273+
274+ buildPhase = ''
275+ runHook preBuild
276+ # https://gitlab.haskell.org/ghc/ghc/issues/9221
277+ $SETUP_HS build ${haskellLib.componentTarget componentId} -j$(($NIX_BUILD_CORES > 4 ? 4 : $NIX_BUILD_CORES)) ${lib.concatStringsSep " " (setupBuildFlags ++ setupGhcOptions)}
278+ runHook postBuild
279+ '';
280+
281+ checkPhase = "notice: Tests are only executed by building the .run sub-derivation of this component.";
282+
283+ # Note: Cabal does *not* copy test executables during the `install` phase.
284+ #
285+ # Note 2: if a package contains multiple libs (lib + sublibs) SETUP register will generate a
286+ # folder isntead of a file for the configuration. Therfore if the result is a folder,
287+ # we need to register each and every element of that folder.
288+ #
289+ # Note 3: if a package has no libs SETUP will not generate anything. This can
290+ # happen when building the `all` component of a package.
291+ installPhase = let
292+ target-pkg-and-db = "${ghc.targetPrefix}ghc-pkg -v0 --package-db $out/package.conf.d";
293+ in ''
294+ runHook preInstall
295+ $SETUP_HS copy ${lib.concatStringsSep " " setupInstallFlags}
296+ ${lib.optionalString (haskellLib.isLibrary componentId || haskellLib.isAll componentId) ''
297+ $SETUP_HS register --gen-pkg-config=${name}.conf
298+ ${ghc.targetPrefix}ghc-pkg -v0 init $out/package.conf.d
299+ if [ -d "${name}.conf" ]; then
300+ for pkg in ${name}.conf/*; do
301+ ${ghc.targetPrefix}ghc-pkg -v0 --package-db ${configFiles}/${configFiles.packageCfgDir} -f $out/package.conf.d register "$pkg"
302+ done
303+ elif [ -e "${name}.conf" ]; then
304+ ${ghc.targetPrefix}ghc-pkg -v0 --package-db ${configFiles}/${configFiles.packageCfgDir} -f $out/package.conf.d register ${name}.conf
305+ fi
222306
223− passthru = {
224− inherit (package) identifier;
225− config = component;
226− inherit configFiles executableToolDepends cleanSrc exeName;
227− env = shellWrappers;
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− }
236− );
237−
238− meta = {
239− homepage = package.homepage;
240− description = package.synopsis;
241− license =
242− let
243− license-map = import ../lib/cabal-licenses.nix lib;
244− in license-map.${package.license} or
245− (builtins.trace "WARNING: license \"${package.license}\" not found" license-map.LicenseRef-OtherLicense);
246− platforms = if platforms == null then stdenv.lib.platforms.all else platforms;
247− };
307+ mkdir -p $out/exactDep
308+ touch $out/exactDep/configure-flags
309+ touch $out/exactDep/cabal.config
310+
311+ if id=$(${target-pkg-and-db} field ${package.identifier.name} id --simple-output); then
312+ echo "--dependency=${package.identifier.name}=$id" >> $out/exactDep/configure-flags
313+ elif id=$(${target-pkg-and-db} field "z-${package.identifier.name}-z-*" id --simple-output); then
314+ name=$(${target-pkg-and-db} field "z-${package.identifier.name}-z-*" name --simple-output)
315+ # so we are dealing with a sublib. As we build sublibs separately, the above
316+ # query should be safe.
317+ echo "--dependency=''${name#z-${package.identifier.name}-z-}=$id" >> $out/exactDep/configure-flags
318+ fi
319+ if ver=$(${target-pkg-and-db} field ${package.identifier.name} version --simple-output); then
320+ echo "constraint: ${package.identifier.name} == $ver" >> $out/exactDep/cabal.config
321+ echo "constraint: ${package.identifier.name} installed" >> $out/exactDep/cabal.config
322+ fi
248323
249− propagatedBuildInputs =
250− frameworks # Frameworks will be needed at link time
251− # Not sure why pkgconfig needs to be propagatedBuildInputs but
252− # for gi-gtk-hs it seems to help.
253− ++ builtins.concatLists pkgconfig;
254−
255− buildInputs = component.libs
256− ++ map (d: d.components.library or d) component.depends;
257−
258− nativeBuildInputs =
259− [shellWrappers buildPackages.removeReferencesTo]
260− ++ executableToolDepends;
261−
262− outputs = ["out" ]
263− ++ (lib.optional enableSeparateDataOutput "data")
264− ++ (lib.optional keepSource "source");
265−
266− configurePhase =
267− (lib.optionalString keepSource ''
268− cp -r . $source
269− cd $source
270− chmod -R +w .
271− '') + ''
272− runHook preConfigure
273− echo Configure flags:
274− printf "%q " ${finalConfigureFlags}
275− echo
276− $SETUP_HS configure ${finalConfigureFlags}
277− runHook postConfigure
278− '';
279−
280− buildPhase = ''
281− runHook preBuild
282− # https://gitlab.haskell.org/ghc/ghc/issues/9221
283− $SETUP_HS build ${haskellLib.componentTarget componentId} -j$(($NIX_BUILD_CORES > 4 ? 4 : $NIX_BUILD_CORES)) ${lib.concatStringsSep " " (setupBuildFlags ++ setupGhcOptions)}
284− runHook postBuild
285− '';
286−
287− checkPhase = "notice: Tests are only executed by building the .run sub-derivation of this component.";
288−
289− # Note: Cabal does *not* copy test executables during the `install` phase.
290− #
291− # Note 2: if a package contains multiple libs (lib + sublibs) SETUP register will generate a
292− # folder isntead of a file for the configuration. Therfore if the result is a folder,
293− # we need to register each and every element of that folder.
294− #
295− # Note 3: if a package has no libs SETUP will not generate anything. This can
296− # happen when building the `all` component of a package.
297− installPhase = let
298− target-pkg-and-db = "${ghc.targetPrefix}ghc-pkg -v0 --package-db $out/package.conf.d";
299− in ''
300− runHook preInstall
301− $SETUP_HS copy ${lib.concatStringsSep " " setupInstallFlags}
302− ${lib.optionalString (haskellLib.isLibrary componentId || haskellLib.isAll componentId) ''
303− $SETUP_HS register --gen-pkg-config=${name}.conf
304− ${ghc.targetPrefix}ghc-pkg -v0 init $out/package.conf.d
305− if [ -d "${name}.conf" ]; then
306− for pkg in ${name}.conf/*; do
307− ${ghc.targetPrefix}ghc-pkg -v0 --package-db ${configFiles}/${configFiles.packageCfgDir} -f $out/package.conf.d register "$pkg"
308− done
309− elif [ -e "${name}.conf" ]; then
310− ${ghc.targetPrefix}ghc-pkg -v0 --package-db ${configFiles}/${configFiles.packageCfgDir} -f $out/package.conf.d register ${name}.conf
311− fi
312−
313− mkdir -p $out/exactDep
314− touch $out/exactDep/configure-flags
315− touch $out/exactDep/cabal.config
316−
317− if id=$(${target-pkg-and-db} field ${package.identifier.name} id --simple-output); then
318− echo "--dependency=${package.identifier.name}=$id" >> $out/exactDep/configure-flags
319− elif id=$(${target-pkg-and-db} field "z-${package.identifier.name}-z-*" id --simple-output); then
320− name=$(${target-pkg-and-db} field "z-${package.identifier.name}-z-*" name --simple-output)
321− # so we are dealing with a sublib. As we build sublibs separately, the above
322− # query should be safe.
323− echo "--dependency=''${name#z-${package.identifier.name}-z-}=$id" >> $out/exactDep/configure-flags
324− fi
325− if ver=$(${target-pkg-and-db} field ${package.identifier.name} version --simple-output); then
326− echo "constraint: ${package.identifier.name} == $ver" >> $out/exactDep/cabal.config
327− echo "constraint: ${package.identifier.name} installed" >> $out/exactDep/cabal.config
328− fi
329−
330− touch $out/envDep
331− if id=$(${target-pkg-and-db} field ${package.identifier.name} id --simple-output); then
332− echo "package-id $id" >> $out/envDep
333− fi
334− ''}
335− ${(lib.optionalString (haskellLib.isTest componentId || haskellLib.isBenchmark componentId || haskellLib.isAll componentId) ''
336− mkdir -p $out/bin
337− if [ -f ${testExecutable} ]; then
338− mkdir -p $(dirname $out/bin/${exeName})
339− ${if stdenv.hostPlatform.isGhcjs then ''
340− cat <(echo \#!${lib.getBin buildPackages.nodejs}/bin/node) ${testExecutable} >| $out/bin/${exeName}
341− chmod +x $out/bin/${exeName}
342− '' else ''
343− cp -r ${testExecutable} $(dirname $out/bin/${exeName})
344− ''}
345− fi
346− '')
347− # In case `setup copy` did not creat this
348− + (lib.optionalString enableSeparateDataOutput "mkdir -p $data")
349− + (lib.optionalString (stdenv.hostPlatform.isWindows && (haskellLib.mayHaveExecutable componentId)) ''
350− echo "Symlink libffi and gmp .dlls ..."
351− for p in ${lib.concatStringsSep " " [ libffi gmp ]}; do
352− find "$p" -iname '*.dll' -exec ln -s {} $out/bin \;
353− done
354− # symlink all .dlls into the local directory.
355− # we ask ghc-pkg for *all* dynamic-library-dirs and then iterate over the unique set
356− # to symlink over dlls as needed.
357− echo "Symlink library dependencies..."
358− 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
359− if [ -d "$libdir" ]; then
360− find "$libdir" -iname '*.dll' -exec ln -s {} $out/bin \;
324+ touch $out/envDep
325+ if id=$(${target-pkg-and-db} field ${package.identifier.name} id --simple-output); then
326+ echo "package-id $id" >> $out/envDep
361327 fi
362− done
363− '')
364− }
365− runHook postInstall
366− '' + (lib.optionalString keepSource ''
367− rm -rf dist
368− '');
369−
370− shellHook = ''
371− export PATH="${shellWrappers}/bin:$PATH"
372− ${shellHookApplied}
373− '';
374−}
375−// haskellLib.optionalHooks {
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
379− preBuild postBuild
380− preInstall postInstall;
381−}
382−)); in self)
328+ ''}
329+ ${(lib.optionalString (haskellLib.isTest componentId || haskellLib.isBenchmark componentId || haskellLib.isAll componentId) ''
330+ mkdir -p $out/bin
331+ if [ -f ${testExecutable} ]; then
332+ mkdir -p $(dirname $out/bin/${exeName})
333+ ${if stdenv.hostPlatform.isGhcjs then ''
334+ cat <(echo \#!${lib.getBin buildPackages.nodejs}/bin/node) ${testExecutable} >| $out/bin/${exeName}
335+ chmod +x $out/bin/${exeName}
336+ '' else ''
337+ cp -r ${testExecutable} $(dirname $out/bin/${exeName})
338+ ''}
339+ fi
340+ '')
341+ # In case `setup copy` did not creat this
342+ + (lib.optionalString enableSeparateDataOutput "mkdir -p $data")
343+ + (lib.optionalString (stdenv.hostPlatform.isWindows && (haskellLib.mayHaveExecutable componentId)) ''
344+ echo "Symlink libffi and gmp .dlls ..."
345+ for p in ${lib.concatStringsSep " " [ libffi gmp ]}; do
346+ find "$p" -iname '*.dll' -exec ln -s {} $out/bin \;
347+ done
348+ # symlink all .dlls into the local directory.
349+ # we ask ghc-pkg for *all* dynamic-library-dirs and then iterate over the unique set
350+ # to symlink over dlls as needed.
351+ echo "Symlink library dependencies..."
352+ 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
353+ if [ -d "$libdir" ]; then
354+ find "$libdir" -iname '*.dll' -exec ln -s {} $out/bin \;
355+ fi
356+ done
357+ '')
358+ }
359+ runHook postInstall
360+ '' + (lib.optionalString keepSource ''
361+ rm -rf dist
362+ '');
363+
364+ shellHook = ''
365+ export PATH="${shellWrappers}/bin:$PATH"
366+ ${shellHookApplied}
367+ '';
368+ }
369+ // haskellLib.optionalHooks {
370+ # These are the hooks that are not needed by haddock (see commonAttrs for the ones that
371+ # are shared with the haddock derivation)
372+ inherit
373+ preBuild postBuild
374+ preInstall postInstall;
375+ });
376+in drv; in self)
builder/haddock-builder.nix+78−79
@@ -56,89 +56,88 @@ let
5656 configFiles = docsConfigFiles;
5757 };
5858
59−in stdenv.lib.fix (drv: stdenv.mkDerivation (commonAttrs // {
60− name = fullName;
59+ drv = stdenv.mkDerivation (commonAttrs // {
60+ name = fullName;
6161
62− passthru = {
63− configFiles = docsConfigFiles;
62+ passthru = {
63+ configFiles = docsConfigFiles;
6464
65− # The directory containing the haddock documentation.
66− haddockDir = if doHaddock' then "${docdir drv.doc}/html" else null;
67− };
65+ # The directory containing the haddock documentation.
66+ haddockDir = if doHaddock' then "${docdir drv.doc}/html" else null;
67+ };
6868
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"]
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"]
7373 ++ lib.optional doHaddock' "doc";
7474
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
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
138101 '';
139−}
140−// haskellLib.optionalHooks {
141− inherit preHaddock postHaddock;
142−}
143−))
144102
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+in drv
builder/setup-builder.nix+3−3
@@ -32,8 +32,7 @@ let
3232 else [c]) component.build-tools) ++
3333 lib.optional (component.pkgconfig != []) pkgconfig;
3434
35−in
36− stdenv.lib.fix (drv:
35+ drv =
3736 stdenv.mkDerivation ({
3837 name = "${ghc.targetPrefix}${fullName}";
3938 src = cleanSrc;
@@ -86,4 +85,5 @@ in
8685 }
8786 // (lib.optionalAttrs (patches != []) { patches = map (p: if builtins.isFunction p then p { inherit (package.identifier) version; inherit revision; } else p) patches; })
8887 // hooks
89− ))
88+ );
89+in drv