1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
|
# Proof-of-concept for bjam-based testing mechanism. This file should
# work on NT, Cygwin, and Linux. No promises for other platforms.
# Set a variable which says how to dump a file to stdout
if $(NT)
{
CATENATE = type ;
}
else
{
CATENATE = cat ;
}
# invoke the given action rule `act' to build target from sources
rule do-make ( target : sources * : act )
{
DEPENDS $(target) : $(sources) ;
$(act) $(target) : $(sources) ;
}
# top-level version of do-make which causes target to be built by
# default
rule make ( target : sources * : act )
{
DEPENDS all : $(target) ;
do-make $(target) : $(sources) : $(act) ;
}
# cause `target' to exist and building to succeed if invoking
#
# $(act) $(target) : $(sources)
#
# fails, and to fail if the action succeeds.
rule make-fail ( target : sources * : act )
{
# Establish another logical target which refers to the same file,
# by using different grist.
DEPENDS all : <different-grist>$(target) ;
# Make the new logical target depend on the target
DEPENDS <different-grist>$(target) : $(target) ;
# Cause the target to be built from sources using $(act).
do-make $(target) : $(sources) : $(act) ;
# Note that we expect target to fail to build
FAIL_EXPECTED $(target) ;
# Build a failure marker file. Because targets are only built if
# all their dependents "succeed", the marker will only be
# generated if $(target) failed to build, as expected.
failure-marker <different-grist>$(target) ;
}
# Simple action rules which write text into the target. Different
# names for different purposes.
actions failure-marker
{
echo failed as expected > $(<)
}
actions create
{
echo creating > $(<)
}
# An action which will always fail, for testing expected failure rules
actions fail-to-create
{
exit 1
}
# Basic rule-action pair which builds the target by executing the
# given commands
rule do-run ( target : commands + )
{
COMMANDS on $(target) = $(commands) ;
NOTFILE $(commands) ;
}
# Run commands, leaving the output behind in $(<:S=.out). Echo to
# stdout if the command fails.
#
# Detailed explanation:
#
# $(COMMANDS) Run commands
# > $(<:S=.out) into the output file
# 2>&1 including stderr
# && and if that succeeds
# cp -f $(<:S=.out) $(<) copy the output file into the target
# || otherwise
# ( $(CATENATE) $(<:S=.out) dump any output to stdout
# && exit 1 and exit with an error code
# )
actions do-run
{
$(COMMANDS) > $(<:S=.out) 2>&1 && cp -f $(<:S=.out) $(<) || ( $(CATENATE) $(<:S=.out) && exit 1 )
}
# top-level version of do-run which causes target to be built by
# default
rule run ( target : commands + )
{
DEPENDS all : $(target) ;
do-run $(target) : $(commands) ;
}
# experimental expected-failure version of run. This doesn't have
# quite the right semantics w.r.t. output dumping (it is still only
# dumped if the run fails), but we don't need run-fail anyway so it
# doesn't matter too much.
rule run-fail ( target : commands + )
{
make-fail $(target) : $(commands) : do-run ;
}
# A command which will always fail to run. There is no file called
# nonexistent, so executing $(error) always causes an error. We can't
# just use `exit 1' below because that will cause all command
# processing to stop, and we want the rest of the do-run action
# command-line to execute.
error = $(CATENATE)" nonexistent" ;
make-fail t1.txt : : create ;
make-fail t2.txt : : fail-to-create ;
make t3.txt : : create ;
make t4.txt : : fail-to-create ;
run t5.txt : "( echo failing t5 && $(error) )" ;
run t6.txt : echo hi ;
run-fail t7.txt : "( echo failing t7 && $(error) )" ;
run-fail t8.txt : echo hi ;
|