5
5
# The whole version replacement therapy is utterly ridiculous. It should be done
6
6
# in the respective packages.
7
7
8
+ # ┌─────────────────────────────────────────────────────────────────────────┐
9
+ # │ GHC Bootstrapping Stages │
10
+ # ├─────────────────────────────────────────────────────────────────────────┤
11
+ # │ │
12
+ # │ Stage 0 (Bootstrap) │
13
+ # │ ┌─────────┐ ┌─────────┐ │
14
+ # │ │ ghc0 │ │ pkg0 │ (initial boot packages) │
15
+ # │ │ (binary)│ │ │ │
16
+ # │ └────┬────┘ └────┬────┘ │
17
+ # │ │ │ │
18
+ # │ └───────┬───────┘ │
19
+ # │ ▼ │
20
+ # │ ┌─────────┐ │
21
+ # │ │ pkg0+ │ (augmented boot packages) │
22
+ # │ └────┬────┘ │
23
+ # │ │ │
24
+ # │ ············│························································· │
25
+ # │ ▼ │
26
+ # │ Stage 1 │ │
27
+ # │ ┌─────────┐ │ │
28
+ # │ │ ghc1 │◄┘ (built with ghc0, linked with rts0) │
29
+ # │ │ │ │
30
+ # │ └────┬────┘ │
31
+ # │ │ │
32
+ # │ │ ┌─────────┐ │
33
+ # │ └────►│ pkg1 │ (initially empty, then populated) │
34
+ # │ ┌─────│ │ (built with ghc1) │
35
+ # │ │ └─────────┘ │
36
+ # │ │ ▲ │
37
+ # │ │ │ (mutual dependency; ghc1 needs to sees pkg1) │
38
+ # │ ▼ │ │
39
+ # │ ┌─────────┐ │ │
40
+ # │ │ ghc1 │──────┘ │
41
+ # │ │ (uses) │ │
42
+ # │ └────┬────┘ │
43
+ # │ │ │
44
+ # │ ·····│································································ │
45
+ # │ ▼ │
46
+ # │ Stage 2 │
47
+ # │ ┌─────────┐ ┌──────────┐ ┌─────────┐ │
48
+ # │ │ ghc2 │ │ ghc-pkg2 │ │ ... │ │
49
+ # │ │ │ │ │ │ │ │
50
+ # │ └─────────┘ └──────────┘ └─────────┘ │
51
+ # │ (built with ghc1, linked with rts1) │
52
+ # │ │
53
+ # │ ┌─────────────────────────────────┐ │
54
+ # │ │ SHIPPED RESULT │ │
55
+ # │ │ ┌─────────┐ ┌─────────┐ │ │
56
+ # │ │ │ pkg1 │ + │ ghc2 │ │ │
57
+ # │ │ └─────────┘ └─────────┘ │ │
58
+ # │ └─────────────────────────────────┘ │
59
+ # │ │
60
+ # │ Notes: │
61
+ # │ • Binaries: one stage ahead (ghc1 builds pkg1, ghc2 ships with pkg1) │
62
+ # │ • Libraries: one stage below (pkg1 ships with ghc2) │
63
+ # │ • ghc1 and ghc2 are ABI compatible |
64
+ # | • ghc0 and ghc1 are not guaruateed to be ABI compatible |
65
+ # │ • ghc1 is linked against rts0, ghc2 against rts1 │
66
+ # | • augmented packages are needed because ghc1 may require newer |
67
+ # | versions or even new pacakges, not shipped with the boot compiler |
68
+ # │ │
69
+ # └─────────────────────────────────────────────────────────────────────────┘
70
+
71
+
72
+ # ISSUES:
73
+ # - [ ] Where do we get the version number from? The configure script _does_ contain
74
+ # one and sets it, but should it come from the last release tag this branch is
75
+ # contains?
76
+ # - [ ] HADRIAN_SETTINGS needs to be removed.
77
+ # - [ ] The hadrian folder needs to be removed.
78
+ # - [ ] All sublibs should be SRPs in the relevant cabal.project files. No more
79
+ # submodules.
80
+
8
81
SHELL := bash
9
82
.SHELLFLAGS := -eu -o pipefail -O globstar -c
10
83
@@ -25,9 +98,10 @@ override CABAL_ARGS += \
25
98
--logs-dir=_build/$(STAGE ) /logs
26
99
27
100
override CABAL_BUILD_ARGS += \
28
- -j -v - w $(GHC ) --with-gcc=$(CC ) \
101
+ -j -w $(GHC ) --with-gcc=$(CC ) \
29
102
--project-file=cabal.project.$(STAGE ) \
30
- --builddir=_build/$(STAGE )
103
+ --builddir=_build/$(STAGE ) \
104
+ --ghc-options="-fhide-source-paths"
31
105
32
106
# just some defaults
33
107
STAGE ?= stage1
@@ -60,25 +134,6 @@ define HADRIAN_SETTINGS
60
134
]
61
135
endef
62
136
63
- define run_and_log
64
- @set -e; \
65
- LOGDIR=$(@D ) /../logs; \
66
- mkdir -p "$$LOGDIR"; \
67
- STDOUT_LOG="$$LOGDIR/$(notdir $@ ) .stdout.log"; \
68
- STDERR_LOG="$$LOGDIR/$(notdir $@ ) .stderr.log"; \
69
- echo "+ $(1 ) "; \
70
- ( { $(1 ) ; } >"$$STDOUT_LOG" 2>"$$STDERR_LOG" ) || { \
71
- if [ -s "$$STDERR_LOG" ]; then \
72
- cat "$$STDERR_LOG"; \
73
- echo "See logs: $$STDERR_LOG (stderr), $$STDOUT_LOG (stdout)"; \
74
- elif [ -s "$$STDOUT_LOG" ]; then \
75
- cat "$$STDOUT_LOG"; \
76
- echo "See logs: $$STDERR_LOG (stderr), $$STDOUT_LOG (stdout)"; \
77
- fi; \
78
- exit 1; \
79
- }
80
- endef
81
-
82
137
# Handle CPUS and THREADS
83
138
CPUS_DETECT_SCRIPT := ./mk/detect-cpu-count.sh
84
139
CPUS := $(shell if [ -x $(CPUS_DETECT_SCRIPT ) ]; then $(CPUS_DETECT_SCRIPT ) ; else echo 2; fi)
@@ -184,13 +239,13 @@ $(abspath _build/stage0/bin/cabal): _build/stage0/bin/cabal
184
239
# This just builds cabal-install, which is used to build the rest of the project.
185
240
186
241
# We need an absolute path here otherwise cabal will consider the path relative to `the project directory
187
- _build/stage0/bin/cabal : BUILD_ARGS=-j -w $(GHC0 ) --disable-tests --project-dir libraries/Cabal --builddir=$(abspath _build/stage0)
242
+ _build/stage0/bin/cabal : BUILD_ARGS=-j -w $(GHC0 ) --disable-tests --project-dir libraries/Cabal --builddir=$(abspath _build/stage0) --ghc-options="-fhide-source-paths"
188
243
_build/stage0/bin/cabal :
189
- @echo " >>> Building Cabal..."
244
+ @echo " ::group:: Building Cabal..."
190
245
@mkdir -p _build/stage0/bin _build/logs
191
246
cabal build $(BUILD_ARGS ) cabal-install:exe:cabal
192
247
cp -rfp $(shell cabal list-bin -v0 $(BUILD_ARGS ) cabal-install:exe:cabal) _build/stage0/bin/cabal
193
- @echo " >>> Cabal built successfully. "
248
+ @echo " ::endgroup:: "
194
249
195
250
# --- Stage 1 build ---
196
251
@@ -199,20 +254,34 @@ _build/stage1/%: private GHC=$(GHC0)
199
254
200
255
.PHONY : $(addprefix _build/stage1/bin/,$(STAGE1_EXECUTABLES ) )
201
256
$(addprefix _build/stage1/bin/,$(STAGE1_EXECUTABLES ) ) & : $(CABAL ) | _build/booted
257
+ @echo " ::group::Building stage1 executables ($( STAGE1_EXECUTABLES) )..."
202
258
# Force cabal to replan
203
259
rm -rf _build/stage1/cache
204
- $( call run_and_log, HADRIAN_SETTINGS='$(HADRIAN_SETTINGS ) ' \
205
- $( CABAL_BUILD ) $( STAGE1_TARGETS ) )
260
+ HADRIAN_SETTINGS=' $(HADRIAN_SETTINGS)' $( CABAL_BUILD ) $( STAGE1_TARGETS )
261
+ @echo " ::endgroup:: "
206
262
207
263
_build/stage1/lib/settings : _build/stage1/bin/ghc-toolchain-bin
264
+ @echo " ::group::Creating settings for $( TARGET_TRIPLE) ..."
208
265
@mkdir -p $(@D )
209
- $(call run_and_log, _build/stage1/bin/ghc-toolchain-bin --triple $(TARGET_TRIPLE ) --output-settings -o $@ --cc $(CC ) --cxx $(CXX ) )
266
+ _build/stage1/bin/ghc-toolchain-bin --triple $(TARGET_TRIPLE ) --output-settings -o $@ --cc $(CC ) --cxx $(CXX )
267
+ @echo " ::endgroup::"
210
268
269
+ # The somewhat strange thing is, we might not even need this at all now anymore. cabal seems to
270
+ # pass all the necessary flags correctly. Thus even with an _empty_ package-db here (and it will
271
+ # stay empty until we are done with the build), the build succeeds.
272
+ #
273
+ # For now, we are tying the knot here by making sure the stage1 compiler (stage1/bin/ghc) sees
274
+ # the packages it builds (to build stage2/bin/ghc), by symlining cabal's target package-db into
275
+ # the compilers global package-db. Another maybe even better solution might be to set the
276
+ # Global Package DB in the settings file to the absolute path where cabal will place the
277
+ # package db. This would elminate this rule outright.
211
278
_build/stage1/lib/package.conf.d/package.cache : _build/stage1/bin/ghc-pkg _build/stage1/lib/settings
279
+ @echo " ::group::Creating stage1 package cache..."
212
280
@mkdir -p _build/stage1/lib/package.conf.d
213
- @rm -rf _build/stage1/lib/package.conf.d/*
214
- cp -rfp _build/stage1/packagedb/host/* /* _build/stage1/lib/package.conf.d
215
- _build/stage1/bin/ghc-pkg recache
281
+ # @mkdir -p _build/stage2/packagedb/host
282
+ # ln -s $(abspath ./_build/stage2/packagedb/host/ghc-9.13) _build/stage1/lib/package.conf.d
283
+ # _build/stage1/bin/ghc-pkg init $(abspath ./_build/stage2/packagedb/host/ghc-9.13)
284
+ @echo "::endgroup::"
216
285
217
286
_build/stage1/lib/template-hsc.h : utils/hsc2hs/data/template-hsc.h
218
287
@mkdir -p $(@D )
@@ -228,22 +297,26 @@ _build/stage2/%: private GHC=$(realpath _build/stage1/bin/ghc)
228
297
229
298
.PHONY : $(addprefix _build/stage2/bin/,$(STAGE2_EXECUTABLES ) )
230
299
$(addprefix _build/stage2/bin/,$(STAGE2_EXECUTABLES ) ) & : $(CABAL ) stage1
300
+ @echo " ::group::Building stage2 executables ($( STAGE2_EXECUTABLES) )..."
231
301
# Force cabal to replan
232
302
rm -rf _build/stage2/cache
233
- $( call run_and_log, HADRIAN_SETTINGS='$(HADRIAN_SETTINGS ) ' \
303
+ HADRIAN_SETTINGS=' $(HADRIAN_SETTINGS)' \
234
304
PATH=$(PWD ) /_build/stage1/bin:$(PATH ) \
235
- $(CABAL_BUILD ) --ghc-options=" -ghcversion-file=$( abspath ./rts/include/ghcversion.h) " -W $(GHC0 ) $(STAGE2_TARGETS ) )
305
+ $(CABAL_BUILD ) --ghc-options=" -ghcversion-file=$( abspath ./rts/include/ghcversion.h) " -W $(GHC0 ) $(STAGE2_TARGETS )
306
+ @echo " ::endgroup::"
236
307
237
308
# Do we want to build these with the stage2 GHC or the stage1 GHC?
238
309
# Traditionally we build them with the stage1 ghc, but we could just as well
239
310
# build them with the stage2 ghc; seems like a better/cleaner idea to me (moritz).
240
311
.PHONY : $(addprefix _build/stage2/bin/,$(STAGE2_UTIL_EXECUTABLES ) )
241
312
$(addprefix _build/stage2/bin/,$(STAGE2_UTIL_EXECUTABLES ) ) & : $(CABAL ) stage1
313
+ @echo " ::group::Building stage2 utilities ($( STAGE2_UTIL_EXECUTABLES) )..."
242
314
# Force cabal to replan
243
315
rm -rf _build/stage2/cache
244
- $( call run_and_log, HADRIAN_SETTINGS='$(HADRIAN_SETTINGS ) ' \
316
+ HADRIAN_SETTINGS=' $(HADRIAN_SETTINGS)' \
245
317
PATH=$(PWD ) /_build/stage1/bin:$(PATH ) \
246
- $(CABAL_BUILD ) --ghc-options=" -ghcversion-file=$( abspath ./rts/include/ghcversion.h) " -W $(GHC0 ) $(STAGE2_UTIL_TARGETS ) )
318
+ $(CABAL_BUILD ) --ghc-options=" -ghcversion-file=$( abspath ./rts/include/ghcversion.h) " -W $(GHC0 ) $(STAGE2_UTIL_TARGETS )
319
+ @echo " ::endgroup::"
247
320
248
321
249
322
# # We use PATH=... here to ensure all the build-tool-depends (deriveConstants, genapply, genprimopcode, ...) are
@@ -279,10 +352,12 @@ _build/stage2/lib/settings: _build/stage1/lib/settings
279
352
cp -rfp _build/stage1/lib/settings _build/stage2/lib/settings
280
353
281
354
_build/stage2/lib/package.conf.d/package.cache : _build/stage2/bin/ghc-pkg _build/stage2/lib/settings
355
+ @echo " ::group::Creating stage2 package cache..."
282
356
@mkdir -p _build/stage2/lib/package.conf.d
283
357
@rm -rf _build/stage2/lib/package.conf.d/*
284
358
cp -rfp _build/stage2/packagedb/host/* /* _build/stage2/lib/package.conf.d
285
359
_build/stage2/bin/ghc-pkg recache
360
+ @echo " ::endgroup::"
286
361
287
362
_build/stage2/lib/template-hsc.h : utils/hsc2hs/data/template-hsc.h
288
363
@mkdir -p $(@D )
@@ -293,7 +368,7 @@ stage2: $(addprefix _build/stage2/bin/,$(STAGE2_EXECUTABLES)) _build/stage2/lib/
293
368
294
369
# Target for creating the final binary distribution directory
295
370
_build/bindist : stage2 driver/ghc-usage.txt driver/ghci-usage.txt
296
- @echo " Creating binary distribution in _build/bindist"
371
+ @echo " ::group:: Creating binary distribution in _build/bindist"
297
372
@mkdir -p _build/bindist/bin
298
373
@mkdir -p _build/bindist/lib
299
374
# Copy executables from stage2 bin
@@ -305,61 +380,66 @@ _build/bindist: stage2 driver/ghc-usage.txt driver/ghci-usage.txt
305
380
@cp -rfp driver/ghci-usage.txt _build/bindist/lib/
306
381
@echo " FIXME: Changing 'Support SMP' from YES to NO in settings file"
307
382
@sed ' s/("Support SMP","YES")/("Support SMP","NO")/' -i.bck _build/bindist/lib/settings
308
- @echo " Binary distribution created. "
383
+ @echo " ::endgroup:: "
309
384
310
385
# --- Configuration ---
311
386
312
387
$(GHC1 ) $(GHC2 ) : | hackage
313
388
hackage : _build/packages/hackage.haskell.org/01-index.tar.gz
314
389
_build/packages/hackage.haskell.org/01-index.tar.gz : | $(CABAL )
390
+ @echo " ::group::Updating Hackage index..."
315
391
@mkdir -p $(@D )
316
392
$(CABAL ) $(CABAL_ARGS ) update --index-state 2025-04-22T01:25:40Z
393
+ @echo " ::endgroup::"
317
394
318
395
# booted depends on successful source preparation
319
396
_build/booted :
320
- @echo " >>> Running ./boot script..."
397
+ @echo " ::group:: Running ./boot script..."
321
398
@mkdir -p _build/logs
322
- ./boot | & tee _build/logs/boot.log
323
- @echo " >>> Running ./configure script..."
324
- $(call run_and_log, ./configure)
399
+ ./boot
400
+ @echo " ::endgroup::"
401
+ @echo " ::group::Running ./configure script..."
402
+ ./configure
403
+ @echo " ::endgroup::"
325
404
touch $@
326
405
327
406
# --- Clean Targets ---
328
407
clean :
329
- @echo " >>> Cleaning build artifacts..."
408
+ @echo " ::group:: Cleaning build artifacts..."
330
409
rm -rf _build
331
- @echo " >>> Build artifacts cleaned. "
410
+ @echo " ::endgroup:: "
332
411
333
412
clean-stage1 :
334
- @echo " >>> Cleaning stage1 build artifacts..."
413
+ @echo " ::group:: Cleaning stage1 build artifacts..."
335
414
rm -rf _build/stage1
336
- @echo " >>> Stage1 build artifacts cleaned. "
415
+ @echo " ::endgroup:: "
337
416
338
417
clean-stage2 :
339
- @echo " >>> Cleaning stage2 build artifacts..."
418
+ @echo " ::group:: Cleaning stage2 build artifacts..."
340
419
rm -rf _build/stage2
341
- @echo " >>> Stage2 build artifacts cleaned. "
420
+ @echo " ::endgroup:: "
342
421
343
422
distclean : clean
344
- @echo " >>> Cleaning all generated files (distclean)..."
423
+ @echo " ::group:: Cleaning all generated files (distclean)..."
345
424
rm -rf autom4te.cache
346
425
rm -f config.status config.log config.h configure aclocal.m4
347
426
rm -rf build-aux/config.guess build-aux/config.sub build-aux/install-sh build-aux/missing build-aux/compile depcomp
348
427
find . -name ' Makefile.in' -delete
349
428
rm -f $(CONFIGURED_FILES )
350
- @echo " >>> All generated files cleaned. "
429
+ @echo " ::endgroup:: "
351
430
352
431
353
432
# --- Test Target ---
354
433
test : _build/bindist
355
- @echo " >>> Running tests with THREADS=${THREADS} " >&2
434
+ @echo " ::group:: Running tests with THREADS=${THREADS} " >&2
356
435
TEST_HC=` pwd` /_build/bindist/bin/ghc \
357
436
TEST_CC=$(CC ) \
358
437
TEST_CXX=$(CXX ) \
359
438
METRICS_FILE=` pwd` /_build/test-perf.csv \
360
439
SUMMARY_FILE=` pwd` /_build/test-summary.txt \
361
440
JUNIT_FILE=` pwd` /_build/test-junit.xml \
362
441
make -C testsuite/tests test THREADS=${THREADS}
442
+ @echo " ::endgroup::" >&2
363
443
364
444
# Inform Make that these are not actual files if they get deleted by other means
365
445
.PHONY : clean distclean test all
0 commit comments