2016-03-08 08:33:45 +03:00
# Usage/help
all help :
@echo
@echo 'USAGE:'
@echo
@echo 'Rules/Targets:'
@echo
@echo 'make "IMPL" # build all steps of IMPL'
@echo 'make "IMPL^STEP" # build STEP of IMPL'
@echo
@echo 'make "test" # test all implementations'
@echo 'make "test^IMPL" # test all steps of IMPL'
@echo 'make "test^STEP" # test STEP for all implementations'
@echo 'make "test^IMPL^STEP" # test STEP of IMPL'
@echo
@echo 'make "perf" # run microbenchmarks for all implementations'
@echo 'make "perf^IMPL" # run microbenchmarks for IMPL'
@echo
@echo 'make "repl^IMPL" # run stepA of IMPL'
@echo 'make "repl^IMPL^STEP" # test STEP of IMPL'
@echo
@echo 'make "clean" # run ' make clean' for all implementations'
@echo 'make "clean^IMPL" # run ' make clean' for IMPL'
@echo
@echo 'make "stats" # run ' make stats' for all implementations'
@echo 'make "stats-lisp" # run ' make stats-lisp' for all implementations'
@echo 'make "stats^IMPL" # run ' make stats' for IMPL'
@echo 'make "stats-lisp^IMPL" # run ' make stats-lisp' for IMPL'
@echo
@echo 'Options/Settings:'
@echo
@echo 'make MAL_IMPL=IMPL "test^mal..." # use IMPL for self-host tests'
@echo 'make REGRESS=1 "test..." # test with previous step tests too'
@echo 'make DOCKERIZE=1 ... # to dockerize above rules/targets'
2019-01-30 20:56:01 +03:00
@echo 'make TEST_OPTS="--opt ..." # options to pass to runtest.py'
2016-03-08 08:33:45 +03:00
@echo
@echo 'Other:'
@echo
@echo 'make "docker-build^IMPL" # build docker image for IMPL'
@echo
2017-09-15 07:37:26 +03:00
@echo 'make "docker-shell^IMPL" # start bash shell in docker image for IMPL'
@echo
2016-03-08 08:33:45 +03:00
2014-03-25 01:32:24 +04:00
#
# Command line settings
#
MAL_IMPL = js
2017-09-15 07:50:15 +03:00
# cbm or qbasic
basic_MODE = cbm
2017-09-12 01:49:26 +03:00
# clj or cljs (Clojure vs ClojureScript/lumo)
clojure_MODE = clj
# python, js, cpp, or neko
haxe_MODE = neko
# octave or matlab
matlab_MODE = octave
# python, python2 or python3
python_MODE = python
2017-09-13 17:49:15 +03:00
# scheme (chibi, kawa, gauche, chicken, sagittarius, cyclone, foment)
2017-09-13 21:14:50 +03:00
scheme_MODE = chibi
2018-12-10 09:30:59 +03:00
# js wace_libc wace_fooboot
2018-12-10 07:55:49 +03:00
wasm_MODE = wace_libc
2014-04-17 07:42:17 +04:00
2015-10-09 19:14:51 +03:00
# Extra options to pass to runtest.py
TEST_OPTS =
2015-12-19 02:24:02 +03:00
# Test with previous test files not just the test files for the
# current step. Step 0 and 1 tests are special and not included in
# later steps.
2016-03-08 08:33:45 +03:00
REGRESS =
2015-12-19 02:24:02 +03:00
2016-05-10 18:26:39 +03:00
DEFERRABLE = 1
2016-05-10 02:00:49 +03:00
OPTIONAL = 1
2016-03-08 08:33:45 +03:00
# Run target/rule within docker image for the implementation
DOCKERIZE =
2014-04-17 07:42:17 +04:00
2017-09-15 07:36:25 +03:00
2014-03-25 01:32:24 +04:00
#
2017-09-15 07:36:25 +03:00
# Implementation specific settings
2014-03-25 01:32:24 +04:00
#
2017-09-25 23:25:47 +03:00
IMPLS = ada awk bash basic c chuck clojure coffee common-lisp cpp crystal cs d dart \
2018-06-17 20:54:54 +03:00
elisp elixir elm erlang es6 factor fantom forth fsharp go groovy gnu-smalltalk \
guile haskell haxe hy io java js julia kotlin livescript logo lua make mal \
matlab miniMAL nasm nim objc objpascal ocaml perl perl6 php picolisp plpgsql \
plsql powershell ps python r racket rexx rpython ruby rust scala scheme skew \
2018-10-13 08:26:38 +03:00
swift swift3 tcl ts vb vhdl vimscript wasm yorick
2014-03-25 01:32:24 +04:00
2017-02-11 09:15:34 +03:00
EXTENSION = .mal
2014-03-25 01:32:24 +04:00
step0 = step0_repl
step1 = step1_read_print
step2 = step2_eval
step3 = step3_env
step4 = step4_if_fn_do
step5 = step5_tco
step6 = step6_file
step7 = step7_quote
step8 = step8_macros
2014-10-10 08:48:47 +04:00
step9 = step9_try
2015-02-28 20:09:54 +03:00
stepA = stepA_mal
2014-03-25 01:32:24 +04:00
2017-02-11 09:15:34 +03:00
argv_STEP = step6_file
2015-12-19 02:24:02 +03:00
regress_step0 = step0
regress_step1 = step1
regress_step2 = step2
regress_step3 = $( regress_step2) step3
regress_step4 = $( regress_step3) step4
regress_step5 = $( regress_step4) step5
regress_step6 = $( regress_step5) step6
regress_step7 = $( regress_step6) step7
regress_step8 = $( regress_step7) step8
regress_step9 = $( regress_step8) step9
regress_stepA = $( regress_step9) stepA
2019-02-27 02:38:05 +03:00
step5_EXCLUDES += bash # never completes at 10,000
step5_EXCLUDES += basic # too slow, and limited to ints of 2^16
step5_EXCLUDES += logo # too slow for 10,000
step5_EXCLUDES += make # no TCO capability (iteration or recursion)
step5_EXCLUDES += mal # host impl dependent
step5_EXCLUDES += matlab # never completes at 10,000
step5_EXCLUDES += plpgsql # too slow for 10,000
step5_EXCLUDES += plsql # too slow for 10,000
step5_EXCLUDES += powershell # too slow for 10,000
step5_EXCLUDES += $( if $( filter cpp,$( haxe_MODE) ) ,haxe,) # cpp finishes 10,000, segfaults at 100,000
2016-03-15 07:39:21 +03:00
2016-02-24 10:05:44 +03:00
dist_EXCLUDES += mal
2016-02-18 09:33:19 +03:00
# TODO: still need to implement dist
2016-02-24 10:05:44 +03:00
dist_EXCLUDES += guile io julia matlab swift
2014-03-25 01:32:24 +04:00
2017-09-15 07:36:25 +03:00
# Extra options to pass to runtest.py
logo_TEST_OPTS = --start-timeout 60 --test-timeout 120
mal_TEST_OPTS = --start-timeout 60 --test-timeout 120
miniMAL_TEST_OPTS = --start-timeout 60 --test-timeout 120
2017-09-25 23:25:47 +03:00
perl6_TEST_OPTS = --test-timeout= 60
2017-09-15 07:36:25 +03:00
plpgsql_TEST_OPTS = --start-timeout 60 --test-timeout 180
plsql_TEST_OPTS = --start-timeout 120 --test-timeout 120
vimscript_TEST_OPTS = --test-timeout 30
i f e q ( $( MAL_IMPL ) , v i m s c r i p t )
mal_TEST_OPTS = --start-timeout 60 --test-timeout 180
e l s e i f e q ( $( MAL_IMPL ) , p o w e r s h e l l )
mal_TEST_OPTS = --start-timeout 60 --test-timeout 180
e n d i f
2014-03-25 01:32:24 +04:00
#
2017-09-15 07:36:25 +03:00
# Implementation specific utility functions
2014-03-25 01:32:24 +04:00
#
2017-09-15 07:50:15 +03:00
basic_STEP_TO_PROG_cbm = basic/$( $( 1) ) .bas
basic_STEP_TO_PROG_qbasic = basic/$( $( 1) )
2017-09-25 23:25:47 +03:00
clojure_STEP_TO_PROG_clj = clojure/target/$( $( 1) ) .jar
clojure_STEP_TO_PROG_cljs = clojure/src/mal/$( $( 1) ) .cljc
2016-01-26 08:37:47 +03:00
haxe_STEP_TO_PROG_neko = haxe/$( $( 1) ) .n
haxe_STEP_TO_PROG_python = haxe/$( $( 1) ) .py
haxe_STEP_TO_PROG_cpp = haxe/cpp/$( $( 1) )
haxe_STEP_TO_PROG_js = haxe/$( $( 1) ) .js
2017-09-13 17:49:15 +03:00
scheme_STEP_TO_PROG_chibi = scheme/$( $( 1) ) .scm
scheme_STEP_TO_PROG_kawa = scheme/out/$( $( 1) ) .class
scheme_STEP_TO_PROG_gauche = scheme/$( $( 1) ) .scm
scheme_STEP_TO_PROG_chicken = scheme/$( $( 1) )
scheme_STEP_TO_PROG_sagittarius = scheme/$( $( 1) ) .scm
scheme_STEP_TO_PROG_cyclone = scheme/$( $( 1) )
scheme_STEP_TO_PROG_foment = scheme/$( $( 1) ) .scm
2015-12-19 02:24:02 +03:00
# Map of step (e.g. "step8") to executable file for that step
2015-03-06 00:50:10 +03:00
ada_STEP_TO_PROG = ada/$( $( 1) )
2015-08-26 04:13:25 +03:00
awk_STEP_TO_PROG = awk/$( $( 1) ) .awk
2014-04-18 06:49:07 +04:00
bash_STEP_TO_PROG = bash/$( $( 1) ) .sh
2017-09-15 07:50:15 +03:00
basic_STEP_TO_PROG = $( basic_STEP_TO_PROG_$( basic_MODE) )
2014-04-18 06:49:07 +04:00
c_STEP_TO_PROG = c/$( $( 1) )
2016-04-20 23:31:28 +03:00
chuck_STEP_TO_PROG = chuck/$( $( 1) ) .ck
2017-09-12 01:49:26 +03:00
clojure_STEP_TO_PROG = $( clojure_STEP_TO_PROG_$( clojure_MODE) )
2014-11-09 01:56:36 +03:00
coffee_STEP_TO_PROG = coffee/$( $( 1) ) .coffee
2016-08-25 19:56:26 +03:00
common-lisp_STEP_TO_PROG = common-lisp/$( $( 1) )
2015-03-26 14:08:35 +03:00
cpp_STEP_TO_PROG = cpp/$( $( 1) )
2015-05-29 20:07:59 +03:00
crystal_STEP_TO_PROG = crystal/$( $( 1) )
2014-04-18 06:49:07 +04:00
cs_STEP_TO_PROG = cs/$( $( 1) ) .exe
2017-09-25 23:25:47 +03:00
d_STEP_TO_PROG = d/$( $( 1) )
2016-11-14 01:21:44 +03:00
dart_STEP_TO_PROG = dart/$( $( 1) ) .dart
2016-02-28 23:21:38 +03:00
elisp_STEP_TO_PROG = elisp/$( $( 1) ) .el
2015-08-29 01:15:46 +03:00
elixir_STEP_TO_PROG = elixir/lib/mix/tasks/$( $( 1) ) .ex
2017-09-25 23:25:47 +03:00
elm_STEP_TO_PROG = elm/$( $( 1) ) .js
2015-03-15 17:13:47 +03:00
erlang_STEP_TO_PROG = erlang/$( $( 1) )
2017-09-28 06:10:24 +03:00
es6_STEP_TO_PROG = es6/$( $( 1) ) .mjs
2015-10-29 02:16:43 +03:00
factor_STEP_TO_PROG = factor/$( $( 1) ) /$( $( 1) ) .factor
2018-04-29 15:53:32 +03:00
fantom_STEP_TO_PROG = fantom/lib/fan/$( $( 1) ) .pod
2015-02-06 08:38:34 +03:00
forth_STEP_TO_PROG = forth/$( $( 1) ) .fs
2015-02-22 06:43:40 +03:00
fsharp_STEP_TO_PROG = fsharp/$( $( 1) ) .exe
2014-10-05 03:34:26 +04:00
go_STEP_TO_PROG = go/$( $( 1) )
2015-05-19 05:54:18 +03:00
groovy_STEP_TO_PROG = groovy/$( $( 1) ) .groovy
2018-06-17 20:54:54 +03:00
gnu-smalltalk_STEP_TO_PROG = gnu-smalltalk/$( $( 1) ) .st
2017-09-25 23:25:47 +03:00
guile_STEP_TO_PROG = guile/$( $( 1) ) .scm
2014-12-24 06:35:48 +03:00
haskell_STEP_TO_PROG = haskell/$( $( 1) )
2017-09-12 01:49:26 +03:00
haxe_STEP_TO_PROG = $( haxe_STEP_TO_PROG_$( haxe_MODE) )
2017-09-20 06:35:59 +03:00
hy_STEP_TO_PROG = hy/$( $( 1) ) .hy
2016-02-17 05:02:12 +03:00
io_STEP_TO_PROG = io/$( $( 1) ) .io
2017-09-25 23:25:47 +03:00
java_STEP_TO_PROG = java/target/classes/mal/$( $( 1) ) .class
2014-04-18 06:49:07 +04:00
js_STEP_TO_PROG = js/$( $( 1) ) .js
2017-09-25 23:25:47 +03:00
julia_STEP_TO_PROG = julia/$( $( 1) ) .jl
2015-10-25 06:10:53 +03:00
kotlin_STEP_TO_PROG = kotlin/$( $( 1) ) .jar
2017-09-25 23:25:47 +03:00
livescript_STEP_TO_PROG = livescript/$( $( 1) ) .js
logo_STEP_TO_PROG = logo/$( $( 1) ) .lg
2015-01-09 08:25:40 +03:00
lua_STEP_TO_PROG = lua/$( $( 1) ) .lua
2014-04-18 06:49:07 +04:00
make_STEP_TO_PROG = make/$( $( 1) ) .mk
mal_STEP_TO_PROG = mal/$( $( 1) ) .mal
2015-02-08 05:32:06 +03:00
matlab_STEP_TO_PROG = matlab/$( $( 1) ) .m
2015-02-12 06:56:47 +03:00
miniMAL_STEP_TO_PROG = miniMAL/$( $( 1) ) .json
2017-10-09 02:10:03 +03:00
nasm_STEP_TO_PROG = nasm/$( $( 1) )
2015-03-15 01:14:32 +03:00
nim_STEP_TO_PROG = nim/$( $( 1) )
2016-03-06 10:16:32 +03:00
objc_STEP_TO_PROG = objc/$( $( 1) )
2016-03-14 00:59:46 +03:00
objpascal_STEP_TO_PROG = objpascal/$( $( 1) )
2017-09-25 23:25:47 +03:00
ocaml_STEP_TO_PROG = ocaml/$( $( 1) )
2014-04-20 00:12:13 +04:00
perl_STEP_TO_PROG = perl/$( $( 1) ) .pl
2016-06-07 00:11:29 +03:00
perl6_STEP_TO_PROG = perl6/$( $( 1) ) .pl
2014-04-18 06:49:07 +04:00
php_STEP_TO_PROG = php/$( $( 1) ) .php
2018-06-17 20:54:54 +03:00
picolisp_STEP_TO_PROG = picolisp/$( $( 1) ) .l
2016-03-22 04:28:08 +03:00
plpgsql_STEP_TO_PROG = plpgsql/$( $( 1) ) .sql
2016-04-01 05:29:47 +03:00
plsql_STEP_TO_PROG = plsql/$( $( 1) ) .sql
2016-08-20 23:09:19 +03:00
powershell_STEP_TO_PROG = powershell/$( $( 1) ) .ps1
2014-04-18 06:49:07 +04:00
ps_STEP_TO_PROG = ps/$( $( 1) ) .ps
python_STEP_TO_PROG = python/$( $( 1) ) .py
2014-11-01 23:54:48 +03:00
r_STEP_TO_PROG = r/$( $( 1) ) .r
2015-01-03 08:20:00 +03:00
racket_STEP_TO_PROG = racket/$( $( 1) ) .rkt
2017-09-15 07:39:00 +03:00
rexx_STEP_TO_PROG = rexx/$( $( 1) ) .rexxpp
2015-06-03 07:58:23 +03:00
rpython_STEP_TO_PROG = rpython/$( $( 1) )
2014-04-18 06:49:07 +04:00
ruby_STEP_TO_PROG = ruby/$( $( 1) ) .rb
2018-07-12 08:23:40 +03:00
rust_STEP_TO_PROG = rust/$( $( 1) )
2016-05-16 18:25:42 +03:00
scala_STEP_TO_PROG = scala/target/scala-2.11/classes/$( $( 1) ) .class
2017-09-13 17:49:15 +03:00
scheme_STEP_TO_PROG = $( scheme_STEP_TO_PROG_$( scheme_MODE) )
2016-11-09 00:40:18 +03:00
skew_STEP_TO_PROG = skew/$( $( 1) ) .js
2015-03-18 09:32:35 +03:00
swift_STEP_TO_PROG = swift/$( $( 1) )
2016-02-24 09:27:23 +03:00
swift3_STEP_TO_PROG = swift3/$( $( 1) )
2015-07-09 18:14:16 +03:00
tcl_STEP_TO_PROG = tcl/$( $( 1) ) .tcl
2017-02-22 18:03:21 +03:00
ts_STEP_TO_PROG = ts/$( $( 1) ) .js
2014-11-16 08:15:09 +03:00
vb_STEP_TO_PROG = vb/$( $( 1) ) .exe
2016-03-23 23:03:58 +03:00
vhdl_STEP_TO_PROG = vhdl/$( $( 1) )
2015-10-20 22:02:00 +03:00
vimscript_STEP_TO_PROG = vimscript/$( $( 1) ) .vim
2018-10-13 08:26:38 +03:00
wasm_STEP_TO_PROG = wasm/$( $( 1) ) .wasm
2017-09-12 23:51:40 +03:00
yorick_STEP_TO_PROG = yorick/$( $( 1) ) .i
2014-04-18 06:49:07 +04:00
2017-09-15 07:36:25 +03:00
#
# General settings and utility functions
#
2015-02-09 05:35:44 +03:00
# Needed some argument munging
COMMA = ,
noop =
SPACE = $( noop) $( noop)
2015-10-29 18:27:24 +03:00
export FACTOR_ROOTS := .
2014-04-18 06:49:07 +04:00
2017-09-15 07:36:25 +03:00
opt_DEFERRABLE = $( if $( strip $( DEFERRABLE) ) ,$( if $( filter t true T True TRUE 1 y yes Yes YES,$( DEFERRABLE) ) ,--deferrable,--no-deferrable) ,--no-deferrable)
opt_OPTIONAL = $( if $( strip $( OPTIONAL) ) ,$( if $( filter t true T True TRUE 1 y yes Yes YES,$( OPTIONAL) ) ,--optional,--no-optional) ,--no-optional)
# Return list of test files for a given step. If REGRESS is set then
# test files will include step 2 tests through tests for the step
# being tested.
STEP_TEST_FILES = $( strip $( wildcard \
2019-02-27 02:38:05 +03:00
$( foreach s,$( if $( strip $( REGRESS) ) ,\
$( filter-out $( if $( filter $( 1) ,$( step5_EXCLUDES) ) ,step5,) ,\
$( regress_$( 2) ) ) \
,$( 2) ) ,\
2017-09-15 07:36:25 +03:00
$( 1) /tests/$( $( s) ) $( EXTENSION) tests/$( $( s) ) $( EXTENSION) ) ) )
2016-03-08 06:59:16 +03:00
# DOCKERIZE utility functions
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 ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) )
impl_to_image = kanaka/mal-test-$( call lc,$( 1) )
actual_impl = $( if $( filter mal,$( 1) ) ,$( MAL_IMPL) ,$( 1) )
2016-05-18 07:37:26 +03:00
# Takes impl
# Returns nothing if DOCKERIZE is not set, otherwise returns the
# docker prefix necessary to run make within the docker environment
# for this impl
2017-09-12 02:23:32 +03:00
get_build_command = $( strip $( if $( strip $( DOCKERIZE) ) ,\
2017-07-27 07:53:39 +03:00
docker run \
-it --rm -u $( shell id -u) \
-v $( dir $( abspath $( lastword $( MAKEFILE_LIST) ) ) ) :/mal \
-w /mal/$( 1) \
2017-09-12 01:49:26 +03:00
$( if $( strip $( $( 1) _MODE) ) ,-e $( 1) _MODE = $( $( 1) _MODE) ,) \
2017-07-27 07:53:39 +03:00
$( if $( filter factor,$( 1) ) ,-e FACTOR_ROOTS = $( FACTOR_ROOTS) ,) \
$( call impl_to_image,$( 1) ) \
2017-09-12 02:23:32 +03:00
$( MAKE) $( if $( strip $( $( 1) _MODE) ) ,$( 1) _MODE = $( $( 1) _MODE) ,) \
,\
$( MAKE) $( if $( strip $( $( 1) _MODE) ) ,$( 1) _MODE = $( $( 1) _MODE) ,) ) )
2014-04-18 06:49:07 +04:00
2017-09-15 07:37:26 +03:00
# Takes impl and step args. Optional env vars and dockerize args
2016-05-18 07:37:26 +03:00
# Returns a command prefix (docker command and environment variables)
# necessary to launch the given impl and step
2017-09-15 07:37:26 +03:00
get_run_prefix = $( strip $( if $( strip $( DOCKERIZE) $( 4) ) ,\
2016-08-09 20:25:33 +03:00
docker run -e STEP = $( $2 ) -e MAL_IMPL = $( MAL_IMPL) \
2016-05-18 07:37:26 +03:00
-it --rm -u $( shell id -u) \
-v $( dir $( abspath $( lastword $( MAKEFILE_LIST) ) ) ) :/mal \
-w /mal/$( call actual_impl,$( 1) ) \
2017-09-12 01:49:26 +03:00
$( if $( strip $( $( 1) _MODE) ) ,-e $( 1) _MODE = $( $( 1) _MODE) ,) \
2016-05-18 07:37:26 +03:00
$( if $( filter factor,$( 1) ) ,-e FACTOR_ROOTS = $( FACTOR_ROOTS) ,) \
$( foreach env,$( 3) ,-e $( env) ) \
$( call impl_to_image,$( call actual_impl,$( 1) ) ) \
,\
2016-08-09 20:25:33 +03:00
env STEP = $( $2 ) MAL_IMPL = $( MAL_IMPL) \
2017-09-12 01:49:26 +03:00
$( if $( strip $( $( 1) _MODE) ) ,$( 1) _MODE = $( $( 1) _MODE) ,) \
2016-05-18 07:37:26 +03:00
$( if $( filter factor,$( 1) ) ,FACTOR_ROOTS= $( FACTOR_ROOTS) ,) \
$( 3) ) )
# Takes impl and step
# Returns the runtest command prefix (with runtest options) for testing the given step
get_runtest_cmd = $( call get_run_prefix,$( 1) ,$( 2) ,$( if $( filter cs fsharp tcl vb,$( 1) ) ,RAW= 1,) ) \
2016-06-08 21:29:59 +03:00
../runtest.py $( opt_DEFERRABLE) $( opt_OPTIONAL) $( call $( 1) _TEST_OPTS) $( TEST_OPTS)
2016-05-18 07:37:26 +03:00
# Takes impl and step
# Returns the runtest command prefix (with runtest options) for testing the given step
get_argvtest_cmd = $( call get_run_prefix,$( 1) ,$( 2) ) ../run_argv_test.sh
2014-03-25 01:32:24 +04:00
# Derived lists
2019-02-27 02:38:05 +03:00
STEPS = $( sort $( filter-out %_EXCLUDES,$( filter step%,$( .VARIABLES) ) ) )
2015-03-12 06:08:21 +03:00
DO_IMPLS = $( filter-out $( SKIP_IMPLS) ,$( IMPLS) )
IMPL_TESTS = $( foreach impl,$( DO_IMPLS) ,test^$( impl) )
2014-03-25 01:32:24 +04:00
STEP_TESTS = $( foreach step,$( STEPS) ,test^$( step) )
2019-02-27 02:38:05 +03:00
ALL_TESTS = $( filter-out $( foreach e,$( step5_EXCLUDES) ,test^$( e) ^step5) ,\
2014-03-25 01:32:24 +04:00
$( strip $( sort \
2015-03-12 06:08:21 +03:00
$( foreach impl,$( DO_IMPLS) ,\
2014-03-25 01:32:24 +04:00
$( foreach step,$( STEPS) ,test^$( impl) ^$( step) ) ) ) ) )
2015-10-06 00:46:21 +03:00
DOCKER_BUILD = $( foreach impl,$( DO_IMPLS) ,docker-build^$( impl) )
2017-09-15 07:37:26 +03:00
DOCKER_SHELL = $( foreach impl,$( DO_IMPLS) ,docker-shell^$( impl) )
2016-03-15 07:39:21 +03:00
IMPL_PERF = $( foreach impl,$( filter-out $( perf_EXCLUDES) ,$( DO_IMPLS) ) ,perf^$( impl) )
2014-04-18 06:49:07 +04:00
2015-12-14 16:50:27 +03:00
IMPL_REPL = $( foreach impl,$( DO_IMPLS) ,repl^$( impl) )
ALL_REPL = $( strip $( sort \
$( foreach impl,$( DO_IMPLS) ,\
$( foreach step,$( STEPS) ,repl^$( impl) ^$( step) ) ) ) )
2014-04-18 06:49:07 +04:00
2017-09-15 07:36:25 +03:00
2014-03-25 01:32:24 +04:00
#
# Build rules
#
2017-09-15 07:36:25 +03:00
# Enable secondary expansion for all rules
.SECONDEXPANSION :
2015-06-16 18:23:12 +03:00
# Build a program in an implementation directory
2015-11-19 01:32:53 +03:00
# Make sure we always try and build first because the dependencies are
# encoded in the implementation Makefile not here
.PHONY : $( foreach i ,$ ( DO_IMPLS ) ,$ ( foreach s ,$ ( STEPS ) ,$ ( call $ ( i ) _STEP_TO_PROG ,$ ( s ) ) ) )
2015-06-16 18:23:12 +03:00
$(foreach i,$(DO_IMPLS),$(foreach s,$(STEPS),$(call $(i)_STEP_TO_PROG,$(s)))) :
2015-11-19 01:32:53 +03:00
$( foreach impl,$( word 1,$( subst /, ,$( @) ) ) ,\
2016-03-08 06:59:16 +03:00
$( if $( DOCKERIZE) , \
2017-09-12 02:23:32 +03:00
$( call get_build_command,$( impl) ) $( patsubst $( impl) /%,%,$( @) ) , \
$( call get_build_command,$( impl) ) -C $( impl) $( subst $( impl) /,,$( @) ) ) )
2014-03-25 01:32:24 +04:00
2016-03-08 08:33:45 +03:00
# Allow IMPL, and IMPL^STEP
$(DO_IMPLS) : $$( foreach s ,$ $ ( STEPS ) ,$ $ ( call $ $ ( @) _STEP_TO_PROG ,$ $ ( s ) ) )
2014-03-25 01:32:24 +04:00
2016-03-08 08:33:45 +03:00
$(foreach i,$(DO_IMPLS),$(foreach s,$(STEPS),$(i)^$(s))) : $$( call $ $ ( word 1,$ $ ( subst ^, ,$ $ ( @) ) ) _STEP_TO_PROG ,$ $ ( word 2,$ $ ( subst ^, ,$ $ ( @) ) ) )
#
# Test rules
#
2014-03-25 01:32:24 +04:00
$(ALL_TESTS) : $$( call $ $ ( word 2,$ $ ( subst ^, ,$ $ ( @) ) ) _STEP_TO_PROG ,$ $ ( word 3,$ $ ( subst ^, ,$ $ ( @) ) ) )
@$( foreach impl,$( word 2,$( subst ^, ,$( @) ) ) ,\
$( foreach step,$( word 3,$( subst ^, ,$( @) ) ) ,\
2016-03-30 17:14:48 +03:00
cd $( if $( filter mal,$( impl) ) ,$( MAL_IMPL) ,$( impl) ) && \
2014-03-25 01:32:24 +04:00
$( foreach test,$( call STEP_TEST_FILES,$( impl) ,$( step) ) ,\
2016-03-30 17:14:48 +03:00
echo '----------------------------------------------' && \
2016-05-18 07:37:26 +03:00
echo 'Testing $@; step file: $+, test file: $(test)' && \
2016-06-03 18:20:28 +03:00
echo 'Running: $(call get_runtest_cmd,$(impl),$(step)) ../$(test) -- ../$(impl)/run' && \
$( call get_runtest_cmd,$( impl) ,$( step) ) ../$( test ) -- ../$( impl) /run && \
2017-02-11 09:15:34 +03:00
$( if $( filter tests/$( argv_STEP) $( EXTENSION) ,$( test ) ) ,\
2016-05-10 22:28:29 +03:00
echo '----------------------------------------------' && \
echo 'Testing ARGV of $@; step file: $+' && \
2016-05-18 07:37:26 +03:00
echo 'Running: $(call get_argvtest_cmd,$(impl),$(step)) ../$(impl)/run ' && \
$( call get_argvtest_cmd,$( impl) ,$( step) ) ../$( impl) /run && ,\
2016-05-10 22:28:29 +03:00
true && ) ) \
2016-03-30 17:14:48 +03:00
true ) )
2014-03-25 01:32:24 +04:00
2016-03-08 08:33:45 +03:00
# Allow test, tests, test^STEP, test^IMPL, and test^IMPL^STEP
2014-03-25 01:32:24 +04:00
test : $( ALL_TESTS )
tests : $( ALL_TESTS )
2016-03-08 08:33:45 +03:00
$(IMPL_TESTS) : $$( filter $ $ @^%,$ $ ( ALL_TESTS ) )
2014-03-25 01:32:24 +04:00
2016-03-08 08:33:45 +03:00
$(STEP_TESTS) : $$( foreach step ,$ $ ( subst test ^,,$ $ @) ,$ $ ( filter %^$ $ ( step ) ,$ $ ( ALL_TESTS ) ) )
2014-03-25 01:32:24 +04:00
2014-04-18 06:49:07 +04:00
2016-03-08 08:33:45 +03:00
#
2017-09-15 07:37:26 +03:00
# Docker build rules
2016-03-08 08:33:45 +03:00
#
2016-02-15 05:57:31 +03:00
2017-09-15 07:37:26 +03:00
docker-build : $( DOCKER_BUILD )
2014-03-25 01:32:24 +04:00
2017-09-15 07:37:26 +03:00
$(DOCKER_BUILD) :
2014-04-11 04:27:42 +04:00
@echo "----------------------------------------------" ; \
$( foreach impl,$( word 2,$( subst ^, ,$( @) ) ) ,\
2017-09-15 07:37:26 +03:00
echo " Running: docker build -t $( call impl_to_image,$( impl) ) .: " ; \
cd $( impl) && docker build -t $( call impl_to_image,$( impl) ) .)
2014-04-11 04:27:42 +04:00
2016-03-08 08:33:45 +03:00
#
2017-09-15 07:37:26 +03:00
# Docker shell rules
2016-03-08 08:33:45 +03:00
#
2015-10-06 00:46:21 +03:00
2017-09-15 07:37:26 +03:00
$(DOCKER_SHELL) :
@echo "----------------------------------------------" ; \
2015-10-06 00:46:21 +03:00
$( foreach impl,$( word 2,$( subst ^, ,$( @) ) ) ,\
2017-09-15 07:37:26 +03:00
echo " Running: $( call get_run_prefix,$( impl) ,stepA,,dockerize) bash " ; \
$( call get_run_prefix,$( impl) ,stepA,,dockerize) bash)
2014-04-18 06:49:07 +04:00
2016-03-08 08:33:45 +03:00
#
2014-04-18 06:49:07 +04:00
# Performance test rules
2016-03-08 08:33:45 +03:00
#
2014-04-18 06:49:07 +04:00
perf : $( IMPL_PERF )
$(IMPL_PERF) :
@echo "----------------------------------------------" ; \
$( foreach impl,$( word 2,$( subst ^, ,$( @) ) ) ,\
cd $( if $( filter mal,$( impl) ) ,$( MAL_IMPL) ,$( impl) ) ; \
echo " Performance test for $( impl) : " ; \
2016-05-18 07:37:26 +03:00
echo 'Running: $(call get_run_prefix,$(impl),stepA) ../$(impl)/run ../tests/perf1.mal' ; \
$( call get_run_prefix,$( impl) ,stepA) ../$( impl) /run ../tests/perf1.mal; \
echo 'Running: $(call get_run_prefix,$(impl),stepA) ../$(impl)/run ../tests/perf2.mal' ; \
$( call get_run_prefix,$( impl) ,stepA) ../$( impl) /run ../tests/perf2.mal; \
echo 'Running: $(call get_run_prefix,$(impl),stepA) ../$(impl)/run ../tests/perf3.mal' ; \
$( call get_run_prefix,$( impl) ,stepA) ../$( impl) /run ../tests/perf3.mal)
2014-04-18 06:49:07 +04:00
2015-12-14 16:50:27 +03:00
2016-03-08 08:33:45 +03:00
#
2015-12-14 16:50:27 +03:00
# REPL invocation rules
2016-03-08 08:33:45 +03:00
#
2015-12-14 16:50:27 +03:00
$(ALL_REPL) : $$( call $ $ ( word 2,$ $ ( subst ^, ,$ $ ( @) ) ) _STEP_TO_PROG ,$ $ ( word 3,$ $ ( subst ^, ,$ $ ( @) ) ) )
@$( foreach impl,$( word 2,$( subst ^, ,$( @) ) ) ,\
$( foreach step,$( word 3,$( subst ^, ,$( @) ) ) ,\
cd $( if $( filter mal,$( impl) ) ,$( MAL_IMPL) ,$( impl) ) ; \
echo 'REPL implementation $(impl), step file: $+' ; \
2017-09-15 07:36:25 +03:00
echo 'Running: $(call get_run_prefix,$(impl),$(step)) ../$(impl)/run $(RUN_ARGS)' ; \
$( call get_run_prefix,$( impl) ,$( step) ) ../$( impl) /run $( RUN_ARGS) ; ) )
2016-02-24 10:05:44 +03:00
2016-03-08 08:33:45 +03:00
# Allow repl^IMPL^STEP and repl^IMPL (which starts REPL of stepA)
$(IMPL_REPL) : $$@^stepA
2016-03-15 07:39:21 +03:00
#
# Utility functions
#
print-% :
@echo " $( $( *) ) "
2016-02-24 10:05:44 +03:00
2016-03-08 08:33:45 +03:00
#
2016-02-24 10:05:44 +03:00
# Recursive rules (call make FOO in each subdirectory)
2016-03-08 08:33:45 +03:00
#
2016-02-24 10:05:44 +03:00
d e f i n e r e c u r _ t e m p l a t e
.PHONY : $( 1)
$(1) : $( 2)
$(2) :
@echo "----------------------------------------------" ; \
$$ ( foreach impl,$$ ( word 2,$$ ( subst ^, ,$$ ( @) ) ) ,\
2016-03-08 06:59:16 +03:00
$$ ( if $$ ( DOCKERIZE) , \
2017-09-12 02:23:32 +03:00
echo " Running: $$ (call get_build_command, $$ (impl)) --no-print-directory $( 1) " ; \
$$ ( call get_build_command,$$ ( impl) ) --no-print-directory $( 1) , \
echo " Running: $$ (call get_build_command, $$ (impl)) --no-print-directory -C $$ (impl) $( 1) " ; \
$$ ( call get_build_command,$$ ( impl) ) --no-print-directory -C $$ ( impl) $( 1) ) )
2016-02-24 10:05:44 +03:00
e n d e f
recur_impls_ = $( filter-out $( foreach impl,$( $( 1) _EXCLUDES) ,$( 1) ^$( impl) ) ,$( foreach impl,$( IMPLS) ,$( 1) ^$( impl) ) )
# recursive clean
$( eval $ ( call recur_template ,clean ,$ ( call recur_impls_ ,clean ) ) )
# recursive stats
$( eval $ ( call recur_template ,stats ,$ ( call recur_impls_ ,stats ) ) )
$( eval $ ( call recur_template ,stats -lisp ,$ ( call recur_impls_ ,stats -lisp ) ) )
# recursive dist
$( eval $ ( call recur_template ,dist ,$ ( call recur_impls_ ,dist ) ) )