8 @echo
'make "IMPL" # build all steps of IMPL'
9 @echo
'make "build^IMPL" # build all steps of IMPL'
10 @echo
'make "IMPL^STEP" # build STEP of IMPL'
11 @echo
'make "build^IMPL^STEP" # build STEP of IMPL'
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'
18 @echo
'make "perf" # run microbenchmarks for all implementations'
19 @echo
'make "perf^IMPL" # run microbenchmarks for IMPL'
21 @echo
'make "repl^IMPL" # run stepA of IMPL'
22 @echo
'make "repl^IMPL^STEP" # test STEP of IMPL'
24 @echo
'make "clean" # run 'make
clean' for all implementations'
25 @echo
'make "clean^IMPL" # run 'make
clean' for IMPL'
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'
32 @echo
'Options/Settings:'
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'
37 @echo
'make TEST_OPTS="--opt ..." # options to pass to runtest.py'
41 @echo
'make "docker-build^IMPL" # build docker image for IMPL'
43 @echo
'make "docker-shell^IMPL" # start bash shell in docker image for IMPL'
47 # Command line settings
54 # clj or cljs (Clojure vs ClojureScript/lumo)
58 # python, js, cpp, or neko
62 # python, python2 or python3
64 # scheme (chibi, kawa, gauche, chicken, sagittarius, cyclone, foment)
66 # wasmtime wasmer lucet wax node warpy wace_libc
69 # Path to loccount for counting LOC stats
72 # Extra options to pass to runtest.py
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
84 # Run target/rule within docker image for the implementation
89 # Implementation specific settings
92 IMPLS
= ada ada
.2 awk bash basic bbc-basic c chuck clojure coffee common-lisp
cpp crystal cs d dart \
93 elisp elixir elm erlang es6 factor fantom forth fsharp go groovy gnu-smalltalk \
94 guile haskell haxe hy io java js jq julia kotlin livescript logo lua make mal \
95 matlab miniMAL nasm nim objc objpascal ocaml perl perl6 php picolisp pike plpgsql \
96 plsql powershell ps python python
.2 r racket rexx rpython ruby rust scala scheme skew \
97 swift swift3 swift4 swift5 tcl ts vala vb vhdl vimscript wasm wren yorick xslt zig
102 step1
= step1_read_print
105 step4
= step4_if_fn_do
113 argv_STEP
= step6_file
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
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
138 step5_EXCLUDES
+= xslt
# iteration cannot be expressed
141 # TODO: still need to implement dist
142 dist_EXCLUDES
+= guile io julia matlab swift
145 # Extra options to pass to runtest.py
146 bbc-basic_TEST_OPTS
= --test-timeout
60
147 guile_TEST_OPTS
= --test-timeout
120
148 io_TEST_OPTS
= --test-timeout
120
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
152 perl6_TEST_OPTS
= --test-timeout
=60
153 plpgsql_TEST_OPTS
= --start-timeout
60 --test-timeout
180
154 plsql_TEST_OPTS
= --start-timeout
120 --test-timeout
120
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
161 xslt_TEST_OPTS
= --test-timeout
120
165 # Implementation specific utility functions
168 basic_STEP_TO_PROG_cbm
= impls
/basic
/$($(1)).bas
169 basic_STEP_TO_PROG_qbasic
= impls
/basic
/$($(1))
171 clojure_STEP_TO_PROG_clj
= impls
/clojure
/target
/$($(1)).jar
172 clojure_STEP_TO_PROG_cljs
= impls
/clojure
/src
/mal
/$($(1)).cljc
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
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
187 # Map of step (e.g. "step8") to executable file for that step
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))
275 # General settings and utility functions
278 # Needed some argument munging
281 SPACE
= $(noop
) $(noop
)
282 export FACTOR_ROOTS
:= .
284 opt_HARD
= $(if
$(strip $(HARD
)),$(if
$(filter t true T True TRUE
1 y yes Yes YES
,$(HARD
)),--hard
,),)
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
)
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
291 STEP_TEST_FILES
= $(strip $(wildcard \
292 $(foreach s
,$(if
$(strip $(REGRESS
)),\
293 $(filter-out $(if
$(filter $(1),$(step5_EXCLUDES
)),step5
,),\
296 impls
/$(1)/tests
/$($(s
))$(EXTENSION
) impls
/tests
/$($(s
))$(EXTENSION
))))
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))
302 actual_impl
= $(if
$(filter mal
,$(1)),$(patsubst %-mal
,%,$(MAL_IMPL
)),$(1))
305 # Returns nothing if DOCKERIZE is not set, otherwise returns the
306 # docker prefix necessary to run make within the docker environment
308 get_build_command
= $(strip $(foreach mode
,$(1)_MODE
, \
309 $(if
$(strip $(DOCKERIZE
)),\
311 -it
--rm -u
$(shell id
-u
) \
312 -v
$(dir $(abspath
$(lastword
$(MAKEFILE_LIST
)))):/mal \
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
)),) \
319 $(MAKE
) $(if
$(strip $($(mode
))),$(mode
)=$($(mode
)),) -C impls
/$(impl
))))
321 # Takes impl and step args. Optional env vars and dockerize args
322 # Returns a command prefix (docker command and environment variables)
323 # necessary to launch the given impl and step
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 \
329 -w
/mal
/impls
/$(call actual_impl
,$(1)) \
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))) \
335 env STEP
=$($2) MAL_IMPL
=$(MAL_IMPL
) \
336 $(if
$(strip $($(mode
))),$(mode
)=$($(mode
)),) \
337 $(if
$(filter factor
,$(1)),FACTOR_ROOTS
=$(FACTOR_ROOTS
),) \
340 # Takes impl and step
341 # Returns the runtest command prefix (with runtest options) for testing the given step
342 get_runtest_cmd
= $(call get_run_prefix
,$(1),$(2),$(if
$(filter cs fsharp mal tcl vb
,$(1)),RAW
=1,)) \
343 ..
/..
/runtest.py
$(opt_HARD
) $(opt_DEFERRABLE
) $(opt_OPTIONAL
) $(call
$(1)_TEST_OPTS
) $(TEST_OPTS
)
345 # Takes impl and step
346 # Returns the runtest command prefix (with runtest options) for testing the given step
347 get_argvtest_cmd
= $(call get_run_prefix
,$(1),$(2)) ..
/tests
/run_argv_test.sh
350 STEPS
= $(sort $(filter-out %_EXCLUDES
,$(filter step
%,$(.VARIABLES
))))
351 DO_IMPLS
= $(filter-out $(SKIP_IMPLS
),$(IMPLS
))
352 IMPL_TESTS
= $(foreach impl
,$(DO_IMPLS
),test^
$(impl
))
353 STEP_TESTS
= $(foreach step
,$(STEPS
),test^
$(step
))
354 ALL_TESTS
= $(filter-out $(foreach e
,$(step5_EXCLUDES
),test^
$(e
)^step5
),\
356 $(foreach impl
,$(DO_IMPLS
),\
357 $(foreach step
,$(STEPS
),test^
$(impl
)^
$(step
))))))
358 ALL_BUILDS
= $(strip $(sort \
359 $(foreach impl
,$(DO_IMPLS
),\
360 $(foreach step
,$(STEPS
),build^
$(impl
)^
$(step
)))))
362 DOCKER_BUILD
= $(foreach impl
,$(DO_IMPLS
),docker-build^
$(impl
))
364 DOCKER_SHELL
= $(foreach impl
,$(DO_IMPLS
),docker-shell^
$(impl
))
366 IMPL_PERF
= $(foreach impl
,$(filter-out $(perf_EXCLUDES
),$(DO_IMPLS
)),perf^
$(impl
))
368 IMPL_STATS
= $(foreach impl
,$(DO_IMPLS
),stats^
$(impl
))
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
)))))
380 # Enable secondary expansion for all rules
383 # Build a program in an implementation directory
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
))))
387 $(foreach i
,$(DO_IMPLS
),$(foreach s
,$(STEPS
),$(call
$(i
)_STEP_TO_PROG
,$(s
)))):
388 $(foreach impl
,$(word 2,$(subst /, ,$(@
))),\
390 $(call get_build_command
,$(impl
)) $(patsubst impls
/$(impl
)/%,%,$(@
)), \
391 $(call get_build_command
,$(impl
)) $(subst impls
/$(impl
)/,,$(@
))))
393 # Allow IMPL, build^IMPL, IMPL^STEP, and build^IMPL^STEP
394 $(DO_IMPLS
): $$(foreach s
,$$(STEPS
),$$(call
$$(@
)_STEP_TO_PROG
,$$(s
)))
396 $(foreach i
,$(DO_IMPLS
),$(foreach s
,$(STEPS
),build^
$(i
))): $$(foreach s
,$$(STEPS
),$$(call
$$(word 2,$$(subst ^
, ,$$(@
)))_STEP_TO_PROG
,$$(s
)))
398 $(foreach i
,$(DO_IMPLS
),$(foreach s
,$(STEPS
),$(i
)^
$(s
))): $$(call
$$(word 1,$$(subst ^
, ,$$(@
)))_STEP_TO_PROG
,$$(word 2,$$(subst ^
, ,$$(@
))))
400 $(foreach i
,$(DO_IMPLS
),$(foreach s
,$(STEPS
),build^
$(i
)^
$(s
))): $$(call
$$(word 2,$$(subst ^
, ,$$(@
)))_STEP_TO_PROG
,$$(word 3,$$(subst ^
, ,$$(@
))))
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 ^
, ,$(@
))),\
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
))),\
414 echo
'----------------------------------------------' && \
415 echo
'Testing $@; step file: $+, test file: $(test)' && \
416 echo
'Running: $(call get_runtest_cmd,$(impl),$(step)) ../$(test) -- ../$(impl)/run' && \
417 $(call get_runtest_cmd
,$(impl
),$(step
)) ..
/$(test) -- ..
/$(impl
)/run
&& \
418 $(if
$(filter tests
/$(argv_STEP
)$(EXTENSION
),$(test)),\
419 echo
'----------------------------------------------' && \
420 echo
'Testing ARGV of $@; step file: $+' && \
421 echo
'Running: $(call get_argvtest_cmd,$(impl),$(step)) ../$(impl)/run ' && \
422 $(call get_argvtest_cmd
,$(impl
),$(step
)) ..
/$(impl
)/run
&& ,\
426 # Allow test, tests, test^STEP, test^IMPL, and test^IMPL^STEP
430 $(IMPL_TESTS
): $$(filter $$@^
%,$$(ALL_TESTS
))
432 $(STEP_TESTS
): $$(foreach step
,$$(subst test^
,,$$@
),$$(filter %^
$$(step
),$$(ALL_TESTS
)))
439 docker-build
: $(DOCKER_BUILD
)
442 @echo
"----------------------------------------------"; \
443 $(foreach impl
,$(word 2,$(subst ^
, ,$(@
))),\
444 echo
"Running: docker build -t $(call impl_to_image,$(impl)) .:"; \
445 cd impls
/$(impl
) && docker build
-t
$(call impl_to_image
,$(impl
)) .
)
452 @echo
"----------------------------------------------"; \
453 $(foreach impl
,$(word 2,$(subst ^
, ,$(@
))),\
454 echo
"Running: $(call get_run_prefix,$(impl),stepA,,dockerize) bash"; \
455 $(call get_run_prefix
,$(impl
),stepA
,,dockerize
) bash
)
459 # Performance test rules
465 @echo
"----------------------------------------------"; \
466 $(foreach impl
,$(word 2,$(subst ^
, ,$(@
))),\
467 cd impls
/$(call actual_impl
,$(impl
)); \
468 echo
"Performance test for $(impl):"; \
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
)
478 # REPL invocation rules
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 ^
, ,$(@
))),\
484 cd impls
/$(call actual_impl
,$(impl
)); \
485 echo
'REPL implementation $(impl), step file: $+'; \
486 echo
'Running: $(call get_run_prefix,$(impl),$(step)) ../$(impl)/run $(RUN_ARGS)'; \
487 $(call get_run_prefix
,$(impl
),$(step
)) ..
/$(impl
)/run
$(RUN_ARGS
);))
489 # Allow repl^IMPL^STEP and repl^IMPL (which starts REPL of stepA)
490 $(IMPL_REPL
): $$@^stepA
496 # For a concise summary:
497 # make stats | egrep -A1 "^Stats for|^all" | egrep -v "^all|^--"
501 @
$(foreach impl
,$(word 2,$(subst ^
, ,$(@
))),\
502 echo
"Stats for $(impl):"; \
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
))
512 # Recursive rules (call make FOO in each subdirectory)
515 define recur_template
519 @echo
"----------------------------------------------"; \
520 $$(foreach impl
,$$(word 2,$$(subst ^
, ,$$(@
))),\
521 echo
"Running: $$(call get_build_command,$$(impl)) --no-print-directory $(1)"; \
522 $$(call get_build_command
,$$(impl
)) --no-print-directory
$(1))
525 recur_impls_
= $(filter-out $(foreach impl
,$($(1)_EXCLUDES
),$(1)^
$(impl
)),$(foreach impl
,$(IMPLS
),$(1)^
$(impl
)))
528 $(eval
$(call recur_template
,clean,$(call recur_impls_
,clean)))
531 $(eval
$(call recur_template
,dist,$(call recur_impls_
,dist)))