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