Skip to content

Refactor nix/lib.nix and cache hatter for iOS/watchOS#215

Merged
jappeace merged 9 commits intojappeace:developfrom
jappeace-sloth:combined-refactor-and-ios-cache
Apr 26, 2026
Merged

Refactor nix/lib.nix and cache hatter for iOS/watchOS#215
jappeace merged 9 commits intojappeace:developfrom
jappeace-sloth:combined-refactor-and-ios-cache

Conversation

@jappeace-sloth
Copy link
Copy Markdown

Summary

  • Combines Refactor nix/lib.nix: deduplicate builders #213 (lib.nix deduplication) and Build hatter as cached cabal package for iOS/watchOS #214 (iOS/watchOS cached hatter package) into a single PR
  • nix/lib.nix: Extract shared data lists, merge mkIOSLib+mkWatchOSLib into parameterised mkAppleStaticLib, merge simulator functions, replace 14 repetitive NDK blocks with map995 → ~700 lines (30% reduction)
  • ios-deps.nix: Build hatter as a callCabal2nix package so .a and package DB are cached
  • mkAppleStaticLib: When crossDeps is provided, only compile Main.hs + run_main.c instead of all 22 modules + 19 C sources
  • Adding a new bridge module now means editing 1 list, not 6+ places

Supersedes #213 and #214.

Test plan

  • nix-instantiate --parse passes on all modified files
  • nix-instantiate --eval confirms all 6 public functions exported
  • CI (full nix-build — Apple targets need macOS runners)

🤖 Generated with Claude Code

jappeace-sloth and others added 9 commits April 19, 2026 18:56
Eliminate every fromIntegral call (70+) across 20 files by using
explicit unwitch conversion functions. This makes numeric type
conversions self-documenting and catches unsafe casts at compile time.

Conversion patterns used:
- Int32 ↔ CInt: Int32.toCInt / CInt.toInt32 (total)
- CInt → Int: CInt.toInt (total, for IntMap keys and BS lengths)
- Int → CInt: Int.toCInt with maybe 0 id (partial)
- Int → Word8: Int.toWord8 with maybe 0 id (partial, hex parsing)
- Word8 → Int/Double: Word8.toInt / Word8.toDouble (total)
- Int32 → Int (IntMap keys): CInt.toInt . Int32.toCInt (total chain,
  avoids Int32.toInt which returns Maybe due to Haskell spec)
- Int32/CInt → Double: Int32.toDouble / CInt.toDouble (total)

Added unwitch 2.2.0 to cabal deps (library, test-suite, redraw-demo)
and to both nix overlays (hpkgs.nix for native, cross-deps.nix for
Android cross-compilation).

Prompt: replace all primitive conversions in hatter with unwitch

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
iOS and watchOS use ios-deps.nix (native macOS GHC) rather than
cross-deps.nix (Android cross-GHC). The unwitch package was missing
from the iOS/watchOS haskellPackages overlay, causing "Could not find
module Unwitch.Convert.*" errors in CI.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
mkIOSLib compiles hatter with raw ghc -staticlib, not through cabal,
so its non-boot dependencies must be explicitly provided in the
crossDeps package DB. Before unwitch, hatter only used GHC boot
packages (base, containers, text, etc.). Now it also needs unwitch.

Add hatterOwnDeps list to ios-deps.nix so the unwitch .a/.hi/.conf
are collected even when no consumerCabalFile is provided (as in CI).
This fixes iOS and watchOS builds which both use ios-deps.nix.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
collect-deps.nix only processes packages explicitly in its deps list —
it doesn't follow propagatedBuildInputs. Since hatter's .conf now
references unwitch, unwitch's .a and .conf must also be collected.

Without this, Android builds fail with "unusable due to missing
dependencies: unwitch-2.2.0-..." when importing Hatter.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Categorise all changes since 0.2.0 into Breaking changes, Added, and
Fixed sections based on the git history (c17518a..HEAD).

Prompt: go repair the changelog in hatter for 0.3.0, use git to figure out what happened between the 0.3.0 release and 0.2.0

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace placeholder 0.3.0 changelog with detailed release notes
unwitch 3.0.0 makes Int32.toInt total (Int32 -> Int) on GHC, so
the int32ToIntKey helper and CInt.toInt . Int32.toCInt chain are
no longer needed. Replace all 10 copies with direct Int32.toInt
calls and remove the CInt import from files that only used it for
the helper.

Bump unwitch dependency to >= 3.0.0, point nix overlays to the
jappeace/unwitch commit with the total conversion.

Prompt: go simplify conversions here with unwitch 3

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace all fromIntegral with unwitch conversions
Combines two improvements to the Nix build infrastructure:

1. Deduplicate nix/lib.nix (995 → ~700 lines, 30% reduction):
   - Extract shared data lists (modules, C sources, headers, symbols)
     and helper functions into top-level let bindings
   - Merge mkIOSLib + mkWatchOSLib into internal mkAppleStaticLib
     parameterised by platform; public API preserved via thin wrappers
   - Merge mkSimulatorApp + mkWatchOSSimulatorApp into internal
     mkAppleSimulatorApp; public API preserved
   - Replace 14 repetitive NDK compile blocks with map over list
   - Hoist applePkgs, appleGhc, gmpStatic, libffiStatic to top-level

2. Build hatter as a cached cabal package for iOS/watchOS:
   - ios-deps.nix: add hatterSrc param, build hatter via callCabal2nix
     so the .a and package DB entry are cached
   - ios.nix, watchos.nix: pass hatterSrc to ios-deps.nix
   - mkAppleStaticLib: when crossDeps is provided, only compile
     Main.hs + run_main.c instead of all 22 modules + 19 C sources
   - Standalone fallback (crossDeps == null) preserved

Adding a new bridge module now means editing 1 list, not 6+ places.
Demo apps and consumers only recompile their entry point.

Prompt: combine PR jappeace#213 and jappeace#214 into a single PR

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@jappeace-sloth jappeace-sloth changed the base branch from master to develop April 26, 2026 10:51
@jappeace jappeace merged commit ec6ab6b into jappeace:develop Apr 26, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants