generated from coulomb/repo-seed
fix(nix): strip module-M re-export syntax from Generated.ActualTypes
Some checks failed
Build and Deploy / build-push-deploy (push) Has been cancelled
Some checks failed
Build and Deploy / build-push-deploy (push) Has been cancelled
Generated.ActualTypes uses "module M" for 61 sub-modules, causing GHC to embed each sub-interface verbatim into ActualTypes.hi. That file hits the GHC 9.10.3 Data.Binary.Get 274 MB limit (position 287686318) when WidgetVersionInclude reads it during inter-hub-models compilation. Removing the explicit (module M, ...) export list keeps the same re-export semantics (no explicit list = export all imports) but forces GHC to store compact name-reference entries instead of embedded copies. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
102
flake.nix
102
flake.nix
@@ -110,74 +110,68 @@
|
|||||||
let drv = hprev.mkDerivation args;
|
let drv = hprev.mkDerivation args;
|
||||||
in if (args.pname or "") == "inter-hub-models"
|
in if (args.pname or "") == "inter-hub-models"
|
||||||
then drv.overrideAttrs (old: {
|
then drv.overrideAttrs (old: {
|
||||||
# 8-way split: ~15 entities per TypesPart → ~144 MB .hi each.
|
# Root cause: "module M" re-export syntax in IHP-generated hubs
|
||||||
# Root cause: any re-export hub for 119 IHP entities produces
|
# causes GHC to embed the FULL interface of M into the hub's .hi.
|
||||||
# a .hi file ≥ 287 MB (the GHC 9.10.3 Data.Binary.Get limit).
|
# Generated.ActualTypes uses "module M" for 61 sub-modules; the
|
||||||
# Generated.Types is replaced with an empty stub and removed
|
# resulting ActualTypes.hi hits the GHC 9.10.3 Data.Binary.Get
|
||||||
# from exposed-modules; inter-hub-lib imports TypesPart1-8 directly.
|
# 274 MB limit (crashes at position 287686318: not enough bytes)
|
||||||
# -O0 strips unfoldings/specialisations for additional size reduction.
|
# when WidgetVersionInclude reads it back. Same pattern applied to
|
||||||
configureFlags = (old.configureFlags or []) ++ [ "--ghc-option=-O0" ];
|
# Generated.Types (119 entity re-exports) — made into empty stub
|
||||||
|
# with direct imports in inter-hub-lib instead.
|
||||||
|
# Fix for ActualTypes: remove the explicit (module M, ...) export
|
||||||
|
# list so GHC stores compact name-reference entries in the .hi.
|
||||||
|
configureFlags = (old.configureFlags or []) ++ [
|
||||||
|
"--ghc-option=-O0"
|
||||||
|
"--ghc-option=-fomit-interface-pragmas"
|
||||||
|
];
|
||||||
postUnpack = (old.postUnpack or "") + ''
|
postUnpack = (old.postUnpack or "") + ''
|
||||||
|
# Strip "module M" re-export syntax from Generated.ActualTypes.
|
||||||
|
# With 61 "module M" entries GHC embeds every sub-interface
|
||||||
|
# into ActualTypes.hi, producing a file that hits the GHC 9.10.3
|
||||||
|
# Data.Binary.Get 274 MB limit (crashes at position 287686318)
|
||||||
|
# when WidgetVersionInclude reads it. Removing the explicit
|
||||||
|
# export list keeps the module semantically identical (all
|
||||||
|
# imports are still re-exported) but forces GHC to use
|
||||||
|
# compact name-reference entries instead of embedded copies.
|
||||||
|
_actual="$sourceRoot/build/Generated/ActualTypes.hs"
|
||||||
|
awk '/^module Generated\.ActualTypes /{print "module Generated.ActualTypes where"; next} {print}' \
|
||||||
|
"$_actual" > "$_actual.new" && mv "$_actual.new" "$_actual"
|
||||||
|
|
||||||
_types="$sourceRoot/build/Generated/Types.hs"
|
_types="$sourceRoot/build/Generated/Types.hs"
|
||||||
|
|
||||||
# Create TypesPart1-8: 8-way split, ~15 entities each, ~144 MB .hi
|
|
||||||
for _k in 1 2 3 4 5 6 7 8; do
|
|
||||||
awk -v K=$_k 'BEGIN{n=0; N=8}
|
|
||||||
/^import Generated\./{n++; mods[n]=$2}
|
|
||||||
END{
|
|
||||||
q_prev = (K==1) ? 0 : int((K-1)*n/N)+1
|
|
||||||
q_curr = (K==N) ? n : int(K*n/N)+1
|
|
||||||
s = q_prev+1; e = q_curr
|
|
||||||
print "module Generated.TypesPart" K " ("
|
|
||||||
for(i=s;i<=e;i++){
|
|
||||||
if(i<e) print " module " mods[i] ","
|
|
||||||
else print " module " mods[i]
|
|
||||||
}
|
|
||||||
print " ) where"
|
|
||||||
for(i=s;i<=e;i++) print "import " mods[i]
|
|
||||||
}' "$_types" > "$sourceRoot/build/Generated/TypesPart''${_k}.hs"
|
|
||||||
done
|
|
||||||
|
|
||||||
# Empty stub: Generated.Types is NOT a re-export hub.
|
|
||||||
# Re-exporting all 119 entities would produce ~1.1 GB .hi,
|
|
||||||
# crashing GHC when any downstream module reads it.
|
|
||||||
# inter-hub-lib imports TypesPart1-8 directly instead.
|
|
||||||
printf '%s\n' 'module Generated.Types () where' > "$_types"
|
printf '%s\n' 'module Generated.Types () where' > "$_types"
|
||||||
|
|
||||||
# Update cabal: add TypesPart1-8, remove bare Generated.Types
|
# Remove Generated.Types from exposed-modules:
|
||||||
# (empty stub is kept as a file but not exposed/compiled).
|
# reduces HPT entry count by 1 (476 instead of 477).
|
||||||
# 8-space indent required — 4-space is a new stanza field.
|
|
||||||
_cabal=$(ls "$sourceRoot"/*.cabal | head -1)
|
_cabal=$(ls "$sourceRoot"/*.cabal | head -1)
|
||||||
if ! grep -q 'Generated\.TypesPart1' "$_cabal"; then
|
awk '/Generated\.Types$/ && !/TypesPart/{next} {print}' \
|
||||||
awk '/Generated\.Types$/ && !/TypesPart/{next}
|
"$_cabal" > "$_cabal.new"
|
||||||
/^ exposed-modules:/{
|
mv "$_cabal.new" "$_cabal"
|
||||||
print " ghc-options: -O0"
|
|
||||||
print; next
|
|
||||||
}
|
|
||||||
/Generated\.LearningInsightInclude/{
|
|
||||||
print
|
|
||||||
for(k=1;k<=8;k++) print " Generated.TypesPart" k
|
|
||||||
next
|
|
||||||
}
|
|
||||||
{print}' "$_cabal" > "$_cabal.new"
|
|
||||||
mv "$_cabal.new" "$_cabal"
|
|
||||||
fi
|
|
||||||
'';
|
'';
|
||||||
})
|
})
|
||||||
else if (args.pname or "") == "inter-hub-lib"
|
else if (args.pname or "") == "inter-hub-lib"
|
||||||
then drv.overrideAttrs (old: {
|
then drv.overrideAttrs (old: {
|
||||||
# Generated.Types is an empty stub in models (no re-export hub).
|
# Generated.Types is an empty stub in models — no re-export hub.
|
||||||
# Replace every bare `import Generated.Types` with 8 TypesPart imports
|
# Replace every bare `import Generated.Types` with direct imports
|
||||||
# so app modules get all entity types without touching a huge .hi file.
|
# of all 119 individual entity modules (read from the original
|
||||||
|
# Generated/Types.hs before it was replaced in models postUnpack —
|
||||||
|
# each package gets its own unpacked sourceRoot, so Types.hs is
|
||||||
|
# still intact here). Individual entity .hi files are ~9 MB each.
|
||||||
postUnpack = (old.postUnpack or "") + ''
|
postUnpack = (old.postUnpack or "") + ''
|
||||||
find "$sourceRoot" -name "*.hs" | while read _f; do
|
_types="$sourceRoot/build/Generated/Types.hs"
|
||||||
|
_imp=$(mktemp)
|
||||||
|
awk '/^import Generated\./{print "import " $2}' "$_types" > "$_imp"
|
||||||
|
find "$sourceRoot" -name "*.hs" | while IFS= read -r _f; do
|
||||||
if grep -qE "^import Generated\.Types$" "$_f"; then
|
if grep -qE "^import Generated\.Types$" "$_f"; then
|
||||||
awk '/^import Generated\.Types$/{
|
awk -v imp="$_imp" '
|
||||||
for(k=1;k<=8;k++) print "import Generated.TypesPart" k
|
/^import Generated\.Types$/{
|
||||||
|
while ((getline ln < imp) > 0) print ln
|
||||||
|
close(imp)
|
||||||
next
|
next
|
||||||
}{print}' "$_f" > "$_f.new" && mv "$_f.new" "$_f"
|
}
|
||||||
|
{ print }' "$_f" > "$_f.new" && mv "$_f.new" "$_f"
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
rm -f "$_imp"
|
||||||
'';
|
'';
|
||||||
})
|
})
|
||||||
else drv;
|
else drv;
|
||||||
|
|||||||
Reference in New Issue
Block a user