|
|
1
|
+# CLAUDE.md
|
|
|
2
|
+
|
|
|
3
|
+This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
|
4
|
+
|
|
|
5
|
+## Overview
|
|
|
6
|
+
|
|
|
7
|
+This is the source tree for **GHC** (Glasgow Haskell Compiler), a self-hosted optimising compiler for Haskell. The compiler is itself written in Haskell. GHC uses the **Hadrian** build system (based on Shake) instead of Make.
|
|
|
8
|
+
|
|
|
9
|
+## Build & Test Workflow
|
|
|
10
|
+
|
|
|
11
|
+All build and test commands go through `.gitlab/ci.sh`, which is the single CI driver. Run it from the repository root. **Always source `source-env.sh` first** — it sets all required environment variables for the Windows validate CI configuration:
|
|
|
12
|
+
|
|
|
13
|
+```sh
|
|
|
14
|
+source source-env.sh
|
|
|
15
|
+```
|
|
|
16
|
+
|
|
|
17
|
+### Setup (once per checkout)
|
|
|
18
|
+
|
|
|
19
|
+```sh
|
|
|
20
|
+source source-env.sh && .gitlab/ci.sh setup # fetch/verify toolchain, update cabal index
|
|
|
21
|
+source source-env.sh && .gitlab/ci.sh configure # run ./boot + ./configure
|
|
|
22
|
+```
|
|
|
23
|
+
|
|
|
24
|
+`configure` respects `CONFIGURE_ARGS`. On Windows this runs with `--enable-tarballs-autodownload` automatically.
|
|
|
25
|
+
|
|
|
26
|
+### Building
|
|
|
27
|
+
|
|
|
28
|
+```sh
|
|
|
29
|
+source source-env.sh && .gitlab/ci.sh build_hadrian
|
|
|
30
|
+```
|
|
|
31
|
+
|
|
|
32
|
+Build output goes to `_build/`; the stage2 compiler ends up at `_build/stage1/bin/ghc`. The bindist is produced at `${BIN_DIST_NAME}.tar.xz`.
|
|
|
33
|
+
|
|
|
34
|
+### Testing
|
|
|
35
|
+
|
|
|
36
|
+```sh
|
|
|
37
|
+source source-env.sh && .gitlab/ci.sh test_hadrian
|
|
|
38
|
+```
|
|
|
39
|
+
|
|
|
40
|
+`test_hadrian` installs the bindist under `_build/install/`, then runs the testsuite against it. Override `RUNTEST_ARGS` to pass extra flags to the test driver:
|
|
|
41
|
+
|
|
|
42
|
+```sh
|
|
|
43
|
+# Run a specific test
|
|
|
44
|
+source source-env.sh
|
|
|
45
|
+RUNTEST_ARGS="--only=T1234" .gitlab/ci.sh test_hadrian
|
|
|
46
|
+
|
|
|
47
|
+# Run tests in a directory
|
|
|
48
|
+RUNTEST_ARGS="--test-root-dirs=testsuite/tests/typecheck" .gitlab/ci.sh test_hadrian
|
|
|
49
|
+
|
|
|
50
|
+# Skip performance tests
|
|
|
51
|
+RUNTEST_ARGS="--skip-perf" .gitlab/ci.sh test_hadrian
|
|
|
52
|
+
|
|
|
53
|
+# Accept new test output
|
|
|
54
|
+RUNTEST_ARGS="-a --only=T1234" .gitlab/ci.sh test_hadrian
|
|
|
55
|
+```
|
|
|
56
|
+
|
|
|
57
|
+Set `VERBOSE=1` to get verbose Hadrian output. Set `IGNORE_PERF_FAILURES=all` to ignore performance regressions.
|
|
|
58
|
+
|
|
|
59
|
+### Cleaning
|
|
|
60
|
+
|
|
|
61
|
+```sh
|
|
|
62
|
+source source-env.sh && .gitlab/ci.sh clean
|
|
|
63
|
+```
|
|
|
64
|
+
|
|
|
65
|
+### What `source-env.sh` sets
|
|
|
66
|
+
|
|
|
67
|
+`source-env.sh` encodes the Windows x86_64 validate CI configuration:
|
|
|
68
|
+
|
|
|
69
|
+| Variable | Value |
|
|
|
70
|
+|---|---|
|
|
|
71
|
+| `BUILD_FLAVOUR` | `validate` |
|
|
|
72
|
+| `BIN_DIST_NAME` | `ghc-x86_64-windows-validate` |
|
|
|
73
|
+| `BIGNUM_BACKEND` | `gmp` |
|
|
|
74
|
+| `FETCH_GHC_VERSION` | `9.10.3` |
|
|
|
75
|
+| `CONFIGURE_ARGS` | `--enable-strict-ghc-toolchain-check` |
|
|
|
76
|
+| `HADRIAN_ARGS` | `--docs=no-sphinx-pdfs` |
|
|
|
77
|
+| `MSYSTEM` | `CLANG64` |
|
|
|
78
|
+
|
|
|
79
|
+Override individual variables after sourcing as needed (e.g. `RUNTEST_ARGS="--only=T1234"`).
|
|
|
80
|
+
|
|
|
81
|
+### Build flavours
|
|
|
82
|
+
|
|
|
83
|
+Select with `BUILD_FLAVOUR=<name>`:
|
|
|
84
|
+- `quick` — `-O0` everywhere except compiler itself; 2-3x faster than default
|
|
|
85
|
+- `quickest` — `-O0` everywhere, vanilla-only libraries; fastest but may not pass all tests
|
|
|
86
|
+- `default` — full optimised build
|
|
|
87
|
+- `validate` — used by CI; includes `-dcore-lint` and error checks
|
|
|
88
|
+- `perf` — fully optimised with split sections; used by CI release builds
|
|
|
89
|
+- `devel1` / `devel2` — debug builds with `-DDEBUG` and `-dcore-lint`
|
|
|
90
|
+
|
|
|
91
|
+Flavour transformers append with `+` (e.g. `BUILD_FLAVOUR=validate+werror`).
|
|
|
92
|
+
|
|
|
93
|
+### GHCi session for fast type-checking feedback
|
|
|
94
|
+
|
|
|
95
|
+```sh
|
|
|
96
|
+./hadrian/ghci -j8 # Load GHC compiler into GHCi (type-check only)
|
|
|
97
|
+ghcid --command="./hadrian/ghci"
|
|
|
98
|
+```
|
|
|
99
|
+
|
|
|
100
|
+This does not go through `ci.sh` and is fine for quick edit-check cycles.
|
|
|
101
|
+
|
|
|
102
|
+### Linting
|
|
|
103
|
+
|
|
|
104
|
+CI linters run as separate jobs. Locally:
|
|
|
105
|
+```sh
|
|
|
106
|
+source source-env.sh && .gitlab/ci.sh run_hadrian lint:compiler # hlint on compiler/
|
|
|
107
|
+source source-env.sh && .gitlab/ci.sh run_hadrian lint:base # hlint on libraries/base/
|
|
|
108
|
+```
|
|
|
109
|
+
|
|
|
110
|
+Other linters (under `linters/`) check whitespace, commit messages, Note cross-references, and submodule refs.
|
|
|
111
|
+
|
|
|
112
|
+Tests are declared in `all.T` files (Python-based). Tests live under `testsuite/tests/` organised by compiler phase/feature, plus per-library tests in `libraries/*/`.
|
|
|
113
|
+
|
|
|
114
|
+## IDE Setup
|
|
|
115
|
+
|
|
|
116
|
+The `hie.yaml` at the root configures HLS/ghcide via hie-bios. On Windows, replace the program path:
|
|
|
117
|
+```yaml
|
|
|
118
|
+cradle: {bios: {program: "./hadrian/hie-bios.bat"}}
|
|
|
119
|
+```
|
|
|
120
|
+
|
|
|
121
|
+## Architecture
|
|
|
122
|
+
|
|
|
123
|
+GHC is a multi-stage self-hosted compiler. The build proceeds:
|
|
|
124
|
+- **Stage0**: bootstrap GHC (pre-installed) builds Hadrian and the Stage1 compiler
|
|
|
125
|
+- **Stage1** (`_build/stage0/bin/ghc`): used to build Stage2 and core libraries
|
|
|
126
|
+- **Stage2** (`_build/stage1/bin/ghc`): the shipped compiler; what `build test` uses by default
|
|
|
127
|
+
|
|
|
128
|
+### Compiler pipeline (`compiler/`)
|
|
|
129
|
+
|
|
|
130
|
+Source flows through these phases, each in its own `GHC/` subdirectory:
|
|
|
131
|
+
|
|
|
132
|
+1. **Parser** (`GHC/Parser.y`, `GHC/Parser/`) — Alex/Happy lexer+parser → `HsSyn` AST
|
|
|
133
|
+2. **Renamer** (`GHC/Rename/`) — resolves names, scope checking → renamed `HsSyn`
|
|
|
134
|
+3. **Type checker** (`GHC/Tc/`) — Hindley-Milner + type classes + GADTs → typed AST
|
|
|
135
|
+4. **Desugarer** (`GHC/HsToCore/`) — `HsSyn` → **Core IR** (`GHC/Core/`)
|
|
|
136
|
+5. **Core optimiser** (`GHC/Core/Opt/`) — simplifier, strictness analysis, specialisation, CSE, etc.
|
|
|
137
|
+6. **STG** (`GHC/CoreToStg/`, `GHC/Stg/`) — Core → Spineless Tagless G-machine IR
|
|
|
138
|
+7. **Cmm** (`GHC/StgToCmm/`, `GHC/Cmm/`) — STG → C-- IR (low-level portable assembly)
|
|
|
139
|
+8. **Backends** (`GHC/CmmToAsm/`, `GHC/CmmToC.hs`, `GHC/CmmToLlvm/`, `GHC/StgToJS/`) — Cmm → native asm / C / LLVM IR / JavaScript
|
|
|
140
|
+9. **Bytecode** (`GHC/ByteCode/`, `GHC/StgToByteCode.hs`) — for GHCi interpreter
|
|
|
141
|
+
|
|
|
142
|
+Key supporting modules:
|
|
|
143
|
+- `GHC/Driver/` — top-level driver, `DynFlags`, pipeline orchestration, `--make` mode
|
|
|
144
|
+- `GHC/Iface/` — interface files (`.hi`) read/write
|
|
|
145
|
+- `GHC/Plugins.hs` — plugin API
|
|
|
146
|
+- `GHC.hs` — the public GHC API entry point
|
|
|
147
|
+- `GHC/Prelude.hs` — re-exported prelude used throughout the compiler
|
|
|
148
|
+
|
|
|
149
|
+### Runtime System (`rts/`)
|
|
|
150
|
+
|
|
|
151
|
+Written in C and Cmm. Key subsystems:
|
|
|
152
|
+- **Scheduler** (`Schedule.c`) — green thread scheduling
|
|
|
153
|
+- **Garbage collector** (`sm/`) — generational GC
|
|
|
154
|
+- **Linker** (`linker/`, `Linker.c`) — dynamic object loading for GHCi
|
|
|
155
|
+- **STM** (`STM.c`) — software transactional memory
|
|
|
156
|
+- **Profiling** (`Profiling.c`, `LdvProfile.c`, `RetainerProfile.c`)
|
|
|
157
|
+- **Event log** (`eventlog/`)
|
|
|
158
|
+
|
|
|
159
|
+### Boot libraries (`libraries/`)
|
|
|
160
|
+
|
|
|
161
|
+Core libraries shipped with GHC: `base`, `ghc-prim`, `ghc-bignum`, `ghc-boot`, `ghci`, `template-haskell`, `ghc-compact`, `ghc-experimental`, and others. Changes to `base` require a [CLC proposal](https://github.com/haskell/core-libraries-committee).
|
|
|
162
|
+
|
|
|
163
|
+### Build system (`hadrian/`)
|
|
|
164
|
+
|
|
|
165
|
+Hadrian source is in `hadrian/src/`. Key files:
|
|
|
166
|
+- `hadrian/src/Flavour.hs` — flavour definitions
|
|
|
167
|
+- `hadrian/src/UserSettings.hs` — override point (copy to `hadrian/UserSettings.hs`)
|
|
|
168
|
+- `hadrian/doc/` — documentation for flavours, expressions, user settings, testsuite
|
|
|
169
|
+
|
|
|
170
|
+## Changelog
|
|
|
171
|
+
|
|
|
172
|
+Every user-facing MR must add a fragment in `changelog.d/` (use a descriptive filename, not a ticket number alone). Required fields: `section`, `synopsis`, `mrs`, `issues`. Apply label `no-changelog` if no entry is needed.
|
|
|
173
|
+
|
|
|
174
|
+```
|
|
|
175
|
+section: compiler
|
|
|
176
|
+synopsis: Brief description of the change.
|
|
|
177
|
+issues: #NNNNN
|
|
|
178
|
+mrs: !NNNNN
|
|
|
179
|
+
|
|
|
180
|
+description: {
|
|
|
181
|
+ Optional extended RST description.
|
|
|
182
|
+}
|
|
|
183
|
+```
|
|
|
184
|
+
|
|
|
185
|
+## Notes / Commentary Convention
|
|
|
186
|
+
|
|
|
187
|
+GHC uses "Note [Title]" comments extensively for cross-referencing design decisions. When making a non-obvious change, add or update a Note and reference it from the relevant code locations with `-- See Note [Title]`.
|
|
|
188
|
+
|
|
|
189
|
+## Contribution Checklist
|
|
|
190
|
+
|
|
|
191
|
+- All commits must be individually buildable or squashed
|
|
|
192
|
+- Commit messages describe what they do; reference tickets with `#NNNNN`
|
|
|
193
|
+- Add testcases in `testsuite/tests/` (see `testsuite/driver/README.md` for how)
|
|
|
194
|
+- Update the user's guide (`docs/users_guide/`) for user-visible changes
|
|
|
195
|
+- Apply `~user-facing` label on GitLab if the change could break user programs |