1 | /* |
---|
2 | * Copyright 1993, 1995 Christopher Seiwald. |
---|
3 | * |
---|
4 | * This file is part of Jam - see jam.c for Copyright information. |
---|
5 | */ |
---|
6 | |
---|
7 | /* This file is ALSO: |
---|
8 | * Copyright 2001-2004 David Abrahams. |
---|
9 | * Distributed under the Boost Software License, Version 1.0. |
---|
10 | * (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) |
---|
11 | */ |
---|
12 | |
---|
13 | #ifndef RULES_DWA_20011020_H |
---|
14 | # define RULES_DWA_20011020_H |
---|
15 | |
---|
16 | # include "modules.h" |
---|
17 | # include "jam.h" |
---|
18 | # include "parse.h" |
---|
19 | |
---|
20 | /* |
---|
21 | * rules.h - targets, rules, and related information |
---|
22 | * |
---|
23 | * This file describes the structures holding the targets, rules, and |
---|
24 | * related information accumulated by interpreting the statements |
---|
25 | * of the jam files. |
---|
26 | * |
---|
27 | * The following are defined: |
---|
28 | * |
---|
29 | * RULE - a generic jam rule, the product of RULE and ACTIONS |
---|
30 | * ACTIONS - a chain of ACTIONs |
---|
31 | * ACTION - a RULE instance with targets and sources |
---|
32 | * SETTINGS - variables to set when executing a TARGET's ACTIONS |
---|
33 | * TARGETS - a chain of TARGETs |
---|
34 | * TARGET - a file or "thing" that can be built |
---|
35 | * |
---|
36 | * 04/11/94 (seiwald) - Combined deps & headers into deps[2] in TARGET. |
---|
37 | * 04/12/94 (seiwald) - actionlist() now just appends a single action. |
---|
38 | * 06/01/94 (seiwald) - new 'actions existing' does existing sources |
---|
39 | * 12/20/94 (seiwald) - NOTIME renamed NOTFILE. |
---|
40 | * 01/19/95 (seiwald) - split DONTKNOW into CANTFIND/CANTMAKE. |
---|
41 | * 02/02/95 (seiwald) - new LEAVES modifier on targets. |
---|
42 | * 02/14/95 (seiwald) - new NOUPDATE modifier on targets. |
---|
43 | */ |
---|
44 | |
---|
45 | typedef struct _rule RULE; |
---|
46 | typedef struct _target TARGET; |
---|
47 | typedef struct _targets TARGETS; |
---|
48 | typedef struct _action ACTION; |
---|
49 | typedef struct _actions ACTIONS; |
---|
50 | typedef struct _settings SETTINGS ; |
---|
51 | |
---|
52 | /* RULE - a generic jam rule, the product of RULE and ACTIONS */ |
---|
53 | |
---|
54 | /* A rule's argument list */ |
---|
55 | struct argument_list |
---|
56 | { |
---|
57 | int reference_count; |
---|
58 | LOL data[1]; |
---|
59 | }; |
---|
60 | |
---|
61 | /* The build actions corresponding to a rule */ |
---|
62 | struct rule_actions |
---|
63 | { |
---|
64 | int reference_count; |
---|
65 | char* command; /* command string from ACTIONS */ |
---|
66 | LIST* bindlist; |
---|
67 | int flags; /* modifiers on ACTIONS */ |
---|
68 | |
---|
69 | # define RULE_NEWSRCS 0x01 /* $(>) is updated sources only */ |
---|
70 | # define RULE_TOGETHER 0x02 /* combine actions on single target */ |
---|
71 | # define RULE_IGNORE 0x04 /* ignore return status of executes */ |
---|
72 | # define RULE_QUIETLY 0x08 /* don't mention it unless verbose */ |
---|
73 | # define RULE_PIECEMEAL 0x10 /* split exec so each $(>) is small */ |
---|
74 | # define RULE_EXISTING 0x20 /* $(>) is pre-exisitng sources only */ |
---|
75 | }; |
---|
76 | |
---|
77 | typedef struct rule_actions rule_actions; |
---|
78 | typedef struct argument_list argument_list; |
---|
79 | |
---|
80 | struct _rule { |
---|
81 | char *name; |
---|
82 | PARSE *procedure; /* parse tree from RULE */ |
---|
83 | argument_list* arguments; /* argument checking info, or NULL for unchecked */ |
---|
84 | rule_actions* actions; /* build actions, or NULL for no actions */ |
---|
85 | module_t *module; /* module in which this rule is executed */ |
---|
86 | int exported; /* nonzero if this rule is supposed to |
---|
87 | * appear in the global module and be |
---|
88 | * automatically imported into other modules |
---|
89 | */ |
---|
90 | #ifdef HAVE_PYTHON |
---|
91 | PyObject* python_function; |
---|
92 | #endif |
---|
93 | }; |
---|
94 | |
---|
95 | /* ACTIONS - a chain of ACTIONs */ |
---|
96 | |
---|
97 | struct _actions { |
---|
98 | ACTIONS *next; |
---|
99 | ACTIONS *tail; /* valid only for head */ |
---|
100 | ACTION *action; |
---|
101 | } ; |
---|
102 | |
---|
103 | /* ACTION - a RULE instance with targets and sources */ |
---|
104 | |
---|
105 | struct _action { |
---|
106 | RULE *rule; |
---|
107 | TARGETS *targets; |
---|
108 | TARGETS *sources; /* aka $(>) */ |
---|
109 | char running; /* has been started */ |
---|
110 | char status; /* see TARGET status */ |
---|
111 | } ; |
---|
112 | |
---|
113 | /* SETTINGS - variables to set when executing a TARGET's ACTIONS */ |
---|
114 | |
---|
115 | struct _settings { |
---|
116 | SETTINGS *next; |
---|
117 | char *symbol; /* symbol name for var_set() */ |
---|
118 | LIST *value; /* symbol value for var_set() */ |
---|
119 | } ; |
---|
120 | |
---|
121 | /* TARGETS - a chain of TARGETs */ |
---|
122 | |
---|
123 | struct _targets { |
---|
124 | TARGETS *next; |
---|
125 | TARGETS *tail; /* valid only for head */ |
---|
126 | TARGET *target; |
---|
127 | } ; |
---|
128 | |
---|
129 | /* TARGET - a file or "thing" that can be built */ |
---|
130 | |
---|
131 | struct _target { |
---|
132 | char *name; |
---|
133 | char *boundname; /* if search() relocates target */ |
---|
134 | ACTIONS *actions; /* rules to execute, if any */ |
---|
135 | SETTINGS *settings; /* variables to define */ |
---|
136 | |
---|
137 | short flags; /* status info */ |
---|
138 | |
---|
139 | # define T_FLAG_TEMP 0x0001 /* TEMPORARY applied */ |
---|
140 | # define T_FLAG_NOCARE 0x0002 /* NOCARE applied */ |
---|
141 | # define T_FLAG_NOTFILE 0x0004 /* NOTFILE applied */ |
---|
142 | # define T_FLAG_TOUCHED 0x0008 /* ALWAYS applied or -t target */ |
---|
143 | # define T_FLAG_LEAVES 0x0010 /* LEAVES applied */ |
---|
144 | # define T_FLAG_NOUPDATE 0x0020 /* NOUPDATE applied */ |
---|
145 | # define T_FLAG_VISITED 0x0040 /* CWM: Used in debugging */ |
---|
146 | |
---|
147 | /* this flag was added to support a new builtin rule named "RMBAD" */ |
---|
148 | /* it is used to force removal of outdated targets whose dependencies |
---|
149 | * fail to build */ |
---|
150 | |
---|
151 | # define T_FLAG_RMOLD 0x0080 /* RMBAD applied */ |
---|
152 | |
---|
153 | /* this flag was added to support a new builting rule named "FAIL_EXPECTED" */ |
---|
154 | /* it is used to indicate that the result of running a given action should */ |
---|
155 | /* be inverted (i.e. ok <=> fail). This is useful to launch certain test */ |
---|
156 | /* runs from a Jamfile.. */ |
---|
157 | /* */ |
---|
158 | # define T_FLAG_FAIL_EXPECTED 0x0100 /* FAIL_EXPECTED applied */ |
---|
159 | |
---|
160 | # define T_FLAG_INTERNAL 0x0200 /* internal INCLUDES node */ |
---|
161 | |
---|
162 | /* Indicates that the target must be a file. This prevents matching non-files, |
---|
163 | like directories, when a target is searched. */ |
---|
164 | #define T_FLAG_ISFILE 0x0400 |
---|
165 | |
---|
166 | |
---|
167 | |
---|
168 | #ifdef OPT_SEMAPHORE |
---|
169 | # define T_MAKE_SEMAPHORE 5 /* Special target type for semaphores */ |
---|
170 | #endif |
---|
171 | |
---|
172 | |
---|
173 | char binding; /* how target relates to real file */ |
---|
174 | |
---|
175 | # define T_BIND_UNBOUND 0 /* a disembodied name */ |
---|
176 | # define T_BIND_MISSING 1 /* couldn't find real file */ |
---|
177 | #ifdef OPT_SEMAPHORE |
---|
178 | TARGET *semaphore; /* used in serialization */ |
---|
179 | #endif |
---|
180 | # define T_BIND_PARENTS 2 /* using parent's timestamp */ |
---|
181 | # define T_BIND_EXISTS 3 /* real file, timestamp valid */ |
---|
182 | |
---|
183 | TARGETS *depends; /* dependencies */ |
---|
184 | TARGETS *dependents;/* the inverse of dependencies */ |
---|
185 | TARGETS *rebuilds; /* targets that should be force-rebuilt whenever this one is */ |
---|
186 | TARGET *includes; /* includes */ |
---|
187 | TARGET *original_target; /* original_target->includes = this */ |
---|
188 | char rescanned; |
---|
189 | |
---|
190 | time_t time; /* update time */ |
---|
191 | time_t leaf; /* update time of leaf sources */ |
---|
192 | |
---|
193 | char fate; /* make0()'s diagnosis */ |
---|
194 | |
---|
195 | # define T_FATE_INIT 0 /* nothing done to target */ |
---|
196 | # define T_FATE_MAKING 1 /* make0(target) on stack */ |
---|
197 | |
---|
198 | # define T_FATE_STABLE 2 /* target didn't need updating */ |
---|
199 | # define T_FATE_NEWER 3 /* target newer than parent */ |
---|
200 | |
---|
201 | # define T_FATE_SPOIL 4 /* >= SPOIL rebuilds parents */ |
---|
202 | # define T_FATE_ISTMP 4 /* unneeded temp target oddly present */ |
---|
203 | |
---|
204 | # define T_FATE_BUILD 5 /* >= BUILD rebuilds target */ |
---|
205 | # define T_FATE_TOUCHED 5 /* manually touched with -t */ |
---|
206 | # define T_FATE_REBUILD 6 |
---|
207 | # define T_FATE_MISSING 7 /* is missing, needs updating */ |
---|
208 | # define T_FATE_NEEDTMP 8 /* missing temp that must be rebuild */ |
---|
209 | # define T_FATE_OUTDATED 9 /* is out of date, needs updating */ |
---|
210 | # define T_FATE_UPDATE 10 /* deps updated, needs updating */ |
---|
211 | |
---|
212 | # define T_FATE_BROKEN 11 /* >= BROKEN ruins parents */ |
---|
213 | # define T_FATE_CANTFIND 11 /* no rules to make missing target */ |
---|
214 | # define T_FATE_CANTMAKE 12 /* can't find dependents */ |
---|
215 | |
---|
216 | char progress; /* tracks make1() progress */ |
---|
217 | |
---|
218 | # define T_MAKE_INIT 0 /* make1(target) not yet called */ |
---|
219 | # define T_MAKE_ONSTACK 1 /* make1(target) on stack */ |
---|
220 | # define T_MAKE_ACTIVE 2 /* make1(target) in make1b() */ |
---|
221 | # define T_MAKE_RUNNING 3 /* make1(target) running commands */ |
---|
222 | # define T_MAKE_DONE 4 /* make1(target) done */ |
---|
223 | |
---|
224 | char status; /* execcmd() result */ |
---|
225 | |
---|
226 | int asynccnt; /* child deps outstanding */ |
---|
227 | TARGETS *parents; /* used by make1() for completion */ |
---|
228 | char *cmds; /* type-punned command list */ |
---|
229 | |
---|
230 | char* failed; |
---|
231 | } ; |
---|
232 | |
---|
233 | RULE *bindrule( char *rulename, module_t* ); |
---|
234 | |
---|
235 | RULE* import_rule( RULE* source, module_t* m, char* name ); |
---|
236 | RULE* new_rule_body( module_t* m, char* rulename, argument_list* args, PARSE* procedure, int exprt ); |
---|
237 | RULE* new_rule_actions( module_t* m, char* rulename, char* command, LIST* bindlist, int flags ); |
---|
238 | TARGET *bindtarget( const char *targetname ); |
---|
239 | TARGET *copytarget( const TARGET *t ); |
---|
240 | void bind_explicitly_located_targets(); |
---|
241 | TARGET* search_for_target( char * name, LIST* search_path ); |
---|
242 | void touchtarget( char *t ); |
---|
243 | TARGETS *targetlist( TARGETS *chain, LIST *targets ); |
---|
244 | TARGETS *targetentry( TARGETS *chain, TARGET *target ); |
---|
245 | TARGETS *targetchain( TARGETS *chain, TARGETS *targets ); |
---|
246 | void freetargets( TARGETS *chain ); |
---|
247 | ACTIONS *actionlist( ACTIONS *chain, ACTION *action ); |
---|
248 | void freeactions( ACTIONS *chain ); |
---|
249 | SETTINGS *addsettings( SETTINGS *head, int append, char *symbol, LIST *value ); |
---|
250 | void pushsettings( SETTINGS *v ); |
---|
251 | void popsettings( SETTINGS *v ); |
---|
252 | SETTINGS *copysettings( SETTINGS *v ); |
---|
253 | void freesettings( SETTINGS *v ); |
---|
254 | void rule_free( RULE *r ); |
---|
255 | void donerules(); |
---|
256 | |
---|
257 | argument_list* args_new(); |
---|
258 | void args_refer( argument_list* ); |
---|
259 | void args_free( argument_list* ); |
---|
260 | |
---|
261 | void actions_refer(rule_actions*); |
---|
262 | void actions_free(rule_actions*); |
---|
263 | |
---|
264 | #endif |
---|
265 | |
---|