# file : tests/recipe/buildscript/testscript # license : MIT; see accompanying LICENSE file posix = ($cxx.target.class != 'windows') +mkdir build +cat <=build/bootstrap.build project = test amalgamation = subprojects = using config using test EOI +cat <=build/root.build EOI : update : { : success : { echo 'bar' >=bar; cat <=buildfile; foo: bar {{ cp $path($<) $path($>) }} EOI $* 2>'cp file{foo}'; cat <<'bar'; # While at it, make sure there is no rebuild. # $* 2>/'info: dir{./} is up to date'; $* clean 2>- } : error : : Test that the target file is removed on error and is created on subsequent : successful update. : { echo 'bar' >=bar; cat <=buildfile; foo: bar {{ diag concat $< t = $path($>) p = $path($<) cp $p $t cat $(p).baz >>$t }} EOI $* 2>>~%EOE% != 0; concat file{bar.} %cat: unable to print '.+bar.baz': .+% buildfile:10:3: error: cat exited with code 1 %.+ EOE test -f foo != 0; echo 'baz' >=bar.baz; $* 2>'concat file{bar.}'; cat <<>EOO; bar baz EOO $* clean 2>- } : mutual-redirects : { echo 'bar' >=bar; cat <=buildfile; foo: bar % [diag=cp] {{ echo 'copying' 2>&1 cp $path($<) $path($>) }} EOI $* 2>>~%EOE% != 0; cp file{foo} buildfile:4:3: error: stdout and stderr redirected to each other %.+ EOE $* clean 2>- } : untracked-var : { cat <=buildfile; a = a b = b foo: {{ x = true echo "$($x ? a : b)" >$path($>) }} EOI $* 2>>~%EOE% != 0; echo file{foo} buildfile:6:10: error: use of untracked variable 'a' info: use the 'depdb' builtin to manually track it %.+ EOE $* clean 2>- } : export : if $posix { cat <=bar; #!/bin/sh echo "$message" EOI cat <=buildfile; exe{foo}: bar {{ cp $path($<) $path($>) }} % test {{ diag test $> export message=text1 $> >>>?'text1' env message=text2 -- $> >>>?'text2' }} EOI $* test 2>>EOE; cp exe{foo} test exe{foo.} EOE $* clean 2>- } : depdb : { : track-var-auto : { echo 'bar' >=bar; cat <=buildfile; s = $process.run(cat bar) foo: {{ echo "$s" >$path($>) }} EOI $* 2>'echo file{foo}'; cat <<'bar'; $* 2>/'info: dir{./} is up to date'; echo 'baz' >=bar; $* 2>'echo file{foo}'; cat <<'baz'; $* clean 2>- } : track-var-manual : { echo 'bar' >=bar; echo 'baz' >=baz; cat <=buildfile; a = $process.run(cat baz) foo: bar {{ depdb hash "$a" diag compose $> cp $path($<) $path($>) x = true echo "$($x ? a : b)" >>$path($>) }} EOI $* 2>'compose file{foo.}'; cat <<>EOO; bar baz EOO $* 2>/'info: dir{./} is up to date'; # Make sure that on filesystems with a low file timestamps resolution # (for example HFS+) the file is considered as changed. # sleep 1; echo 'BAR' >=bar; $* 2>'compose file{foo.}'; cat <<>EOO; BAR baz EOO $* 2>/'info: dir{./} is up to date'; echo 'BAZ' >=baz; $* 2>'compose file{foo.}'; cat <<>EOO; BAR BAZ EOO $* 2>/'info: dir{./} is up to date'; $* clean 2>- } : preamble : { : valid : { echo 'bar' >=bar; cat <=buildfile; s = $process.run(cat bar) foo: {{ depdb clear s1 = 'abc' s2 = 'xyz' if echo "$s" >>>? 'bar' v = "$s1" else echo "$s2" | set v end depdb string "$v" echo "$v" >$path($>) }} EOI $* 2>'echo file{foo}'; cat <<'abc'; $* 2>/'info: dir{./} is up to date'; echo 'baz' >=bar; $* 2>'echo file{foo}'; cat <<'xyz'; $* clean 2>- } : invalid : { cat <=buildfile; foo: {{ v = 'abc' echo "$v" >$path($>) depdb string "$v" }} EOI $* 2>>~%EOE% != 0; buildfile:4:3: error: disallowed command in depdb preamble info: only variable assignments are allowed in depdb preamble buildfile:5:3: info: depdb preamble ends here %.+ EOE $* clean 2>- } : temp-dir : { cat <=buildfile; foo: {{ touch $~/f | set dummy if test -f $~/f v = "yes" else v = "no" end depdb string "$v" diag echo $> test -f $~/f echo "$v" >$path($>) }} EOI $* 2>'echo file{foo.}'; $* clean 2>- } } : string : { echo 'bar' >=bar; cat <=buildfile; s = $process.run(cat bar) foo: {{ depdb clear depdb string "$s" echo "$s" >$path($>) }} EOI $* 2>'echo file{foo}'; cat <<'bar'; $* 2>/'info: dir{./} is up to date'; echo 'baz' >=bar; $* 2>'echo file{foo}'; cat <<'baz'; $* clean 2>- } : hash : { echo 'bar' >=bar; cat <=buildfile; s = $process.run(cat bar) foo: {{ depdb clear depdb hash "$s" echo "$s" >$path($>) }} EOI $* 2>'echo file{foo}'; cat <<'bar'; $* 2>/'info: dir{./} is up to date'; echo 'baz' >=bar; $* 2>'echo file{foo}'; cat <<'baz'; $* clean 2>- } : env : { : invalid : { cat <=buildfile; foo: {{ s = $getenv(FOO) depdb clear depdb env FOO=bar echo "$s" >$path($>) }} EOI $* 2>>/EOE != 0; buildfile:6:3: error: invalid 'depdb env' argument: invalid variable name 'FOO=bar': contains '=' info: while updating file{foo} info: while updating dir{./} info: failed to update dir{./} EOE $* clean 2>- } : valid : { cat <=buildfile; foo: {{ s = $getenv(FOO) depdb clear depdb env FOO echo "$s" >$path($>) }} EOI export FOO=foo; $* 2>'echo file{foo}'; cat <<'foo'; $* 2>/'info: dir{./} is up to date'; export FOO=bar; $* 2>'echo file{foo}'; cat <<'bar'; export -u FOO; $* 2>'echo file{foo}'; cat <<''; $* clean 2>- } } : dyndep : { : normal : { cat <=bar.h; bar EOI cat <=buildfile; define h: file h{*}: extension = h ./: h{foo baz} h{foo}: {{ # Note that strictly speaking we should return $out_base/baz.h # on the second invocation (since it now exists). But our dyndep # machinery skips the entry which it has already seen, so this # works for now. # depdb dyndep "-I$out_base" --what=header --default-type=h -- \ echo "$out_base/foo.h: $src_base/bar.h baz.h" diag gen $> cat $path($<) >$path($>) }} h{baz}: {{ diag gen $> echo baz >$path($>) }} EOI $* 2>>EOE; gen h{baz.h} gen h{foo.h} EOE cat foo.h >>EOO; bar baz EOO $* clean 2>- } : byproduct : { cat <=bar.h; bar EOI cat <=buildfile; define h: file h{*}: extension = h h{foo}: h{baz} {{ o = $path($>) t = $path($>).t depdb dyndep --byproduct --what=header --default-type=h --file $t diag gen $> cat $src_base/bar.h $out_base/baz.h >$o echo "$out_base/foo.h: $src_base/bar.h $out_base/baz.h" >$t }} h{baz}: {{ diag gen $> echo baz >$path($>) }} EOI $* 2>>EOE; gen h{baz.h} gen h{foo.h} EOE cat foo.h >>EOO; bar baz EOO $* clean 2>- } } } } : clean : { echo 'bar' >=bar; cat <=buildfile; foo: bar {{ cp $path($<) $path($>) }} % [diag=clean] clean {{ t = $path($>) rm $t $(t).d }} EOI $* 2>-; # Rely on the cleanup machinery to verify that the build output files are # removed. # $* clean 2>'clean file{foo}' } : test : { : success : { echo 'bar' >=bar; cat <=buildfile; foo: bar {{ cp $path($<) $path($>) }} % [diag=test] test {{ cat <$path($>) >?$path($<) }} EOI $* test 2>>EOE; cp file{foo} test file{foo} EOE $* clean 2>- } : depdb : { echo 'bar' >=bar; cat <=buildfile; foo: bar {{ cp $path($<) $path($>) }} % [diag=test] test {{ depdb clear cat <$path($>) >?$path($<) }} EOI $* test 2>>EOE != 0 buildfile:7:3: error: 'depdb' builtin cannot be used to perform test EOE } : runner : if $posix { echo 'bar' >=bar; cat <=run; #!/bin/sh if test "$1" = "--trace"; then shift echo "$*" fi "$@" EOI chmod u+x run; cat <=buildfile; foo: bar {{ cp $path($<) $path($>) }} % [diag=test] test {{ if ($test.runner.path != [null]) $test.runner.path $test.runner.options cat <$path($>) else cat <$path($>) end }} EOI $* test 2>>EOE; cp file{foo} test file{foo} bar EOE $* test config.test.runner="./run --trace" 2>>EOE; test file{foo} cat bar EOE $* clean 2>- } } : diff-label : { echo 'bar' >=bar; cat <=buildfile; foo: bar {{ echo 'baz' >? $path($<) }} EOI $* 2>>/~%EOE% != 0; %.+ %--- .+/bar% +++ stdout %.+ EOE $* clean 2>- } : timeout : if $posix { : update : { : expired : { echo 'bar' >=bar; cat <=buildfile; foo: bar % [diag=update] {{ cp $path($<) $path($>) timeout 1 ^sleep 5 }} EOI $* 2>>~%EOE% != 0; update file{foo} buildfile:6:3: error: ^sleep terminated: execution timeout expired info: while updating file{foo} %.+ EOE $* clean 2>- } : successful-timeout : { echo 'bar' >=bar; cat <=buildfile; foo: bar % [diag=update] {{ cp $path($<) $path($>) timeout --success 1 ^sleep 5 }} EOI $* 2>>EOE; update file{foo} EOE $* clean 2>- } } : test : { : expired : { echo 'bar' >=bar; cat <=buildfile; foo: bar {{ cp $path($<) $path($>) }} % [diag=test] test {{ ^sleep 5 }} EOI $* test config.test.timeout=1 2>>~%EOE% != 0; cp file{foo} test file{foo} buildfile:7:3: error: ^sleep terminated: execution timeout expired info: while testing file{foo} %.+ EOE $* test config.test.timeout=/1 2>>~%EOE% != 0; test file{foo} buildfile:7:3: error: ^sleep terminated: execution timeout expired info: while testing file{foo} %.+ EOE $* clean 2>- } : not-expired : { echo 'bar' >=bar; cat <=buildfile; foo: bar % [diag=cp] {{ ^sleep 4 cp $path($<) $path($>) }} % [diag=test] test {{ ^sleep 1 }} EOI $* test config.test.timeout=3 2>>EOE; cp file{foo} test file{foo} EOE $* clean 2>- } } } # @@ TODO: test $1 when implemented. # : rule : { cat <=buildfile; alias{far}: alias{bar} alias{bar}: alias{~'/f(.+)/'}: alias{~'/b\1/'} {{ diag $< $> }} EOI $* 2>>EOE alias{bar} alias{far} EOE }