5
5
# The whole version replacement therapy is utterly ridiculous. It should be done
6
6
# in the respective packages.
7
7
8
+ SHELL := bash
9
+ .SHELLFLAGS := -eu -o pipefail -O globstar -c
10
+
11
+ ROOT_DIR := $(dir $(realpath $(lastword $(MAKEFILE_LIST ) ) ) )
12
+
8
13
GHC0 ?= ghc-9.8.4
9
14
PYTHON ?= python3
10
15
CABAL ?= cabal
11
16
17
+ CABAL_ARGS += --remote-repo-cache _build/packages
18
+ CABAL_ARGS += --store-dir=_build/$(STAGE ) /store
19
+ CABAL_ARGS += --logs-dir=_build/$(STAGE ) /logs
20
+
21
+ CABAL_BUILD_ARGS += -j1 -v -w $(GHC )
22
+ CABAL_BUILD_ARGS += --project-file=cabal.project.$(STAGE )
23
+ CABAL_BUILD_ARGS += --builddir=_build/$(STAGE )
24
+
25
+ # just some defaults
26
+ STAGE ?= stage1
27
+ GHC ?= $(GHC0 )
28
+
29
+ CABAL_BUILD = $(CABAL ) $(CABAL_ARGS ) build $(CABAL_BUILD_ARGS )
30
+
31
+ CABAL_LIST_BIN_ARGS += $(CABAL_BUILD_ARGS ) -v0
32
+ CABAL_LIST_BIN = $(CABAL ) $(CABAL_ARGS ) list-bin $(CABAL_LIST_BIN_ARGS )
33
+
12
34
GHC1 = _build/stage1/bin/ghc
13
35
GHC2 = _build/stage2/bin/ghc
14
36
15
37
define GHC_INFO
16
38
$(shell $(GHC0 ) --info | $(GHC0 ) -e 'getContents >>= foldMap putStrLn . lookup "$1" . read')
17
39
endef
18
40
19
- define COPY_BIN # $1 : cabal, $2: ghc, $3: stage, $4: target, $5: name
20
- cp -rfp $(shell $1 list-bin --project-file=cabal.project.$3 -w $2 --builddir=_build/$3/cabal $4 -v0) _build/$3/bin/$5
21
- endef
22
-
23
41
TARGET_PLATFORM := $(call GHC_INFO,target platform string)
24
42
TARGET_ARCH := $(call GHC_INFO,target arch)
25
43
TARGET_OS := $(call GHC_INFO,target os)
@@ -68,98 +86,119 @@ all: _build/bindist # booted will depend on prepare-sources
68
86
69
87
STAGE_TARGETS := rts-headers:rts-headers ghc-bin:ghc ghc-pkg:ghc-pkg genprimopcode:genprimopcode deriveConstants:deriveConstants genapply:genapply unlit:unlit hsc2hs:hsc2hs
70
88
STAGE1_TARGETS := $(STAGE_TARGETS ) ghc-toolchain-bin:ghc-toolchain-bin
71
- STAGE2_TARGETS := $(STAGE_TARGETS ) hp2ps:hp2ps hpc-bin:hpc iserv:iserv runghc:runghc
72
89
90
+ # TODO: dedup
91
+ STAGE1_EXECUTABLES := ghc ghc-pkg unlit hsc2hs deriveConstants genprimopcode genapply ghc-toolchain-bin
92
+
93
+ STAGE2_TARGETS := $(STAGE_TARGETS ) hp2ps:hp2ps hpc-bin:hpc iserv:iserv runghc:runghc
73
94
# All these libraries are somehow needed by some tests :rolleyes: this seems to be needed occationally.
74
95
STAGE2_TARGETS += ghc-bignum:ghc-bignum ghc-compact:ghc-compact ghc-experimental:ghc-experimental integer-gmp:integer-gmp xhtml:xhtml terminfo:terminfo ghc-toolchain:ghc-toolchain system-cxx-std-lib:system-cxx-std-lib
75
96
# This package is just utterly retarded
76
97
# I don't understand why this following line somehow breaks the build...
77
98
# STAGE2_TARGETS += system-cxx-std-lib:system-cxx-std-lib
78
99
100
+ # TODO: dedup
101
+ STAGE2_EXECUTABLES := \
102
+ ghc \
103
+ pkg \
104
+ unlit \
105
+ hsc2hs \
106
+ deriveConstants \
107
+ genprimopcode \
108
+ genapply \
109
+ hp2ps \
110
+ hpc \
111
+ runghc \
112
+ ghc-iserv
113
+
79
114
# export CABAL := $(shell cabal update 2>&1 >/dev/null && cabal build cabal-install -v0 --disable-tests --project-dir libraries/Cabal && cabal list-bin -v0 --project-dir libraries/Cabal cabal-install:exe:cabal)
80
115
$(abspath _build/stage0/bin/cabal) : _build/stage0/bin/cabal
81
116
117
+ .PHONY : _build/stage0/bin/cabal
82
118
_build/stage0/bin/cabal :
83
119
@echo " >>> Building Cabal..."
84
- @mkdir -p _build/stage0/bin
85
- @mkdir -p _build/logs
86
- cabal build --disable-tests --project-dir libraries/Cabal --builddir=_build/stage0/cabal cabal-install:exe:cabal -j -w ghc | & tee _build/logs/cabal.log
87
- cp -rfp $(shell cabal list-bin -v0 --project-dir libraries/Cabal cabal-install:exe:cabal --builddir=_build/stage0/cabal -v0) _build/stage0/bin/cabal
120
+ @mkdir -p _build/stage0/bin _build/logs
121
+ cabal build -j -w $(GHC0 ) --disable-tests --project-dir libraries/Cabal --builddir=_build/stage0/cabal cabal-install:exe:cabal | & tee _build/logs/cabal.log
122
+ cp -rfp $(shell cabal list-bin -v0 -j -w $(GHC0 ) --project-dir libraries/Cabal --builddir=_build/stage0/cabal cabal-install:exe:cabal) _build/stage0/bin/cabal
88
123
@echo " >>> Cabal built successfully."
89
124
90
- $(GHC1 ) : _build/booted $(CABAL )
91
- @echo " >>> Building with GHC: $( GHC0) and Cabal: $( CABAL) "
92
- @echo " >>> Using $( THREADS) threads"
93
- @mkdir -p _build/logs
125
+ # --- Stage 1 build ---
126
+
127
+ _build/stage1/% : private STAGE=stage1
128
+ _build/stage1/% : private GHC=$(GHC0 )
129
+ _build/stage1/% : $(CABAL ) | _build/booted
130
+
131
+ .PHONY : $(addprefix _build/stage1/bin/,$(STAGE1_EXECUTABLES ) )
132
+ $(addprefix _build/stage1/bin/,$(STAGE1_EXECUTABLES ) ) & : $(CABAL )
133
+ ./configure
94
134
HADRIAN_SETTINGS=' $(HADRIAN_SETTINGS)' \
95
- $(CABAL ) build --project-file=cabal.project.stage1 --builddir=_build/stage1/cabal -j -w $(GHC0 ) \
96
- $(STAGE1_TARGETS ) \
135
+ $(CABAL_BUILD ) $(STAGE1_TARGETS ) \
97
136
| & tee _build/logs/stage1.log
137
+
138
+ @mkdir -p _build/stage1/bin
139
+ for t in $( STAGE1_EXECUTABLES) ; do cp -v $$ ($( CABAL_LIST_BIN) exe:$$ t) _build/stage1/bin/; done
98
140
99
- _build/stage1.done : $(GHC1 )
100
- mkdir -p _build/stage1/{bin,lib}
101
- $(call COPY_BIN,$(CABAL ) ,$(GHC0 ) ,stage1,ghc-bin:ghc,ghc)
102
- $(call COPY_BIN,$(CABAL ) ,$(GHC0 ) ,stage1,ghc-pkg:ghc-pkg,ghc-pkg)
103
- $(call COPY_BIN,$(CABAL ) ,$(GHC0 ) ,stage1,unlit:unlit,unlit)
104
- $(call COPY_BIN,$(CABAL ) ,$(GHC0 ) ,stage1,hsc2hs:hsc2hs,hsc2hs)
105
- $(call COPY_BIN,$(CABAL ) ,$(GHC0 ) ,stage1,deriveConstants:deriveConstants,deriveConstants)
106
- $(call COPY_BIN,$(CABAL ) ,$(GHC0 ) ,stage1,genprimopcode:genprimopcode,genprimopcode)
107
- $(call COPY_BIN,$(CABAL ) ,$(GHC0 ) ,stage1,genapply:genapply,genapply)
108
- $(call COPY_BIN,$(CABAL ) ,$(GHC0 ) ,stage1,ghc-toolchain-bin:ghc-toolchain-bin,ghc-toolchain)
109
-
141
+ _build/stage1.done : $(addprefix _build/stage1/bin/,$(STAGE1_EXECUTABLES ) ) _build/stage1/bin/ghc-toolchain-bin
142
+ @mkdir -p _build/stage1/{bin,lib}
110
143
cp -rfp utils/hsc2hs/data/template-hsc.h _build/stage1/lib/template-hsc.h
144
+ _build/stage1/bin/ghc-toolchain-bin --triple $(TARGET_TRIPLE ) --output-settings -o _build/stage1/lib/settings --cc $(CC ) --cxx $(CXX ) | & tee _build/logs/ghc-toolchain.log
145
+ cp -rfp _build/stage1/packagedb/host _build/stage1/lib/package.conf.d
146
+ _build/stage1/bin/ghc-pkg recache
147
+ touch $@
111
148
112
- _build/ stage1/bin/ghc-toolchain --triple $(TARGET_TRIPLE) --output-settings -o _build/stage1/lib/settings --cc $(CC) --cxx $(CXX) |& tee _build/logs/ghc-toolchain.log
149
+ stage1 : _build/stage1.done
113
150
114
- rm -fR _build/stage1/lib/package.conf.d; ln -s $(abspath $(wildcard ./_build/stage1/cabal/packagedb/ghc-*)) _build/stage1/lib/package.conf.d
115
- _build/stage1/bin/ghc-pkg recache
151
+ # --- Stage 2 build ---
116
152
117
- # We use PATH=... here to ensure all the build-tool-depends (deriveConstants, genapply, genprimopcode, ...) are
118
- # available in PATH while cabal evaluates configure files. Cabal sadly does not support build-tool-depends or
119
- # handle build-depends properly prior to building the package. Thus Configure/Setup/... do not have build-tool-depends
120
- # available in PATH. This is a workaround for that. I consider this a defect in cabal.
121
- $(GHC2 ) : _build/stage1.done
122
- @$(LIB )
123
- @echo " >>> Building with GHC: $( GHC1) and Cabal: $( CABAL) "
124
- @echo " >>> Using $( THREADS) threads"
125
-
126
- # this is stupid, having to build the rts first. We need to find a better way to do this.
127
- # We might be able to just have the `ghc` executable depend on the specific rts we want to
128
- # set as a default.
129
- HADRIAN_SETTINGS='$(HADRIAN_SETTINGS)' \
130
- PATH=$(PWD)/_build/stage1/bin:$(PATH) \
131
- $(CABAL) build --project-file=cabal.project.stage2 --builddir=_build/stage2/cabal -j -w ghc \
132
- --ghc-options="-ghcversion-file=$(abspath ./rts/include/ghcversion.h)" \
133
- rts:nonthreaded-nodebug rts:nonthreaded-debug \
134
- |& tee _build/logs/rts.log
153
+ _build/stage2/% : private STAGE=stage2
154
+ _build/stage2/% : private GHC=_build/stage1/bin/ghc
135
155
156
+ .PHONY : $(addprefix _build/stage2/bin/,$(STAGE2_EXECUTABLES ) )
157
+ $(addprefix _build/stage2/bin/,$(STAGE2_EXECUTABLES ) ) & : $(CABAL ) _build/stage1.done
136
158
HADRIAN_SETTINGS=' $(HADRIAN_SETTINGS)' \
137
159
PATH=$(PWD ) /_build/stage1/bin:$(PATH ) \
138
- $(CABAL) build --project-file=cabal.project.stage2 --builddir=_build/stage2/cabal -j -w ghc \
139
- --ghc-options="-ghcversion-file=$(abspath ./rts/include/ghcversion.h)" \
140
- $(STAGE2_TARGETS) \
160
+ $(CABAL_BUILD ) --ghc-options=" -ghcversion-file=$( abspath ./rts/include/ghcversion.h) " -W $(GHC0 ) $(STAGE2_TARGETS ) \
141
161
| & tee _build/logs/stage2.log
142
162
143
- _build/stage2.done : $(GHC2 )
144
- mkdir -p _build/stage2/{bin,lib}
145
- $(call COPY_BIN,$(CABAL ) ,$(GHC1 ) ,stage2,ghc-bin:ghc,ghc)
146
- $(call COPY_BIN,$(CABAL ) ,$(GHC1 ) ,stage2,ghc-pkg:ghc-pkg,ghc-pkg)
147
- $(call COPY_BIN,$(CABAL ) ,$(GHC1 ) ,stage2,unlit:unlit,unlit)
148
- $(call COPY_BIN,$(CABAL ) ,$(GHC1 ) ,stage2,hsc2hs:hsc2hs,hsc2hs)
149
- $(call COPY_BIN,$(CABAL ) ,$(GHC1 ) ,stage2,deriveConstants:deriveConstants,deriveConstants)
150
- $(call COPY_BIN,$(CABAL ) ,$(GHC1 ) ,stage2,genprimopcode:genprimopcode,genprimopcode)
151
- $(call COPY_BIN,$(CABAL ) ,$(GHC1 ) ,stage2,genapply:genapply,genapply)
152
- $(call COPY_BIN,$(CABAL ) ,$(GHC1 ) ,stage2,hp2ps:hp2ps,hp2ps)
153
- $(call COPY_BIN,$(CABAL ) ,$(GHC1 ) ,stage2,hpc-bin:hpc,hpc)
154
- $(call COPY_BIN,$(CABAL ) ,$(GHC1 ) ,stage2,runghc:runghc,runghc)
155
- $(call COPY_BIN,$(CABAL ) ,$(GHC1 ) ,stage2,iserv:iserv,ghc-iserv)
156
-
157
- cp -rfp utils/hsc2hs/data/template-hsc.h _build/stage2/lib/template-hsc.h
163
+ @mkdir -p _build/stage2/bin
164
+ for t in $(STAGE2_EXECUTABLES); do cp -v $$($(CABAL_LIST_BIN) exe:$$t) _build/stage2/bin/; done
165
+
166
+
167
+ # # We use PATH=... here to ensure all the build-tool-depends (deriveConstants, genapply, genprimopcode, ...) are
168
+ # # available in PATH while cabal evaluates configure files. Cabal sadly does not support build-tool-depends or
169
+ # # handle build-depends properly prior to building the package. Thus Configure/Setup/... do not have build-tool-depends
170
+ # # available in PATH. This is a workaround for that. I consider this a defect in cabal.
171
+ # _build/stage2/bin/ghc: _build/stage1.done
172
+ # @$(LIB)
173
+ # @echo ">>> Building with GHC: $(GHC1) and Cabal: $(CABAL)"
174
+ # @echo ">>> Using $(THREADS) threads"
175
+
176
+ # # this is stupid, having to build the rts first. We need to find a better way to do this.
177
+ # # We might be able to just have the `ghc` executable depend on the specific rts we want to
178
+ # # set as a default.
179
+ # HADRIAN_SETTINGS='$(HADRIAN_SETTINGS)' \
180
+ # PATH=$(PWD)/_build/stage1/bin:$(PATH) \
181
+ # $(CABAL) $(CABAL_ARGS) build --project-file=cabal.project.stage2 --builddir=_build/stage2/cabal -j -w ghc \
182
+ # $(CABAL_BUILD_ARGS) \
183
+ # --ghc-options="-ghcversion-file=$(abspath ./rts/include/ghcversion.h)" \
184
+ # rts:nonthreaded-nodebug rts:nonthreaded-debug \
185
+ # |& tee _build/logs/rts.log
186
+
187
+ # HADRIAN_SETTINGS='$(HADRIAN_SETTINGS)' \
188
+ # PATH=$(PWD)/_build/stage1/bin:$(PATH) \
189
+ # $(CABAL) $(CABAL_ARGS) build --project-file=cabal.project.stage2 --builddir=_build/stage2/cabal -j -w ghc \
190
+ # $(CABAL_BUILD_ARGS) \
191
+ # --ghc-options="-ghcversion-file=$(abspath ./rts/include/ghcversion.h)" \
192
+ # $(STAGE2_TARGETS) \
193
+ # |& tee _build/logs/stage2.log
158
194
195
+ _build/stage2.done : $(GHC2 )
196
+ @mkdir -p _build/stage2/{bin,lib}
159
197
cp -rfp _build/stage1/lib/settings _build/stage2/lib/settings
160
-
161
- rm -fR _build/stage2/lib/package.conf.d; ln -s $(abspath $(wildcard ./_build/stage2/cabal/ packagedb/ghc-*)) _build/stage2/lib/package.conf.d
198
+ cp -rfp utils/hsc2hs/data/template-hsc.h _build/stage2/lib/template-hsc.h
199
+ cp -rfp _build/stage2/packagedb/host _build/stage2/lib/package.conf.d
162
200
_build/stage2/bin/ghc-pkg recache
201
+ touch $@
163
202
164
203
# Target for creating the final binary distribution directory
165
204
_build/bindist : _build/stage2.done driver/ghc-usage.txt driver/ghci-usage.txt
@@ -176,8 +215,15 @@ _build/bindist: _build/stage2.done driver/ghc-usage.txt driver/ghci-usage.txt
176
215
@echo " FIXME: swpaaing Support SMP from YES to NO in settings file"
177
216
@sed ' s/("Support SMP","YES")/("Support SMP","NO")/' -i.bck _build/bindist/lib/settings
178
217
@echo " Binary distribution created."
218
+
179
219
# --- Configuration ---
180
220
221
+ $(GHC1 ) $(GHC2 ) : | hackage
222
+ hackage : _build/packages/hackage.haskell.org/01-index.tar.gz
223
+ _build/packages/hackage.haskell.org/01-index.tar.gz : | $(CABAL )
224
+ @mkdir -p $(@D )
225
+ $(CABAL ) $(CABAL_ARGS ) update --index-state 2025-04-22T01:25:40Z
226
+
181
227
# booted depends on successful source preparation
182
228
_build/booted :
183
229
@echo " >>> Running ./boot script..."
0 commit comments