generated from coulomb/repo-seed
fix(nix): split inter-hub-models into two Cabal library components
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
GHC 9.10.3 crashes with Data.Binary.Get.runGet at position 287686318
invariantly when compiling all 476 inter-hub-models modules in a single
--make invocation. Split into two library components to force two
separate GHC compilations:
models-inner (~63 modules): Generated.ActualTypes.* + Generated.Enums
Pure type definitions; zero inter-hub-models dependencies.
main library (~413 modules): entity ops + Include instances
Depends on models-inner.
Longer-term this is the right architecture: explicit boundaries reduce
build cost, isolate changes, and make diagnostics cheaper.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
174
flake.nix
174
flake.nix
@@ -110,42 +110,156 @@
|
|||||||
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: {
|
||||||
# Root cause: "module M" re-export syntax in IHP-generated hubs
|
# GHC 9.10.3 crash: Data.Binary.Get.runGet at position 287686318.
|
||||||
# causes GHC to embed the FULL interface of M into the hub's .hi.
|
# Invariant regardless of flags. Workaround: split the 476-module
|
||||||
# Generated.ActualTypes uses "module M" for 61 sub-modules; the
|
# inter-hub-models into two Cabal library components so GHC runs
|
||||||
# resulting ActualTypes.hi hits the GHC 9.10.3 Data.Binary.Get
|
# two separate --make invocations instead of one giant one.
|
||||||
# 274 MB limit (crashes at position 287686318: not enough bytes)
|
#
|
||||||
# when WidgetVersionInclude reads it back. Same pattern applied to
|
# models-inner (~63 modules): Generated.ActualTypes.* + Enums.
|
||||||
# Generated.Types (119 entity re-exports) — made into empty stub
|
# Pure type definitions; no inter-hub-models deps.
|
||||||
# with direct imports in inter-hub-lib instead.
|
# main library (~413 modules): entity ops + Include instances.
|
||||||
# Fix for ActualTypes: remove the explicit (module M, ...) export
|
# Depends on models-inner.
|
||||||
# list so GHC stores compact name-reference entries in the .hi.
|
#
|
||||||
|
# Long-term intent: explicit module boundaries reduce build cost,
|
||||||
|
# isolate changes, and make diagnostics cheaper across the board.
|
||||||
configureFlags = (old.configureFlags or []) ++ [
|
configureFlags = (old.configureFlags or []) ++ [
|
||||||
"--ghc-option=-O0"
|
"--ghc-option=-O0"
|
||||||
"--ghc-option=-fomit-interface-pragmas"
|
"--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"
|
|
||||||
printf '%s\n' 'module Generated.Types () where' > "$_types"
|
|
||||||
|
|
||||||
# Remove Generated.Types from exposed-modules:
|
|
||||||
# reduces HPT entry count by 1 (476 instead of 477).
|
|
||||||
_cabal=$(ls "$sourceRoot"/*.cabal | head -1)
|
_cabal=$(ls "$sourceRoot"/*.cabal | head -1)
|
||||||
awk '/Generated\.Types$/ && !/TypesPart/{next} {print}' \
|
_pname=$(grep '^name:' "$_cabal" | awk '{print $2}')
|
||||||
"$_cabal" > "$_cabal.new"
|
|
||||||
mv "$_cabal.new" "$_cabal"
|
# Classify exposed-modules into inner vs outer.
|
||||||
|
# Inner: Generated.ActualTypes.X (capital X) and Generated.Enums
|
||||||
|
# — these have zero inter-hub-models dependencies.
|
||||||
|
# Outer: everything else except Generated.Types (empty stub).
|
||||||
|
_inner=$(awk '
|
||||||
|
/^ exposed-modules:/{e=1;next}
|
||||||
|
e && /^ /{m=$1;
|
||||||
|
if (m~/^Generated\.ActualTypes\.[A-Z]/||m=="Generated.Enums")
|
||||||
|
print m;
|
||||||
|
next}
|
||||||
|
e{e=0}
|
||||||
|
' "$_cabal")
|
||||||
|
_outer=$(awk '
|
||||||
|
/^ exposed-modules:/{e=1;next}
|
||||||
|
e && /^ /{m=$1;
|
||||||
|
if (!(m~/^Generated\.ActualTypes\.[A-Z]/) &&
|
||||||
|
m!="Generated.Enums" && m!="Generated.Types")
|
||||||
|
print m;
|
||||||
|
next}
|
||||||
|
e{e=0}
|
||||||
|
' "$_cabal")
|
||||||
|
|
||||||
|
# Rewrite the cabal file with two library stanzas.
|
||||||
|
# Hard-coded deps/extensions match IHP default.nix template
|
||||||
|
# (pinned flake — these won't drift without a flake update).
|
||||||
|
cat > "$_cabal" <<CABAL_EOF
|
||||||
|
cabal-version: 2.2
|
||||||
|
name: $_pname
|
||||||
|
version: 0.1.0
|
||||||
|
build-type: Simple
|
||||||
|
|
||||||
|
library models-inner
|
||||||
|
default-language: GHC2021
|
||||||
|
hs-source-dirs: build
|
||||||
|
build-depends:
|
||||||
|
base
|
||||||
|
, ihp
|
||||||
|
, basic-prelude
|
||||||
|
, text
|
||||||
|
, bytestring
|
||||||
|
, time
|
||||||
|
, uuid
|
||||||
|
, aeson
|
||||||
|
, postgresql-simple
|
||||||
|
, deepseq
|
||||||
|
, data-default
|
||||||
|
, scientific
|
||||||
|
, string-conversions
|
||||||
|
, hasql
|
||||||
|
, hasql-dynamic-statements
|
||||||
|
, hasql-implicits
|
||||||
|
, hasql-mapping
|
||||||
|
, hasql-postgresql-types
|
||||||
|
, hasql-pool
|
||||||
|
, unordered-containers
|
||||||
|
, postgresql-types
|
||||||
|
exposed-modules:
|
||||||
|
$(echo "$_inner" | sed 's/^/ /')
|
||||||
|
default-extensions:
|
||||||
|
OverloadedStrings
|
||||||
|
NoImplicitPrelude
|
||||||
|
ImplicitParams
|
||||||
|
TypeSynonymInstances
|
||||||
|
FlexibleInstances
|
||||||
|
FlexibleContexts
|
||||||
|
InstanceSigs
|
||||||
|
MultiParamTypeClasses
|
||||||
|
TypeFamilies
|
||||||
|
DataKinds
|
||||||
|
TypeOperators
|
||||||
|
UndecidableInstances
|
||||||
|
ConstraintKinds
|
||||||
|
StandaloneDeriving
|
||||||
|
DuplicateRecordFields
|
||||||
|
OverloadedLabels
|
||||||
|
OverloadedRecordDot
|
||||||
|
ghc-options: -Wno-unused-imports -Wno-dodgy-imports -Wno-unused-matches
|
||||||
|
|
||||||
|
library
|
||||||
|
default-language: GHC2021
|
||||||
|
hs-source-dirs: build
|
||||||
|
build-depends:
|
||||||
|
$_pname:models-inner
|
||||||
|
, base
|
||||||
|
, ihp
|
||||||
|
, basic-prelude
|
||||||
|
, text
|
||||||
|
, bytestring
|
||||||
|
, time
|
||||||
|
, uuid
|
||||||
|
, aeson
|
||||||
|
, postgresql-simple
|
||||||
|
, deepseq
|
||||||
|
, data-default
|
||||||
|
, scientific
|
||||||
|
, string-conversions
|
||||||
|
, hasql
|
||||||
|
, hasql-dynamic-statements
|
||||||
|
, hasql-implicits
|
||||||
|
, hasql-mapping
|
||||||
|
, hasql-postgresql-types
|
||||||
|
, hasql-pool
|
||||||
|
, unordered-containers
|
||||||
|
, postgresql-types
|
||||||
|
exposed-modules:
|
||||||
|
$(echo "$_outer" | sed 's/^/ /')
|
||||||
|
default-extensions:
|
||||||
|
OverloadedStrings
|
||||||
|
NoImplicitPrelude
|
||||||
|
ImplicitParams
|
||||||
|
TypeSynonymInstances
|
||||||
|
FlexibleInstances
|
||||||
|
FlexibleContexts
|
||||||
|
InstanceSigs
|
||||||
|
MultiParamTypeClasses
|
||||||
|
TypeFamilies
|
||||||
|
DataKinds
|
||||||
|
TypeOperators
|
||||||
|
UndecidableInstances
|
||||||
|
ConstraintKinds
|
||||||
|
StandaloneDeriving
|
||||||
|
DuplicateRecordFields
|
||||||
|
OverloadedLabels
|
||||||
|
OverloadedRecordDot
|
||||||
|
ghc-options: -Wno-unused-imports -Wno-dodgy-imports -Wno-unused-matches
|
||||||
|
CABAL_EOF
|
||||||
|
|
||||||
|
# Stub out Generated.Types (kept as file for inter-hub-lib)
|
||||||
|
printf '%s\n' 'module Generated.Types () where' \
|
||||||
|
> "$sourceRoot/build/Generated/Types.hs"
|
||||||
'';
|
'';
|
||||||
})
|
})
|
||||||
else if (args.pname or "") == "inter-hub-lib"
|
else if (args.pname or "") == "inter-hub-lib"
|
||||||
|
|||||||
Reference in New Issue
Block a user