Skip to content

Commit 78b0e71

Browse files
committed
refactor: move dummy-ghc-pkg-dump to its own file
1 parent 8bf373b commit 78b0e71

File tree

3 files changed

+253
-220
lines changed

3 files changed

+253
-220
lines changed

lib/call-cabal-project-to-nix.nix

Lines changed: 9 additions & 219 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
{ pkgs, runCommand, cacert, index-state-hashes, haskellLib }:
1+
{ pkgs, cacert, index-state-hashes, haskellLib }:
2+
23
{ name ? src.name or null # optional name for better error messages
34
, src
45
, materialized-dir ? ../materialized
@@ -102,6 +103,7 @@ in let
102103
ghc = if ghc' ? latestVersion
103104
then __trace "WARNING: ${ghc'.version} is out of date, consider using upgrading to ${ghc'.latestVersion}." ghc'
104105
else ghc';
106+
105107
subDir' = src.origSubDir or "";
106108
subDir = pkgs.lib.strings.removePrefix "/" subDir';
107109

@@ -295,8 +297,6 @@ let
295297

296298
fixedProject = replaceSourceRepos rawCabalProject;
297299

298-
ghcSrc = (ghc.raw-src or ghc.buildGHC.raw-src) evalPackages;
299-
300300
platformString = p: with p.parsed; "${cpu.name}-${vendor.name}-${kernel.name}";
301301

302302
# Dummy `ghc` that uses the captured output
@@ -366,222 +366,12 @@ let
366366
'';
367367
};
368368

369-
ghc-pkgs = [
370-
"Cabal"
371-
"array"
372-
"base"
373-
"binary"
374-
"bytestring"
375-
"containers"
376-
"deepseq"
377-
"directory"
378-
"filepath"
379-
"ghc-boot"
380-
"ghc-boot-th"
381-
"ghc-compact"
382-
"ghc-heap"
383-
"ghc-prim"
384-
"ghci"
385-
"integer-gmp"
386-
"mtl"
387-
"parsec"
388-
"pretty"
389-
"process"
390-
"rts"
391-
"template-haskell"
392-
"text"
393-
"time"
394-
"transformers"
395-
] ++ pkgs.lib.optionals (!pkgs.stdenv.targetPlatform.isGhcjs || builtins.compareVersions ghc.version "9.0" > 0) [
396-
# GHCJS 8.10 does not have these
397-
"Cabal-syntax"
398-
"exceptions"
399-
"file-io"
400-
"ghc"
401-
"ghc-bignum"
402-
"ghc-experimental"
403-
"ghc-internal"
404-
"ghc-platform"
405-
"ghc-toolchain"
406-
"haskeline"
407-
"hpc"
408-
"libiserv"
409-
"os-string"
410-
"semaphore-compat"
411-
"stm"
412-
"xhtml"
413-
] ++ pkgs.lib.optionals (!pkgs.stdenv.targetPlatform.isGhcjs) [
414-
"terminfo"
415-
] ++ (if pkgs.stdenv.targetPlatform.isWindows
416-
then [ "Win32" ]
417-
else [ "unix" ]
418-
);
419-
420-
dummy-ghc-pkg-dump = evalPackages.runCommand "dummy-ghc-pkg-dump" {
421-
nativeBuildInputs = [
422-
evalPackages.haskell-nix.nix-tools-unchecked.exes.cabal2json
423-
evalPackages.jq
424-
];
425-
} (let varname = x: builtins.replaceStrings ["-"] ["_"] x; in ''
426-
PACKAGE_VERSION=${ghc.version}
427-
ProjectVersion=${ghc.version}
428-
429-
# The following logic is from GHC m4/setup_project_version.m4
430-
431-
# Split PACKAGE_VERSION into (possibly empty) parts
432-
VERSION_MAJOR=`echo $PACKAGE_VERSION | sed 's/^\([^.]*\)\(\.\{0,1\}\(.*\)\)$/\1'/`
433-
VERSION_TMP=`echo $PACKAGE_VERSION | sed 's/^\([^.]*\)\(\.\{0,1\}\(.*\)\)$/\3'/`
434-
VERSION_MINOR=`echo $VERSION_TMP | sed 's/^\([^.]*\)\(\.\{0,1\}\(.*\)\)$/\1'/`
435-
ProjectPatchLevel=`echo $VERSION_TMP | sed 's/^\([^.]*\)\(\.\{0,1\}\(.*\)\)$/\3'/`
436-
437-
# Calculate project version as an integer, using 2 digits for minor version
438-
case $VERSION_MINOR in
439-
?) ProjectVersionInt=''${VERSION_MAJOR}0''${VERSION_MINOR} ;;
440-
??) ProjectVersionInt=''${VERSION_MAJOR}''${VERSION_MINOR} ;;
441-
*) echo bad minor version in $PACKAGE_VERSION; exit 1 ;;
442-
esac
443-
# AC_SUBST([ProjectVersionInt])
444-
445-
# The project patchlevel is zero unless stated otherwise
446-
test -z "$ProjectPatchLevel" && ProjectPatchLevel=0
447-
448-
# Save split version of ProjectPatchLevel
449-
ProjectPatchLevel1=`echo $ProjectPatchLevel | sed 's/^\([^.]*\)\(\.\{0,1\}\(.*\)\)$/\1/'`
450-
ProjectPatchLevel2=`echo $ProjectPatchLevel | sed 's/^\([^.]*\)\(\.\{0,1\}\(.*\)\)$/\3/'`
451-
452-
# The project patchlevel1/2 is zero unless stated otherwise
453-
test -z "$ProjectPatchLevel1" && ProjectPatchLevel1=0
454-
test -z "$ProjectPatchLevel2" && ProjectPatchLevel2=0
455-
456-
# AC_SUBST([ProjectPatchLevel1])
457-
# AC_SUBST([ProjectPatchLevel2])
458-
459-
# Remove dots from the patch level; this allows us to have versions like 6.4.1.20050508
460-
ProjectPatchLevel=`echo $ProjectPatchLevel | sed 's/\.//'`
461-
462-
# AC_SUBST([ProjectPatchLevel])
463-
464-
# The version of the GHC package changes every day, since the
465-
# patchlevel is the current date. We don't want to force
466-
# recompilation of the entire compiler when this happens, so for
467-
# GHC HEAD we omit the patchlevel from the package version number.
468-
#
469-
# The ProjectPatchLevel1 > 20000000 iff GHC HEAD. If it's for a stable
470-
# release like 7.10.1 or for a release candidate such as 7.10.1.20141224
471-
# then we don't omit the patchlevel components.
472-
473-
ProjectVersionMunged="$ProjectVersion"
474-
if test "$ProjectPatchLevel1" -gt 20000000; then
475-
ProjectVersionMunged="''${VERSION_MAJOR}.''${VERSION_MINOR}"
476-
fi
477-
# AC_SUBST([ProjectVersionMunged])
478-
479-
# The version used for libraries tightly coupled with GHC (e.g.
480-
# ghc-internal) which need a major version bump for every minor/patchlevel
481-
# GHC version.
482-
# Example: for GHC=9.10.1, ProjectVersionForLib=9.1001
483-
#
484-
# Just like with project version munged, we don't want to use the
485-
# patchlevel version which changes every day, so if using GHC HEAD, the
486-
# patchlevel = 00.
487-
case $VERSION_MINOR in
488-
?) ProjectVersionForLibUpperHalf=''${VERSION_MAJOR}.0''${VERSION_MINOR} ;;
489-
??) ProjectVersionForLibUpperHalf=''${VERSION_MAJOR}.''${VERSION_MINOR} ;;
490-
*) echo bad minor version in $PACKAGE_VERSION; exit 1 ;;
491-
esac
492-
# GHC HEAD uses patch level version > 20000000
493-
case $ProjectPatchLevel1 in
494-
?) ProjectVersionForLib=''${ProjectVersionForLibUpperHalf}0''${ProjectPatchLevel1} ;;
495-
??) ProjectVersionForLib=''${ProjectVersionForLibUpperHalf}''${ProjectPatchLevel1} ;;
496-
*) ProjectVersionForLib=''${ProjectVersionForLibUpperHalf}00
497-
esac
498-
499-
PKGS=""
500-
${pkgs.lib.concatStrings
501-
(builtins.map (name: ''
502-
cabal_file=""
503-
if [ -f ${ghcSrc}/libraries/${name}/${name}.cabal ]; then
504-
cabal_file=${ghcSrc}/libraries/${name}/${name}.cabal
505-
elif [ -f ${ghcSrc}/libraries/Cabal/${name}/${name}.cabal ]; then
506-
cabal_file=${ghcSrc}/libraries/Cabal/${name}/${name}.cabal
507-
elif [ -f ${ghcSrc}/libraries/${name}/${name}/${name}.cabal ]; then
508-
cabal_file=${ghcSrc}/libraries/${name}/${name}/${name}.cabal
509-
elif [ -f ${ghcSrc}/compiler/${name}.cabal ]; then
510-
cabal_file=${ghcSrc}/compiler/${name}.cabal
511-
elif [ -f ${ghcSrc}/compiler/${name}.cabal.in ]; then
512-
cabal_file=${ghcSrc}/compiler/${name}.cabal.in
513-
elif [ -f ${ghcSrc}/libraries/${name}/${name}.cabal.in ]; then
514-
cabal_file=${ghcSrc}/libraries/${name}/${name}.cabal.in
515-
fi
516-
if [[ "$cabal_file" != "" ]]; then
517-
fixed_cabal_file=$(mktemp)
518-
cat $cabal_file | sed -e "s/@ProjectVersionMunged@/$ProjectVersionMunged/g" -e "s/@ProjectVersionForLib@/$ProjectVersionForLib/g" -e 's/default: *@[A-Za-z0-9]*@/default: False/g' -e 's/@Suffix@//g' > $fixed_cabal_file
519-
json_cabal_file=$(mktemp)
520-
cabal2json $fixed_cabal_file > $json_cabal_file
521-
522-
exposed_modules="$(jq -r '.library."exposed-modules"[]|select(type=="array")[]' $json_cabal_file)"
523-
reexported_modules="$(jq -r '.library."reexported-modules"//[]|.[]|select(type=="array")[]' $json_cabal_file)"
524-
525-
# FIXME This is a bandaid. Rather than doing this, conditionals should be interpreted.
526-
${pkgs.lib.optionalString pkgs.stdenv.targetPlatform.isGhcjs ''
527-
exposed_modules+=" $(jq -r '.library."exposed-modules"[]|select(type=="object" and .if.arch == "javascript")|.then[]' $json_cabal_file)"
528-
''}
529-
${pkgs.lib.optionalString pkgs.stdenv.targetPlatform.isWindows ''
530-
exposed_modules+=" $(jq -r '.library."exposed-modules"[]|select(type=="object" and .if.os == "windows")|.then[]' $json_cabal_file)"
531-
''}
532-
${pkgs.lib.optionalString (!pkgs.stdenv.targetPlatform.isWindows) ''
533-
exposed_modules+=" $(jq -r '.library."exposed-modules"[]|select(type=="object" and .if.not.os == "windows")|.then[]' $json_cabal_file)"
534-
''}
535-
536-
EXPOSED_MODULES_${varname name}="$(tr '\n' ' ' <<< "$exposed_modules $reexported_modules")"
537-
DEPS_${varname name}="$(jq -r '.library."build-depends"[]|select(type=="array")[],select(type=="object" and .if.not.flag != "vendor-filepath").then[]' $json_cabal_file | sed 's/^\([A-Za-z0-9-]*\).*$/\1/g' | sort -u | tr '\n' ' ')"
538-
VER_${varname name}="$(jq -r '.version' $json_cabal_file)"
539-
PKGS+=" ${name}"
540-
LAST_PKG="${name}"
541-
fi
542-
'') ghc-pkgs)
543-
}
544-
${ # There is no .cabal file for system-cxx-std-lib
545-
pkgs.lib.optionalString (builtins.compareVersions ghc.version "9.2" >= 0) (
546-
let name="system-cxx-std-lib"; in ''
547-
EXPOSED_MODULES_${varname name}=""
548-
DEPS_${varname name}=""
549-
VER_${varname name}="1.0"
550-
PKGS+=" ${name}"
551-
LAST_PKG="${name}"
552-
'')
553-
# ghcjs packages (before the ghc JS backend). TODO remove this when GHC 8.10 support is dropped
554-
+ pkgs.lib.optionalString (pkgs.stdenv.targetPlatform.isGhcjs && builtins.compareVersions ghc.version "9" < 0) ''
555-
EXPOSED_MODULES_${varname "ghcjs-prim"}="GHCJS.Prim GHCJS.Prim.Internal GHCJS.Prim.Internal.Build"
556-
DEPS_${varname "ghcjs-prim"}="base ghc-prim"
557-
VER_${varname "ghcjs-prim"}="0.1.1.0"
558-
EXPOSED_MODULES_${varname "ghcjs-th"}="GHCJS.Prim.TH.Eval GHCJS.Prim.TH.Types"
559-
DEPS_${varname "ghcjs-th"}="base binary bytestring containers ghc-prim ghci template-haskell"
560-
VER_${varname "ghcjs-th"}="0.1.0.0"
561-
PKGS+=" ghcjs-prim ghcjs-th"
562-
LAST_PKG="ghcjs-th"
563-
''
564-
}
565-
for pkg in $PKGS; do
566-
varname="$(echo $pkg | tr "-" "_")"
567-
ver="VER_$varname"
568-
exposed_mods="EXPOSED_MODULES_$varname"
569-
deps="DEPS_$varname"
570-
echo "name: $pkg" >> $out
571-
echo "version: ''${!ver}" >> $out
572-
echo "exposed-modules: ''${!exposed_mods}" >> $out
573-
echo "depends:" >> $out
574-
for dep in ''${!deps}; do
575-
ver_dep="VER_$(echo $dep | tr "-" "_")"
576-
if [[ "''${!ver_dep}" != "" ]]; then
577-
echo " $dep-''${!ver_dep}" >> $out
578-
fi
579-
done
580-
if [[ "$pkg" != "$LAST_PKG" ]]; then
581-
echo '---' >> $out
582-
fi
583-
done
584-
'');
369+
dummy-ghc-pkg-dump = import ./dummy-ghc-pkg-dump.nix {
370+
inherit pkgs evalPackages;
371+
ghc-src = (ghc.raw-src or ghc.buildGHC.raw-src) evalPackages;
372+
ghc-version = ghc.version;
373+
};
374+
585375
# Dummy `ghc-pkg` that uses the captured output
586376
dummy-ghc-pkg = evalPackages.writeTextFile {
587377
name = "dummy-pkg-" + ghc.name;

0 commit comments

Comments
 (0)