Line-buffer stdout and stderr
[cabal.git] / Makefile
blob70e150edebbbb88d0e7a1fbf3f31b9223ca342d1
1 .PHONY: phony
2 # Adding dependency "phony" is like declaring a target as ".PHONY":
3 # See https://www.gnu.org/software/make/manual/html_node/Force-Targets.html
5 CABALBUILD := cabal build
6 CABALRUN := cabal run
8 # We have to avoid allow-newer.
9 # SEE: https://github.com/haskell/cabal/issues/6859
10 DOCTEST := cabal doctest --allow-newer=False
12 # default rules
14 .PHONY: all
15 all: help-banner exe lib ## Build the Cabal libraries and cabal-install executables.
17 .PHONY: lib
18 lib: ## Builds the Cabal libraries.
19 $(CABALBUILD) Cabal:libs
21 .PHONY: exe
22 exe: ## Builds the cabal-install executables.
23 $(CABALBUILD) cabal-install:exes
25 .PHONY: init
26 init: ## Set up git hooks and ignored revisions.
27 @git config core.hooksPath .githooks
28 ## TODO
30 .PHONY: style
31 style: ## Run the code styler.
32 @fourmolu -q -i Cabal Cabal-syntax cabal-install cabal-validate
34 .PHONY: style-modified
35 style-modified: ## Run the code styler on modified files.
36 @git ls-files --modified Cabal Cabal-syntax cabal-install cabal-validate \
37 | grep '.hs$$' | xargs -P $(PROCS) -I {} fourmolu -q -i {}
39 .PHONY: style-commit
40 style-commit: ## Run the code styler on the previous commit.
41 @git diff --name-only HEAD $(COMMIT) Cabal Cabal-syntax cabal-install cabal-validate \
42 | grep '.hs$$' | xargs -P $(PROCS) -I {} fourmolu -q -i {}
44 .PHONY: whitespace
45 whitespace: ## Run fix-whitespace in check mode.
46 fix-whitespace --check --verbose
48 .PHONY: fix-whitespace
49 fix-whitespace: ## Run fix-whitespace in fix mode.
50 fix-whitespace --verbose
52 .PHONY: lint
53 lint: ## Run HLint.
54 hlint -j .
56 .PHONY: lint-json
57 lint-json: ## Run HLint in JSON mode.
58 hlint -j --json -- .
60 # local checks
62 .PHONY: checks
63 checks: whitespace users-guide-typos markdown-typos style lint-json ## Run all local checks; whitespace, typos, style, and lint.
65 # source generation: SPDX
67 SPDX_LICENSE_HS:=Cabal-syntax/src/Distribution/SPDX/LicenseId.hs
68 SPDX_EXCEPTION_HS:=Cabal-syntax/src/Distribution/SPDX/LicenseExceptionId.hs
70 # Note: the 'spdx' goal is used in .github/workflows/quick-jobs.yml.
71 # Any changes to this goal need to be reconciled with this workflow.
73 .PHONY: spdx
74 spdx : $(SPDX_LICENSE_HS) $(SPDX_EXCEPTION_HS)
76 SPDX_LICENSE_VERSIONS:=3.0 3.2 3.6 3.9 3.10 3.16 3.23 3.25
78 $(SPDX_LICENSE_HS) : templates/SPDX.LicenseId.template.hs cabal-dev-scripts/src/GenUtils.hs cabal-dev-scripts/src/GenSPDX.hs license-list-data/licenses-3.0.json license-list-data/licenses-3.2.json
79 cabal run --builddir=dist-newstyle-meta --project-file=cabal.meta.project gen-spdx -- templates/SPDX.LicenseId.template.hs $(SPDX_LICENSE_VERSIONS:%=license-list-data/licenses-%.json) $(SPDX_LICENSE_HS)
81 $(SPDX_EXCEPTION_HS) : templates/SPDX.LicenseExceptionId.template.hs cabal-dev-scripts/src/GenUtils.hs cabal-dev-scripts/src/GenSPDXExc.hs license-list-data/exceptions-3.0.json license-list-data/exceptions-3.2.json
82 cabal run --builddir=dist-newstyle-meta --project-file=cabal.meta.project gen-spdx-exc -- templates/SPDX.LicenseExceptionId.template.hs $(SPDX_LICENSE_VERSIONS:%=license-list-data/exceptions-%.json) $(SPDX_EXCEPTION_HS)
84 # source generation: templates
86 TEMPLATE_MACROS:=Cabal/src/Distribution/Simple/Build/Macros/Z.hs
87 TEMPLATE_PATHS:=Cabal/src/Distribution/Simple/Build/PathsModule/Z.hs
89 # Note: the 'templates' goal is used in .github/workflows/quick-jobs.yml.
90 # Any changes to this goal need to be reconciled with this workflow.
92 .PHONY: templates
93 templates : $(TEMPLATE_MACROS) $(TEMPLATE_PATHS)
95 $(TEMPLATE_MACROS) : templates/cabal_macros.template.h cabal-dev-scripts/src/GenCabalMacros.hs
96 cabal run --builddir=dist-newstyle-meta --project-file=cabal.meta.project gen-cabal-macros -- $< $@
98 $(TEMPLATE_PATHS) : templates/Paths_pkg.template.hs cabal-dev-scripts/src/GenPathsModule.hs
99 cabal run --builddir=dist-newstyle-meta --project-file=cabal.meta.project gen-paths-module -- $< $@
101 # generated docs
102 # Use cabal build before cabal run to avoid output of the build on stdout when running
103 doc/buildinfo-fields-reference.rst : \
104 $(wildcard Cabal-syntax/src/*/*.hs Cabal-syntax/src/*/*/*.hs Cabal-syntax/src/*/*/*/*.hs) \
105 $(wildcard Cabal-described/src/Distribution/Described.hs Cabal-described/src/Distribution/Utils/*.hs) \
106 buildinfo-reference-generator/src/Main.hs \
107 buildinfo-reference-generator/template.zinza
108 cabal build buildinfo-reference-generator
109 cabal run buildinfo-reference-generator buildinfo-reference-generator/template.zinza | tee $@
110 git diff --exit-code $@
112 .PHONY: analyse-imports
113 analyse-imports :
114 find Cabal-syntax/src Cabal/src cabal-install/src -type f -name '*.hs' | xargs cabal run --builddir=dist-newstyle-meta --project-file=cabal.meta.project analyse-imports --
116 # ghcid
118 .PHONY: ghcid-lib
119 ghcid-lib: ## Run ghcid for the Cabal library.
120 ghcid -c 'cabal repl Cabal'
122 .PHONY: ghcid-cli
123 ghcid-cli: ## Run ghcid for the cabal-install executable.
124 ghcid -c 'cabal repl cabal-install'
126 .PHONY: doctest
127 doctest: ## Run doctests.
128 cd Cabal-syntax && $(DOCTEST)
129 cd Cabal-described && $(DOCTEST)
130 cd Cabal && $(DOCTEST)
131 cd cabal-install-solver && $(DOCTEST)
132 cd cabal-install && $(DOCTEST)
134 # This is not run as part of validate.sh (we need hackage-security, which is tricky to get).
135 .PHONY: doctest-cli
136 doctest-cli :
137 doctest -D__DOCTEST__ --fast cabal-install/src cabal-install-solver/src cabal-install-solver/src-assertion
139 .PHONY: doctest-install
140 doctest-install: ## Install doctest tool needed for running doctests.
141 cabal install doctest --overwrite-policy=always --ignore-project --flag cabal-doctest
143 # tests
145 .PHONY: check-tests
146 check-tests :
147 $(CABALRUN) check-tests -- --cwd Cabal-tests ${TEST}
149 .PHONY: parser-tests
150 parser-tests :
151 $(CABALRUN) parser-tests -- --cwd Cabal-tests ${TEST}
153 .PHONY: parser-tests-accept
154 parser-tests-accept :
155 $(CABALRUN) parser-tests -- --cwd Cabal-tests --accept ${TEST}
157 .PHONY: custom-setup-tests
158 custom-setup-tests :
159 $(CABALRUN) custom-setup-tests --
161 .PHONY: hackage-parsec-tests
162 hackage-parsec-tests :
163 $(CABALRUN) hackage-tests -- parsec +RTS -s -qg -I0 -A64M -N${THREADS} -RTS ${TEST}
165 .PHONY: hackage-rountrip-tests
166 hackage-roundtrip-tests :
167 $(CABALRUN) hackage-tests -- roundtrip +RTS -s -qg -I0 -A64M -N${THREADS} -RTS ${TEST}
169 .PHONY: cabal-install-test
170 cabal-install-test:
171 $(CABALBUILD) -j3 cabal-tests cabal
172 rm -rf .ghc.environment.*
173 cd cabal-testsuite && `cabal list-bin cabal-tests` --with-cabal=`cabal list-bin cabal` --hide-successes -j3 ${TEST}
175 # hackage-benchmarks (solver)
177 .PHONY: hackage-benchmarks-run
178 hackage-benchmarks-run:
179 $(CABALBUILD) -j3 hackage-benchmark cabal
180 rm -rf .ghc.environment.*
181 $$(cabal list-bin hackage-benchmark) --cabal1=cabal --cabal2=$$(cabal list-bin cabal) --packages="hakyll servant-auth-server" --print-trials --concurrently
184 # This doesn't run build, as you first need to test with cabal-install-test :)
185 .PHONY: cabal-install-test-accept
186 cabal-install-test-accept:
187 rm -rf .ghc.environment.*
188 cd cabal-testsuite && `cabal list-bin cabal-tests` --with-cabal=`cabal list-bin cabal` --hide-successes -j3 --accept ${TEST}
190 # Docker validation
192 # Use this carefully, on big machine you can say
194 # make validate-via-docker-all -j4 -O
196 .PHONY: validate-via-docker-all
197 validate-via-docker-all : validate-via-docker-8.2.2
198 validate-via-docker-all : validate-via-docker-8.4.4
199 validate-via-docker-all : validate-via-docker-8.8.4
200 validate-via-docker-all : validate-via-docker-8.10.4
202 .PHONY: validate-dockerfiles
203 validate-dockerfiles : .docker/validate-8.10.4.dockerfile
204 validate-dockerfiles : .docker/validate-8.8.4.dockerfile
205 validate-dockerfiles : .docker/validate-8.4.4.dockerfile
206 validate-dockerfiles : .docker/validate-8.2.2.dockerfile
208 .docker/validate-%.dockerfile : .docker/validate.dockerfile.zinza cabal-dev-scripts/src/GenValidateDockerfile.hs
209 cabal run --builddir=dist-newstyle-meta --project-file=cabal.meta.project gen-validate-dockerfile -- $* $< $@
211 # This is good idea anyway
212 # and we have a test relying on this limit being sufficiently small
213 DOCKERARGS:=--ulimit nofile=1024:1024
215 .PHONY: validate-via-docker-8.2.2
216 validate-via-docker-8.2.2:
217 docker build $(DOCKERARGS) -t cabal-validate:8.2.2 -f .docker/validate-8.2.2.dockerfile .
219 .PHONY: validate-via-docker-8.4.4
220 validate-via-docker-8.4.4:
221 docker build $(DOCKERARGS) -t cabal-validate:8.4.4 -f .docker/validate-8.4.4.dockerfile .
223 .PHONY: validate-via-docker-8.8.4
224 validate-via-docker-8.8.4:
225 docker build $(DOCKERARGS) -t cabal-validate:8.8.4 -f .docker/validate-8.8.4.dockerfile .
227 .PHONY: validate-via-docker-8.10.4
228 validate-via-docker-8.10.4:
229 docker build $(DOCKERARGS) -t cabal-validate:8.10.4 -f .docker/validate-8.10.4.dockerfile .
231 .PHONY: validate-via-docker-old
232 validate-via-docker-old:
233 docker build $(DOCKERARGS) -t cabal-validate:older -f .docker/validate-old.dockerfile .
235 # tags
236 .PHONY : tags
237 tags: ## Generate editor tags, vim ctags and emacs etags.
238 hasktags -b Cabal-syntax/src Cabal/src Cabal-described/src cabal-install/src cabal-testsuite/src
240 # bootstrapping
241 ##############################################################################
243 bootstrap-json-%: phony
244 cabal build --project-file=cabal.bootstrap.project --with-compiler=ghc-$* --dry-run cabal-install:exe:cabal
245 cp dist-newstyle/cache/plan.json bootstrap/linux-$*.plan.json
246 @# -v0 to avoid build output on stdout
247 cd bootstrap && cabal run -v0 cabal-bootstrap-gen -- linux-$*.plan.json \
248 | python3 -m json.tool > linux-$*.json
250 BOOTSTRAP_GHC_VERSIONS := 9.0.2 9.2.8 9.4.8 9.6.6 9.8.2
252 .PHONY: bootstrap-jsons
253 bootstrap-jsons: $(BOOTSTRAP_GHC_VERSIONS:%=bootstrap-json-%)
255 # documentation
256 ##############################################################################
258 .PHONY: users-guide
259 users-guide: ## Build the users guide.
260 $(MAKE) -C doc users-guide
262 .PHONY: users-guide-requirements
263 users-guide-requirements: ## Install the requirements for building the users guide.
264 $(MAKE) -C doc users-guide-requirements
266 ifeq ($(shell uname), Darwin)
267 PROCS := $(shell sysctl -n hw.logicalcpu)
268 else
269 PROCS := $(shell nproc)
270 endif
272 PHONY: help
273 help: ## Show the commented targets.
274 @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | \
275 sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
277 PHONY: help-banner
278 help-banner: ## Show the help banner.
279 @echo "===================================================================="
280 @echo "§ all make with no arguments also shows this banner"
281 @echo "§ help make help will list targets with descriptions"
282 @echo "===================================================================="
284 .PHONY: typos-install
285 typos-install: ## Install typos-cli for typos target using cargo
286 cargo install typos-cli
288 GREP_EXCLUDE := grep -v -E 'dist-|cabal-testsuite|python-'
289 FIND_NAMED := find . -type f -name
291 .PHONY: users-guide-typos
292 users-guide-typos: ## Find typos in users guide
293 cd doc && $(FIND_NAMED) '*.rst' | xargs typos
295 .PHONY: users-guide-fix-typos
296 users-guide-fix-typos: ## Fix typos in users guide
297 cd doc && $(FIND_NAMED) '*.rst' | xargs typos --write-changes
299 .PHONY: markdown-typos
300 markdown-typos: ## Find typos in markdown files
301 $(FIND_NAMED) '*.md' | $(GREP_EXCLUDE) | xargs typos
303 .PHONY: markdown-fix-typos
304 markdown-fix-typos: ## Fix typos in markdown files
305 $(FIND_NAMED) '*.md' | $(GREP_EXCLUDE) | xargs typos --write-changes