Commit | Line | Data |
---|---|---|
5b207de7 JM |
1 | # Usage/help |
2 | all help: | |
3 | @echo | |
4 | @echo 'USAGE:' | |
5 | @echo | |
6 | @echo 'Rules/Targets:' | |
7 | @echo | |
8 | @echo 'make "IMPL" # build all steps of IMPL' | |
a003046c | 9 | @echo 'make "build^IMPL" # build all steps of IMPL' |
5b207de7 | 10 | @echo 'make "IMPL^STEP" # build STEP of IMPL' |
a003046c | 11 | @echo 'make "build^IMPL^STEP" # build STEP of IMPL' |
5b207de7 JM |
12 | @echo |
13 | @echo 'make "test" # test all implementations' | |
14 | @echo 'make "test^IMPL" # test all steps of IMPL' | |
15 | @echo 'make "test^STEP" # test STEP for all implementations' | |
16 | @echo 'make "test^IMPL^STEP" # test STEP of IMPL' | |
17 | @echo | |
18 | @echo 'make "perf" # run microbenchmarks for all implementations' | |
19 | @echo 'make "perf^IMPL" # run microbenchmarks for IMPL' | |
20 | @echo | |
21 | @echo 'make "repl^IMPL" # run stepA of IMPL' | |
22 | @echo 'make "repl^IMPL^STEP" # test STEP of IMPL' | |
23 | @echo | |
24 | @echo 'make "clean" # run 'make clean' for all implementations' | |
25 | @echo 'make "clean^IMPL" # run 'make clean' for IMPL' | |
26 | @echo | |
27 | @echo 'make "stats" # run 'make stats' for all implementations' | |
28 | @echo 'make "stats-lisp" # run 'make stats-lisp' for all implementations' | |
29 | @echo 'make "stats^IMPL" # run 'make stats' for IMPL' | |
30 | @echo 'make "stats-lisp^IMPL" # run 'make stats-lisp' for IMPL' | |
31 | @echo | |
32 | @echo 'Options/Settings:' | |
33 | @echo | |
34 | @echo 'make MAL_IMPL=IMPL "test^mal..." # use IMPL for self-host tests' | |
35 | @echo 'make REGRESS=1 "test..." # test with previous step tests too' | |
36 | @echo 'make DOCKERIZE=1 ... # to dockerize above rules/targets' | |
e47a5ec4 | 37 | @echo 'make TEST_OPTS="--opt ..." # options to pass to runtest.py' |
5b207de7 JM |
38 | @echo |
39 | @echo 'Other:' | |
40 | @echo | |
41 | @echo 'make "docker-build^IMPL" # build docker image for IMPL' | |
42 | @echo | |
48bd82ba JM |
43 | @echo 'make "docker-shell^IMPL" # start bash shell in docker image for IMPL' |
44 | @echo | |
5b207de7 | 45 | |
31690700 JM |
46 | # |
47 | # Command line settings | |
48 | # | |
49 | ||
50 | MAL_IMPL = js | |
51 | ||
115e430d JM |
52 | # cbm or qbasic |
53 | basic_MODE = cbm | |
2d76e877 JM |
54 | # clj or cljs (Clojure vs ClojureScript/lumo) |
55 | clojure_MODE = clj | |
c424b18d JM |
56 | # gdc, ldc2, or dmd |
57 | d_MODE = gdc | |
2d76e877 JM |
58 | # python, js, cpp, or neko |
59 | haxe_MODE = neko | |
60 | # octave or matlab | |
61 | matlab_MODE = octave | |
62 | # python, python2 or python3 | |
63 | python_MODE = python | |
fea8cfff | 64 | # scheme (chibi, kawa, gauche, chicken, sagittarius, cyclone, foment) |
d09216a0 | 65 | scheme_MODE = chibi |
9a7485aa | 66 | # wasmtime wasmer lucet wax node warpy wace_libc |
dad306ed | 67 | wasm_MODE = wasmtime |
a05f7822 | 68 | |
c4269f9b JM |
69 | # Path to loccount for counting LOC stats |
70 | LOCCOUNT = loccount | |
71 | ||
337c8031 JM |
72 | # Extra options to pass to runtest.py |
73 | TEST_OPTS = | |
74 | ||
17180e85 JM |
75 | # Test with previous test files not just the test files for the |
76 | # current step. Step 0 and 1 tests are special and not included in | |
77 | # later steps. | |
5b207de7 | 78 | REGRESS = |
17180e85 | 79 | |
77fd710c | 80 | HARD= |
a1eb30fc | 81 | DEFERRABLE=1 |
46e25689 JM |
82 | OPTIONAL=1 |
83 | ||
5b207de7 JM |
84 | # Run target/rule within docker image for the implementation |
85 | DOCKERIZE = | |
a05f7822 | 86 | |
5a5357b1 | 87 | |
31690700 | 88 | # |
5a5357b1 | 89 | # Implementation specific settings |
31690700 JM |
90 | # |
91 | ||
04061e52 | 92 | IMPLS = ada ada.2 awk bash basic bbc-basic c chuck clojure coffee common-lisp cpp crystal cs d dart \ |
8ea36c89 | 93 | elisp elixir elm erlang es6 factor fantom forth fsharp go groovy gnu-smalltalk \ |
0b25243b | 94 | guile haskell haxe hy io java js jq julia kotlin livescript logo lua make mal \ |
a04e7a78 | 95 | matlab miniMAL nasm nim objc objpascal ocaml perl perl6 php picolisp pike plpgsql \ |
270f1f72 | 96 | plsql powershell ps python python.2 r racket rexx rpython ruby rust scala scheme skew \ |
bfae91cc | 97 | swift swift3 swift4 swift5 tcl ts vala vb vhdl vimscript wasm wren yorick xslt zig |
31690700 | 98 | |
a0e89ae4 JM |
99 | EXTENSION = .mal |
100 | ||
31690700 JM |
101 | step0 = step0_repl |
102 | step1 = step1_read_print | |
103 | step2 = step2_eval | |
104 | step3 = step3_env | |
105 | step4 = step4_if_fn_do | |
106 | step5 = step5_tco | |
107 | step6 = step6_file | |
108 | step7 = step7_quote | |
109 | step8 = step8_macros | |
01c97316 | 110 | step9 = step9_try |
90f618cb | 111 | stepA = stepA_mal |
31690700 | 112 | |
a0e89ae4 JM |
113 | argv_STEP = step6_file |
114 | ||
115 | ||
17180e85 JM |
116 | regress_step0 = step0 |
117 | regress_step1 = step1 | |
118 | regress_step2 = step2 | |
119 | regress_step3 = $(regress_step2) step3 | |
120 | regress_step4 = $(regress_step3) step4 | |
121 | regress_step5 = $(regress_step4) step5 | |
122 | regress_step6 = $(regress_step5) step6 | |
123 | regress_step7 = $(regress_step6) step7 | |
124 | regress_step8 = $(regress_step7) step8 | |
125 | regress_step9 = $(regress_step8) step9 | |
126 | regress_stepA = $(regress_step9) stepA | |
127 | ||
195977ce JM |
128 | step5_EXCLUDES += bash # never completes at 10,000 |
129 | step5_EXCLUDES += basic # too slow, and limited to ints of 2^16 | |
130 | step5_EXCLUDES += logo # too slow for 10,000 | |
131 | step5_EXCLUDES += make # no TCO capability (iteration or recursion) | |
132 | step5_EXCLUDES += mal # host impl dependent | |
133 | step5_EXCLUDES += matlab # never completes at 10,000 | |
134 | step5_EXCLUDES += plpgsql # too slow for 10,000 | |
135 | step5_EXCLUDES += plsql # too slow for 10,000 | |
136 | step5_EXCLUDES += powershell # too slow for 10,000 | |
137 | step5_EXCLUDES += $(if $(filter cpp,$(haxe_MODE)),haxe,) # cpp finishes 10,000, segfaults at 100,000 | |
4c50b673 | 138 | step5_EXCLUDES += xslt # iteration cannot be expressed |
dca6b585 | 139 | |
bcfd8b70 | 140 | dist_EXCLUDES += mal |
5245b079 | 141 | # TODO: still need to implement dist |
bcfd8b70 | 142 | dist_EXCLUDES += guile io julia matlab swift |
31690700 | 143 | |
5a5357b1 JM |
144 | |
145 | # Extra options to pass to runtest.py | |
69463603 | 146 | bbc-basic_TEST_OPTS = --test-timeout 60 |
77fd710c JM |
147 | guile_TEST_OPTS = --test-timeout 120 |
148 | io_TEST_OPTS = --test-timeout 120 | |
5a5357b1 JM |
149 | logo_TEST_OPTS = --start-timeout 60 --test-timeout 120 |
150 | mal_TEST_OPTS = --start-timeout 60 --test-timeout 120 | |
151 | miniMAL_TEST_OPTS = --start-timeout 60 --test-timeout 120 | |
a9f64691 | 152 | perl6_TEST_OPTS = --test-timeout=60 |
5a5357b1 JM |
153 | plpgsql_TEST_OPTS = --start-timeout 60 --test-timeout 180 |
154 | plsql_TEST_OPTS = --start-timeout 120 --test-timeout 120 | |
5a5357b1 JM |
155 | vimscript_TEST_OPTS = --test-timeout 30 |
156 | ifeq ($(MAL_IMPL),vimscript) | |
157 | mal_TEST_OPTS = --start-timeout 60 --test-timeout 180 | |
158 | else ifeq ($(MAL_IMPL),powershell) | |
159 | mal_TEST_OPTS = --start-timeout 60 --test-timeout 180 | |
160 | endif | |
4c50b673 | 161 | xslt_TEST_OPTS = --test-timeout 120 |
5a5357b1 JM |
162 | |
163 | ||
31690700 | 164 | # |
5a5357b1 | 165 | # Implementation specific utility functions |
31690700 JM |
166 | # |
167 | ||
8a19f603 JM |
168 | basic_STEP_TO_PROG_cbm = impls/basic/$($(1)).bas |
169 | basic_STEP_TO_PROG_qbasic = impls/basic/$($(1)) | |
115e430d | 170 | |
8a19f603 JM |
171 | clojure_STEP_TO_PROG_clj = impls/clojure/target/$($(1)).jar |
172 | clojure_STEP_TO_PROG_cljs = impls/clojure/src/mal/$($(1)).cljc | |
a9f64691 | 173 | |
8a19f603 JM |
174 | haxe_STEP_TO_PROG_neko = impls/haxe/$($(1)).n |
175 | haxe_STEP_TO_PROG_python = impls/haxe/$($(1)).py | |
176 | haxe_STEP_TO_PROG_cpp = impls/haxe/cpp/$($(1)) | |
177 | haxe_STEP_TO_PROG_js = impls/haxe/$($(1)).js | |
32d0a1cf | 178 | |
8a19f603 JM |
179 | scheme_STEP_TO_PROG_chibi = impls/scheme/$($(1)).scm |
180 | scheme_STEP_TO_PROG_kawa = impls/scheme/out/$($(1)).class | |
181 | scheme_STEP_TO_PROG_gauche = impls/scheme/$($(1)).scm | |
182 | scheme_STEP_TO_PROG_chicken = impls/scheme/$($(1)) | |
183 | scheme_STEP_TO_PROG_sagittarius = impls/scheme/$($(1)).scm | |
184 | scheme_STEP_TO_PROG_cyclone = impls/scheme/$($(1)) | |
185 | scheme_STEP_TO_PROG_foment = impls/scheme/$($(1)).scm | |
fea8cfff | 186 | |
17180e85 | 187 | # Map of step (e.g. "step8") to executable file for that step |
e914bc2d A |
188 | ada_STEP_TO_PROG = impls/ada/$($(1)) |
189 | ada.2_STEP_TO_PROG = impls/ada.2/$($(1)) | |
190 | awk_STEP_TO_PROG = impls/awk/$($(1)).awk | |
191 | bash_STEP_TO_PROG = impls/bash/$($(1)).sh | |
192 | basic_STEP_TO_PROG = $(basic_STEP_TO_PROG_$(basic_MODE)) | |
193 | bbc-basic_STEP_TO_PROG = impls/bbc-basic/$($(1)).bas | |
194 | c_STEP_TO_PROG = impls/c/$($(1)) | |
195 | chuck_STEP_TO_PROG = impls/chuck/$($(1)).ck | |
196 | clojure_STEP_TO_PROG = $(clojure_STEP_TO_PROG_$(clojure_MODE)) | |
197 | coffee_STEP_TO_PROG = impls/coffee/$($(1)).coffee | |
198 | common-lisp_STEP_TO_PROG = impls/common-lisp/$($(1)) | |
199 | cpp_STEP_TO_PROG = impls/cpp/$($(1)) | |
200 | crystal_STEP_TO_PROG = impls/crystal/$($(1)) | |
201 | cs_STEP_TO_PROG = impls/cs/$($(1)).exe | |
202 | d_STEP_TO_PROG = impls/d/$($(1)) | |
203 | dart_STEP_TO_PROG = impls/dart/$($(1)).dart | |
204 | elisp_STEP_TO_PROG = impls/elisp/$($(1)).el | |
205 | elixir_STEP_TO_PROG = impls/elixir/lib/mix/tasks/$($(1)).ex | |
206 | elm_STEP_TO_PROG = impls/elm/$($(1)).js | |
207 | erlang_STEP_TO_PROG = impls/erlang/$($(1)) | |
208 | es6_STEP_TO_PROG = impls/es6/$($(1)).mjs | |
209 | factor_STEP_TO_PROG = impls/factor/$($(1))/$($(1)).factor | |
210 | fantom_STEP_TO_PROG = impls/fantom/lib/fan/$($(1)).pod | |
211 | forth_STEP_TO_PROG = impls/forth/$($(1)).fs | |
212 | fsharp_STEP_TO_PROG = impls/fsharp/$($(1)).exe | |
213 | go_STEP_TO_PROG = impls/go/$($(1)) | |
214 | groovy_STEP_TO_PROG = impls/groovy/$($(1)).groovy | |
215 | gnu-smalltalk_STEP_TO_PROG = impls/gnu-smalltalk/$($(1)).st | |
216 | guile_STEP_TO_PROG = impls/guile/$($(1)).scm | |
217 | haskell_STEP_TO_PROG = impls/haskell/$($(1)) | |
218 | haxe_STEP_TO_PROG = $(haxe_STEP_TO_PROG_$(haxe_MODE)) | |
219 | hy_STEP_TO_PROG = impls/hy/$($(1)).hy | |
220 | io_STEP_TO_PROG = impls/io/$($(1)).io | |
221 | java_STEP_TO_PROG = impls/java/target/classes/mal/$($(1)).class | |
222 | js_STEP_TO_PROG = impls/js/$($(1)).js | |
223 | jq_STEP_PROG = impls/jq/$($(1)).jq | |
224 | julia_STEP_TO_PROG = impls/julia/$($(1)).jl | |
225 | kotlin_STEP_TO_PROG = impls/kotlin/$($(1)).jar | |
226 | livescript_STEP_TO_PROG = impls/livescript/$($(1)).js | |
227 | logo_STEP_TO_PROG = impls/logo/$($(1)).lg | |
228 | lua_STEP_TO_PROG = impls/lua/$($(1)).lua | |
229 | make_STEP_TO_PROG = impls/make/$($(1)).mk | |
230 | mal_STEP_TO_PROG = impls/mal/$($(1)).mal | |
231 | matlab_STEP_TO_PROG = impls/matlab/$($(1)).m | |
232 | miniMAL_STEP_TO_PROG = impls/miniMAL/$($(1)).json | |
233 | nasm_STEP_TO_PROG = impls/nasm/$($(1)) | |
234 | nim_STEP_TO_PROG = impls/nim/$($(1)) | |
235 | objc_STEP_TO_PROG = impls/objc/$($(1)) | |
236 | objpascal_STEP_TO_PROG = impls/objpascal/$($(1)) | |
237 | ocaml_STEP_TO_PROG = impls/ocaml/$($(1)) | |
238 | perl_STEP_TO_PROG = impls/perl/$($(1)).pl | |
239 | perl6_STEP_TO_PROG = impls/perl6/$($(1)).pl | |
240 | php_STEP_TO_PROG = impls/php/$($(1)).php | |
241 | picolisp_STEP_TO_PROG = impls/picolisp/$($(1)).l | |
242 | pike_STEP_TO_PROG = impls/pike/$($(1)).pike | |
243 | plpgsql_STEP_TO_PROG = impls/plpgsql/$($(1)).sql | |
244 | plsql_STEP_TO_PROG = impls/plsql/$($(1)).sql | |
245 | powershell_STEP_TO_PROG = impls/powershell/$($(1)).ps1 | |
246 | ps_STEP_TO_PROG = impls/ps/$($(1)).ps | |
247 | python_STEP_TO_PROG = impls/python/$($(1)).py | |
248 | python.2_STEP_TO_PROG = impls/python.2/$($(1)).py | |
249 | r_STEP_TO_PROG = impls/r/$($(1)).r | |
250 | racket_STEP_TO_PROG = impls/racket/$($(1)).rkt | |
251 | rexx_STEP_TO_PROG = impls/rexx/$($(1)).rexxpp | |
252 | rpython_STEP_TO_PROG = impls/rpython/$($(1)) | |
253 | ruby_STEP_TO_PROG = impls/ruby/$($(1)).rb | |
254 | rust_STEP_TO_PROG = impls/rust/$($(1)) | |
255 | scala_STEP_TO_PROG = impls/scala/target/scala-2.11/classes/$($(1)).class | |
256 | scheme_STEP_TO_PROG = $(scheme_STEP_TO_PROG_$(scheme_MODE)) | |
257 | skew_STEP_TO_PROG = impls/skew/$($(1)).js | |
258 | swift_STEP_TO_PROG = impls/swift/$($(1)) | |
259 | swift3_STEP_TO_PROG = impls/swift3/$($(1)) | |
260 | swift4_STEP_TO_PROG = impls/swift4/$($(1)) | |
261 | swift5_STEP_TO_PROG = impls/swift5/$($(1)) | |
262 | tcl_STEP_TO_PROG = impls/tcl/$($(1)).tcl | |
263 | ts_STEP_TO_PROG = impls/ts/$($(1)).js | |
264 | vala_STEP_TO_PROG = impls/vala/$($(1)) | |
265 | vb_STEP_TO_PROG = impls/vb/$($(1)).exe | |
266 | vhdl_STEP_TO_PROG = impls/vhdl/$($(1)) | |
267 | vimscript_STEP_TO_PROG = impls/vimscript/$($(1)).vim | |
268 | wasm_STEP_TO_PROG = impls/wasm/$($(1)).$(if $(filter lucet,$(wasm_MODE)),so,wasm) | |
269 | wren_STEP_TO_PROG = impls/wren/$($(1)).wren | |
270 | yorick_STEP_TO_PROG = impls/yorick/$($(1)).i | |
271 | xslt_STEP_TO_PROG = impls/xslt/$($(1)) | |
272 | zig_STEP_TO_PROG = impls/zig/$($(1)) | |
db4c329a | 273 | |
5a5357b1 JM |
274 | # |
275 | # General settings and utility functions | |
276 | # | |
277 | ||
c4033aab JM |
278 | # Needed some argument munging |
279 | COMMA = , | |
280 | noop = | |
281 | SPACE = $(noop) $(noop) | |
d1596ac2 | 282 | export FACTOR_ROOTS := . |
db4c329a | 283 | |
77fd710c | 284 | opt_HARD = $(if $(strip $(HARD)),$(if $(filter t true T True TRUE 1 y yes Yes YES,$(HARD)),--hard,),) |
5a5357b1 JM |
285 | opt_DEFERRABLE = $(if $(strip $(DEFERRABLE)),$(if $(filter t true T True TRUE 1 y yes Yes YES,$(DEFERRABLE)),--deferrable,--no-deferrable),--no-deferrable) |
286 | opt_OPTIONAL = $(if $(strip $(OPTIONAL)),$(if $(filter t true T True TRUE 1 y yes Yes YES,$(OPTIONAL)),--optional,--no-optional),--no-optional) | |
287 | ||
288 | # Return list of test files for a given step. If REGRESS is set then | |
289 | # test files will include step 2 tests through tests for the step | |
290 | # being tested. | |
291 | STEP_TEST_FILES = $(strip $(wildcard \ | |
195977ce JM |
292 | $(foreach s,$(if $(strip $(REGRESS)),\ |
293 | $(filter-out $(if $(filter $(1),$(step5_EXCLUDES)),step5,),\ | |
294 | $(regress_$(2)))\ | |
295 | ,$(2)),\ | |
8a19f603 | 296 | impls/$(1)/tests/$($(s))$(EXTENSION) impls/tests/$($(s))$(EXTENSION)))) |
5a5357b1 | 297 | |
4959b19d JM |
298 | # DOCKERIZE utility functions |
299 | lc = $(subst A,a,$(subst B,b,$(subst C,c,$(subst D,d,$(subst E,e,$(subst F,f,$(subst G,g,$(subst H,h,$(subst I,i,$(subst J,j,$(subst K,k,$(subst L,l,$(subst M,m,$(subst N,n,$(subst O,o,$(subst P,p,$(subst Q,q,$(subst R,r,$(subst S,s,$(subst T,t,$(subst U,u,$(subst V,v,$(subst W,w,$(subst X,x,$(subst Y,y,$(subst Z,z,$1)))))))))))))))))))))))))) | |
300 | impl_to_image = kanaka/mal-test-$(call lc,$(1)) | |
301 | ||
ff4e5f16 | 302 | actual_impl = $(if $(filter mal,$(1)),$(patsubst %-mal,%,$(MAL_IMPL)),$(1)) |
4959b19d | 303 | |
20e8dea0 JM |
304 | # Takes impl |
305 | # Returns nothing if DOCKERIZE is not set, otherwise returns the | |
306 | # docker prefix necessary to run make within the docker environment | |
307 | # for this impl | |
7864f19b JM |
308 | get_build_command = $(strip $(foreach mode,$(1)_MODE, \ |
309 | $(if $(strip $(DOCKERIZE)),\ | |
310 | docker run \ | |
311 | -it --rm -u $(shell id -u) \ | |
312 | -v $(dir $(abspath $(lastword $(MAKEFILE_LIST)))):/mal \ | |
8a19f603 | 313 | -w /mal/impls/$(1) \ |
7864f19b JM |
314 | $(if $(strip $($(mode))),-e $(mode)=$($(mode)),) \ |
315 | $(if $(filter factor,$(1)),-e FACTOR_ROOTS=$(FACTOR_ROOTS),) \ | |
316 | $(call impl_to_image,$(1)) \ | |
317 | $(MAKE) $(if $(strip $($(mode))),$(mode)=$($(mode)),) \ | |
318 | ,\ | |
8a19f603 | 319 | $(MAKE) $(if $(strip $($(mode))),$(mode)=$($(mode)),) -C impls/$(impl)))) |
db4c329a | 320 | |
48bd82ba | 321 | # Takes impl and step args. Optional env vars and dockerize args |
20e8dea0 JM |
322 | # Returns a command prefix (docker command and environment variables) |
323 | # necessary to launch the given impl and step | |
7864f19b JM |
324 | get_run_prefix = $(strip $(foreach mode,$(call actual_impl,$(1))_MODE, \ |
325 | $(if $(strip $(DOCKERIZE) $(4)),\ | |
326 | docker run -e STEP=$($2) -e MAL_IMPL=$(MAL_IMPL) \ | |
327 | -it --rm -u $(shell id -u) \ | |
328 | -v $(dir $(abspath $(lastword $(MAKEFILE_LIST)))):/mal \ | |
8a19f603 | 329 | -w /mal/impls/$(call actual_impl,$(1)) \ |
7864f19b JM |
330 | $(if $(strip $($(mode))),-e $(mode)=$($(mode)),) \ |
331 | $(if $(filter factor,$(1)),-e FACTOR_ROOTS=$(FACTOR_ROOTS),) \ | |
332 | $(foreach env,$(3),-e $(env)) \ | |
333 | $(call impl_to_image,$(call actual_impl,$(1))) \ | |
334 | ,\ | |
335 | env STEP=$($2) MAL_IMPL=$(MAL_IMPL) \ | |
336 | $(if $(strip $($(mode))),$(mode)=$($(mode)),) \ | |
337 | $(if $(filter factor,$(1)),FACTOR_ROOTS=$(FACTOR_ROOTS),) \ | |
338 | $(3)))) | |
20e8dea0 JM |
339 | |
340 | # Takes impl and step | |
341 | # Returns the runtest command prefix (with runtest options) for testing the given step | |
6c4cc8ad | 342 | get_runtest_cmd = $(call get_run_prefix,$(1),$(2),$(if $(filter cs fsharp mal tcl vb,$(1)),RAW=1,)) \ |
8a19f603 | 343 | ../../runtest.py $(opt_HARD) $(opt_DEFERRABLE) $(opt_OPTIONAL) $(call $(1)_TEST_OPTS) $(TEST_OPTS) |
20e8dea0 JM |
344 | |
345 | # Takes impl and step | |
346 | # Returns the runtest command prefix (with runtest options) for testing the given step | |
8a19f603 | 347 | get_argvtest_cmd = $(call get_run_prefix,$(1),$(2)) ../tests/run_argv_test.sh |
31690700 | 348 | |
31690700 | 349 | # Derived lists |
195977ce | 350 | STEPS = $(sort $(filter-out %_EXCLUDES,$(filter step%,$(.VARIABLES)))) |
8569b2af JM |
351 | DO_IMPLS = $(filter-out $(SKIP_IMPLS),$(IMPLS)) |
352 | IMPL_TESTS = $(foreach impl,$(DO_IMPLS),test^$(impl)) | |
31690700 | 353 | STEP_TESTS = $(foreach step,$(STEPS),test^$(step)) |
195977ce | 354 | ALL_TESTS = $(filter-out $(foreach e,$(step5_EXCLUDES),test^$(e)^step5),\ |
31690700 | 355 | $(strip $(sort \ |
8569b2af | 356 | $(foreach impl,$(DO_IMPLS),\ |
31690700 | 357 | $(foreach step,$(STEPS),test^$(impl)^$(step)))))) |
a003046c JM |
358 | ALL_BUILDS = $(strip $(sort \ |
359 | $(foreach impl,$(DO_IMPLS),\ | |
360 | $(foreach step,$(STEPS),build^$(impl)^$(step))))) | |
31690700 | 361 | |
cf1d3eae JM |
362 | DOCKER_BUILD = $(foreach impl,$(DO_IMPLS),docker-build^$(impl)) |
363 | ||
48bd82ba JM |
364 | DOCKER_SHELL = $(foreach impl,$(DO_IMPLS),docker-shell^$(impl)) |
365 | ||
dca6b585 | 366 | IMPL_PERF = $(foreach impl,$(filter-out $(perf_EXCLUDES),$(DO_IMPLS)),perf^$(impl)) |
db4c329a | 367 | |
c4269f9b JM |
368 | IMPL_STATS = $(foreach impl,$(DO_IMPLS),stats^$(impl)) |
369 | ||
854cf2a6 DM |
370 | IMPL_REPL = $(foreach impl,$(DO_IMPLS),repl^$(impl)) |
371 | ALL_REPL = $(strip $(sort \ | |
372 | $(foreach impl,$(DO_IMPLS),\ | |
373 | $(foreach step,$(STEPS),repl^$(impl)^$(step))))) | |
db4c329a | 374 | |
5a5357b1 | 375 | |
31690700 JM |
376 | # |
377 | # Build rules | |
378 | # | |
379 | ||
5a5357b1 JM |
380 | # Enable secondary expansion for all rules |
381 | .SECONDEXPANSION: | |
382 | ||
4fc7a281 | 383 | # Build a program in an implementation directory |
f045aba1 JM |
384 | # Make sure we always try and build first because the dependencies are |
385 | # encoded in the implementation Makefile not here | |
386 | .PHONY: $(foreach i,$(DO_IMPLS),$(foreach s,$(STEPS),$(call $(i)_STEP_TO_PROG,$(s)))) | |
4fc7a281 | 387 | $(foreach i,$(DO_IMPLS),$(foreach s,$(STEPS),$(call $(i)_STEP_TO_PROG,$(s)))): |
8a19f603 | 388 | $(foreach impl,$(word 2,$(subst /, ,$(@))),\ |
4959b19d | 389 | $(if $(DOCKERIZE), \ |
8a19f603 JM |
390 | $(call get_build_command,$(impl)) $(patsubst impls/$(impl)/%,%,$(@)), \ |
391 | $(call get_build_command,$(impl)) $(subst impls/$(impl)/,,$(@)))) | |
31690700 | 392 | |
a003046c | 393 | # Allow IMPL, build^IMPL, IMPL^STEP, and build^IMPL^STEP |
5b207de7 | 394 | $(DO_IMPLS): $$(foreach s,$$(STEPS),$$(call $$(@)_STEP_TO_PROG,$$(s))) |
31690700 | 395 | |
a003046c JM |
396 | $(foreach i,$(DO_IMPLS),$(foreach s,$(STEPS),build^$(i))): $$(foreach s,$$(STEPS),$$(call $$(word 2,$$(subst ^, ,$$(@)))_STEP_TO_PROG,$$(s))) |
397 | ||
5b207de7 JM |
398 | $(foreach i,$(DO_IMPLS),$(foreach s,$(STEPS),$(i)^$(s))): $$(call $$(word 1,$$(subst ^, ,$$(@)))_STEP_TO_PROG,$$(word 2,$$(subst ^, ,$$(@)))) |
399 | ||
a003046c JM |
400 | $(foreach i,$(DO_IMPLS),$(foreach s,$(STEPS),build^$(i)^$(s))): $$(call $$(word 2,$$(subst ^, ,$$(@)))_STEP_TO_PROG,$$(word 3,$$(subst ^, ,$$(@)))) |
401 | ||
402 | ||
5b207de7 JM |
403 | |
404 | # | |
405 | # Test rules | |
406 | # | |
31690700 | 407 | |
31690700 JM |
408 | $(ALL_TESTS): $$(call $$(word 2,$$(subst ^, ,$$(@)))_STEP_TO_PROG,$$(word 3,$$(subst ^, ,$$(@)))) |
409 | @$(foreach impl,$(word 2,$(subst ^, ,$(@))),\ | |
410 | $(foreach step,$(word 3,$(subst ^, ,$(@))),\ | |
8a19f603 JM |
411 | echo "(call STEP_TEST_FILES,$(impl),$(step)): $(call STEP_TEST_FILES,$(impl),$(step))" && \ |
412 | cd impls/$(call actual_impl,$(impl)) && \ | |
413 | $(foreach test,$(patsubst impls/%,%,$(call STEP_TEST_FILES,$(impl),$(step))),\ | |
d5221bcf | 414 | echo '----------------------------------------------' && \ |
20e8dea0 | 415 | echo 'Testing $@; step file: $+, test file: $(test)' && \ |
ba1649e4 JM |
416 | echo 'Running: $(call get_runtest_cmd,$(impl),$(step)) ../$(test) -- ../$(impl)/run' && \ |
417 | $(call get_runtest_cmd,$(impl),$(step)) ../$(test) -- ../$(impl)/run && \ | |
a0e89ae4 | 418 | $(if $(filter tests/$(argv_STEP)$(EXTENSION),$(test)),\ |
d3c401c1 DM |
419 | echo '----------------------------------------------' && \ |
420 | echo 'Testing ARGV of $@; step file: $+' && \ | |
20e8dea0 JM |
421 | echo 'Running: $(call get_argvtest_cmd,$(impl),$(step)) ../$(impl)/run ' && \ |
422 | $(call get_argvtest_cmd,$(impl),$(step)) ../$(impl)/run && ,\ | |
d3c401c1 | 423 | true && ))\ |
d5221bcf | 424 | true)) |
31690700 | 425 | |
5b207de7 | 426 | # Allow test, tests, test^STEP, test^IMPL, and test^IMPL^STEP |
31690700 JM |
427 | test: $(ALL_TESTS) |
428 | tests: $(ALL_TESTS) | |
429 | ||
5b207de7 | 430 | $(IMPL_TESTS): $$(filter $$@^%,$$(ALL_TESTS)) |
31690700 | 431 | |
5b207de7 | 432 | $(STEP_TESTS): $$(foreach step,$$(subst test^,,$$@),$$(filter %^$$(step),$$(ALL_TESTS))) |
31690700 | 433 | |
db4c329a | 434 | |
5b207de7 | 435 | # |
48bd82ba | 436 | # Docker build rules |
5b207de7 | 437 | # |
b6dc3e37 | 438 | |
48bd82ba | 439 | docker-build: $(DOCKER_BUILD) |
31690700 | 440 | |
48bd82ba | 441 | $(DOCKER_BUILD): |
712af9ef JM |
442 | @echo "----------------------------------------------"; \ |
443 | $(foreach impl,$(word 2,$(subst ^, ,$(@))),\ | |
48bd82ba | 444 | echo "Running: docker build -t $(call impl_to_image,$(impl)) .:"; \ |
8a19f603 | 445 | cd impls/$(impl) && docker build -t $(call impl_to_image,$(impl)) .) |
712af9ef | 446 | |
5b207de7 | 447 | # |
48bd82ba | 448 | # Docker shell rules |
5b207de7 | 449 | # |
cf1d3eae | 450 | |
48bd82ba JM |
451 | $(DOCKER_SHELL): |
452 | @echo "----------------------------------------------"; \ | |
cf1d3eae | 453 | $(foreach impl,$(word 2,$(subst ^, ,$(@))),\ |
48bd82ba JM |
454 | echo "Running: $(call get_run_prefix,$(impl),stepA,,dockerize) bash"; \ |
455 | $(call get_run_prefix,$(impl),stepA,,dockerize) bash) | |
db4c329a | 456 | |
5b207de7 JM |
457 | |
458 | # | |
db4c329a | 459 | # Performance test rules |
5b207de7 | 460 | # |
db4c329a JM |
461 | |
462 | perf: $(IMPL_PERF) | |
463 | ||
db4c329a JM |
464 | $(IMPL_PERF): |
465 | @echo "----------------------------------------------"; \ | |
466 | $(foreach impl,$(word 2,$(subst ^, ,$(@))),\ | |
8a19f603 | 467 | cd impls/$(call actual_impl,$(impl)); \ |
db4c329a | 468 | echo "Performance test for $(impl):"; \ |
20e8dea0 JM |
469 | echo 'Running: $(call get_run_prefix,$(impl),stepA) ../$(impl)/run ../tests/perf1.mal'; \ |
470 | $(call get_run_prefix,$(impl),stepA) ../$(impl)/run ../tests/perf1.mal; \ | |
471 | echo 'Running: $(call get_run_prefix,$(impl),stepA) ../$(impl)/run ../tests/perf2.mal'; \ | |
472 | $(call get_run_prefix,$(impl),stepA) ../$(impl)/run ../tests/perf2.mal; \ | |
473 | echo 'Running: $(call get_run_prefix,$(impl),stepA) ../$(impl)/run ../tests/perf3.mal'; \ | |
474 | $(call get_run_prefix,$(impl),stepA) ../$(impl)/run ../tests/perf3.mal) | |
db4c329a | 475 | |
854cf2a6 | 476 | |
5b207de7 | 477 | # |
854cf2a6 | 478 | # REPL invocation rules |
5b207de7 | 479 | # |
854cf2a6 | 480 | |
854cf2a6 DM |
481 | $(ALL_REPL): $$(call $$(word 2,$$(subst ^, ,$$(@)))_STEP_TO_PROG,$$(word 3,$$(subst ^, ,$$(@)))) |
482 | @$(foreach impl,$(word 2,$(subst ^, ,$(@))),\ | |
483 | $(foreach step,$(word 3,$(subst ^, ,$(@))),\ | |
8a19f603 | 484 | cd impls/$(call actual_impl,$(impl)); \ |
854cf2a6 | 485 | echo 'REPL implementation $(impl), step file: $+'; \ |
5a5357b1 JM |
486 | echo 'Running: $(call get_run_prefix,$(impl),$(step)) ../$(impl)/run $(RUN_ARGS)'; \ |
487 | $(call get_run_prefix,$(impl),$(step)) ../$(impl)/run $(RUN_ARGS);)) | |
bcfd8b70 | 488 | |
5b207de7 | 489 | # Allow repl^IMPL^STEP and repl^IMPL (which starts REPL of stepA) |
5b207de7 JM |
490 | $(IMPL_REPL): $$@^stepA |
491 | ||
c4269f9b JM |
492 | # |
493 | # Stats test rules | |
494 | # | |
495 | ||
496 | # For a concise summary: | |
497 | # make stats | egrep -A1 "^Stats for|^all" | egrep -v "^all|^--" | |
498 | stats: $(IMPL_STATS) | |
499 | ||
500 | $(IMPL_STATS): | |
501 | @$(foreach impl,$(word 2,$(subst ^, ,$(@))),\ | |
502 | echo "Stats for $(impl):"; \ | |
8a19f603 | 503 | $(LOCCOUNT) -x "[sS]tep[0-9]_.*|[.]md$$|tests|examples|Makefile|package.json|tsconfig.json|Cargo.toml|project.clj|node_modules|getline.cs|terminal.cs|elm-stuff|objpascal/regexpr|rdyncall|swift/templates" impls/$(impl)) |
c4269f9b | 504 | |
dca6b585 JM |
505 | # |
506 | # Utility functions | |
507 | # | |
dca6b585 JM |
508 | print-%: |
509 | @echo "$($(*))" | |
bcfd8b70 | 510 | |
5b207de7 | 511 | # |
bcfd8b70 | 512 | # Recursive rules (call make FOO in each subdirectory) |
5b207de7 | 513 | # |
bcfd8b70 JM |
514 | |
515 | define recur_template | |
516 | .PHONY: $(1) | |
517 | $(1): $(2) | |
bcfd8b70 JM |
518 | $(2): |
519 | @echo "----------------------------------------------"; \ | |
520 | $$(foreach impl,$$(word 2,$$(subst ^, ,$$(@))),\ | |
7864f19b JM |
521 | echo "Running: $$(call get_build_command,$$(impl)) --no-print-directory $(1)"; \ |
522 | $$(call get_build_command,$$(impl)) --no-print-directory $(1)) | |
bcfd8b70 JM |
523 | endef |
524 | ||
525 | recur_impls_ = $(filter-out $(foreach impl,$($(1)_EXCLUDES),$(1)^$(impl)),$(foreach impl,$(IMPLS),$(1)^$(impl))) | |
526 | ||
527 | # recursive clean | |
528 | $(eval $(call recur_template,clean,$(call recur_impls_,clean))) | |
529 | ||
bcfd8b70 JM |
530 | # recursive dist |
531 | $(eval $(call recur_template,dist,$(call recur_impls_,dist))) |