]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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: | |
1e59de90 | 8 | * Copyright 2022 René Ferdinand Rivera Morell |
7c673cae FG |
9 | * Copyright 2001-2004 David Abrahams. |
10 | * Distributed under the Boost Software License, Version 1.0. | |
1e59de90 | 11 | * (See accompanying file LICENSE.txt or https://www.bfgroup.xyz/b2/LICENSE.txt) |
7c673cae FG |
12 | */ |
13 | ||
14 | /* | |
15 | * rules.h - targets, rules, and related information | |
16 | * | |
17 | * This file describes the structures holding the targets, rules, and related | |
18 | * information accumulated by interpreting the statements of the jam files. | |
19 | * | |
20 | * The following are defined: | |
21 | * | |
22 | * RULE - a generic jam rule, the product of RULE and ACTIONS. | |
23 | * ACTIONS - a chain of ACTIONs. | |
24 | * ACTION - a RULE instance with targets and sources. | |
25 | * SETTINGS - variables to set when executing a TARGET's ACTIONS. | |
26 | * TARGETS - a chain of TARGETs. | |
27 | * TARGET - an entity (e.g. a file) that can be built. | |
28 | */ | |
29 | ||
30 | #ifndef RULES_DWA_20011020_H | |
31 | #define RULES_DWA_20011020_H | |
32 | ||
92f5a8d4 | 33 | #include "config.h" |
7c673cae | 34 | #include "function.h" |
1e59de90 | 35 | #include "mem.h" |
7c673cae FG |
36 | #include "modules.h" |
37 | #include "timestamp.h" | |
1e59de90 | 38 | #include <utility> |
7c673cae FG |
39 | |
40 | typedef struct _rule RULE; | |
41 | typedef struct _target TARGET; | |
42 | typedef struct _targets TARGETS; | |
43 | typedef struct _action ACTION; | |
44 | typedef struct _actions ACTIONS; | |
1e59de90 TL |
45 | typedef struct _settings SETTINGS; |
46 | ||
47 | typedef RULE* rule_ptr; | |
48 | typedef TARGET* target_ptr; | |
49 | typedef TARGETS* targets_ptr; | |
50 | typedef ACTION* action_ptr; | |
51 | typedef ACTIONS* actions_ptr; | |
52 | typedef SETTINGS* settings_ptr; | |
53 | ||
54 | typedef RULE& rule_ref; | |
55 | typedef TARGET& target_ref; | |
56 | typedef TARGETS& targets_ref; | |
57 | typedef ACTION& action_ref; | |
58 | typedef ACTIONS& actions_ref; | |
59 | typedef SETTINGS& settings_ref; | |
60 | ||
61 | using rule_uptr = b2::jam::unique_jptr<_rule>; | |
62 | using target_uptr = b2::jam::unique_jptr<_target>; | |
63 | using targets_uptr = b2::jam::unique_jptr<_targets>; | |
64 | using action_uptr = b2::jam::unique_jptr<_action>; | |
65 | using actions_uptr = b2::jam::unique_jptr<_actions>; | |
66 | using settings_uptr = b2::jam::unique_jptr<_settings>; | |
7c673cae FG |
67 | |
68 | /* RULE - a generic jam rule, the product of RULE and ACTIONS. */ | |
69 | ||
70 | /* Build actions corresponding to a rule. */ | |
1e59de90 TL |
71 | struct rule_actions { |
72 | int reference_count; | |
73 | function_ptr command; /* command string from ACTIONS */ | |
74 | list_ptr bindlist; | |
75 | int flags; /* modifiers on ACTIONS */ | |
7c673cae FG |
76 | }; |
77 | ||
1e59de90 TL |
78 | #define RULE_NEWSRCS 0x01 /* $(>) is updated sources only */ |
79 | #define RULE_TOGETHER 0x02 /* combine actions on single target */ | |
80 | #define RULE_IGNORE 0x04 /* ignore return status of executes */ | |
81 | #define RULE_QUIETLY 0x08 /* do not mention it unless verbose */ | |
82 | #define RULE_PIECEMEAL 0x10 /* split exec so each $(>) is small */ | |
83 | #define RULE_EXISTING 0x20 /* $(>) is pre-existing sources only */ | |
84 | ||
85 | typedef struct rule_actions* rule_actions_ptr; | |
86 | ||
87 | struct _rule { | |
88 | object_ptr name; | |
89 | function_ptr procedure; | |
90 | rule_actions_ptr actions; /* build actions, or NULL for no actions */ | |
91 | module_ptr module; /* module in which this rule is executed */ | |
92 | int exported; /* nonzero if this rule is supposed to appear in | |
93 | * the global module and be automatically | |
94 | * imported into other modules | |
95 | */ | |
7c673cae FG |
96 | }; |
97 | ||
98 | /* ACTIONS - a chain of ACTIONs. */ | |
1e59de90 TL |
99 | struct _actions { |
100 | actions_ptr next; | |
101 | actions_ptr tail; /* valid only for head */ | |
102 | action_ptr action; | |
7c673cae FG |
103 | }; |
104 | ||
105 | /* ACTION - a RULE instance with targets and sources. */ | |
1e59de90 TL |
106 | struct _action { |
107 | rule_ptr rule; | |
108 | targets_uptr targets; | |
109 | targets_uptr sources; /* aka $(>) */ | |
110 | char running; /* has been started */ | |
111 | #define A_INIT 0 | |
7c673cae | 112 | #define A_RUNNING_NOEXEC 1 |
1e59de90 TL |
113 | #define A_RUNNING 2 |
114 | int refs; | |
7c673cae FG |
115 | |
116 | /* WARNING: These variables are used to pass state required by make1cmds and | |
117 | * are not valid anywhere else. | |
118 | */ | |
1e59de90 TL |
119 | void* first_cmd; /* Pointer to the first CMD created by this action */ |
120 | void* last_cmd; /* Pointer to the last CMD created by this action */ | |
7c673cae FG |
121 | }; |
122 | ||
123 | /* SETTINGS - variables to set when executing a TARGET's ACTIONS. */ | |
1e59de90 TL |
124 | struct _settings { |
125 | settings_ptr next; | |
126 | object_ptr symbol; /* symbol name for var_set() */ | |
127 | list_ptr value; /* symbol value for var_set() */ | |
7c673cae FG |
128 | }; |
129 | ||
130 | /* TARGETS - a chain of TARGETs. */ | |
1e59de90 TL |
131 | struct _targets { |
132 | targets_uptr next = nullptr; | |
133 | targets_ptr tail = nullptr; /* valid only for head */ | |
134 | target_ptr target = nullptr; | |
135 | ||
136 | ~_targets() | |
137 | { | |
138 | targets_uptr sink = std::move(next); | |
139 | while ( sink ) sink = std::move(sink->next); | |
140 | } | |
7c673cae FG |
141 | }; |
142 | ||
143 | /* TARGET - an entity (e.g. a file) that can be built. */ | |
1e59de90 TL |
144 | struct _target { |
145 | object_ptr name; | |
146 | object_ptr boundname; /* if search() relocates target */ | |
147 | actions_ptr actions; /* rules to execute, if any */ | |
148 | settings_ptr settings; /* variables to define */ | |
149 | ||
150 | targets_uptr depends; /* dependencies */ | |
151 | targets_uptr dependants; /* the inverse of dependencies */ | |
152 | targets_uptr rebuilds; /* targets that should be force-rebuilt | |
153 | * whenever this one is | |
154 | */ | |
155 | target_ptr includes; /* internal includes node */ | |
156 | ||
157 | timestamp time; /* update time */ | |
158 | timestamp leaf; /* update time of leaf sources */ | |
159 | ||
160 | short flags; /* status info */ | |
161 | ||
162 | #define T_FLAG_TEMP 0x0001 /* TEMPORARY applied */ | |
163 | #define T_FLAG_NOCARE 0x0002 /* NOCARE applied */ | |
164 | #define T_FLAG_NOTFILE 0x0004 /* NOTFILE applied */ | |
165 | #define T_FLAG_TOUCHED 0x0008 /* ALWAYS applied or -t target */ | |
166 | #define T_FLAG_LEAVES 0x0010 /* LEAVES applied */ | |
167 | #define T_FLAG_NOUPDATE 0x0020 /* NOUPDATE applied */ | |
168 | #define T_FLAG_VISITED 0x0040 /* CWM: Used in debugging */ | |
7c673cae FG |
169 | |
170 | /* This flag has been added to support a new built-in rule named "RMBAD". It is | |
171 | * used to force removal of outdated targets whose dependencies fail to build. | |
172 | */ | |
1e59de90 | 173 | #define T_FLAG_RMOLD 0x0080 /* RMBAD applied */ |
7c673cae FG |
174 | |
175 | /* This flag was added to support a new built-in rule named "FAIL_EXPECTED" used | |
176 | * to indicate that the result of running a given action should be inverted, | |
177 | * i.e. ok <=> fail. Useful for launching certain test runs from a Jamfile. | |
178 | */ | |
1e59de90 | 179 | #define T_FLAG_FAIL_EXPECTED 0x0100 /* FAIL_EXPECTED applied */ |
7c673cae | 180 | |
1e59de90 | 181 | #define T_FLAG_INTERNAL 0x0200 /* internal INCLUDES node */ |
7c673cae FG |
182 | |
183 | /* Indicates that the target must be a file. Prevents matching non-files, like | |
184 | * directories, when a target is searched. | |
185 | */ | |
1e59de90 | 186 | #define T_FLAG_ISFILE 0x0400 |
7c673cae | 187 | |
1e59de90 | 188 | #define T_FLAG_PRECIOUS 0x0800 |
7c673cae | 189 | |
1e59de90 TL |
190 | char binding; /* how target relates to a real file or |
191 | * folder | |
192 | */ | |
7c673cae | 193 | |
1e59de90 TL |
194 | #define T_BIND_UNBOUND 0 /* a disembodied name */ |
195 | #define T_BIND_MISSING 1 /* could not find real file */ | |
196 | #define T_BIND_PARENTS 2 /* using parent's timestamp */ | |
197 | #define T_BIND_EXISTS 3 /* real file, timestamp valid */ | |
7c673cae | 198 | |
1e59de90 | 199 | char fate; /* make0()'s diagnosis */ |
7c673cae | 200 | |
1e59de90 TL |
201 | #define T_FATE_INIT 0 /* nothing done to target */ |
202 | #define T_FATE_MAKING 1 /* make0(target) on stack */ | |
7c673cae | 203 | |
1e59de90 TL |
204 | #define T_FATE_STABLE 2 /* target did not need updating */ |
205 | #define T_FATE_NEWER 3 /* target newer than parent */ | |
7c673cae | 206 | |
1e59de90 TL |
207 | #define T_FATE_SPOIL 4 /* >= SPOIL rebuilds parents */ |
208 | #define T_FATE_ISTMP 4 /* unneeded temp target oddly present */ | |
7c673cae | 209 | |
1e59de90 TL |
210 | #define T_FATE_BUILD 5 /* >= BUILD rebuilds target */ |
211 | #define T_FATE_TOUCHED 5 /* manually touched with -t */ | |
212 | #define T_FATE_REBUILD 6 | |
213 | #define T_FATE_MISSING 7 /* is missing, needs updating */ | |
214 | #define T_FATE_NEEDTMP 8 /* missing temp that must be rebuild */ | |
215 | #define T_FATE_OUTDATED 9 /* is out of date, needs updating */ | |
216 | #define T_FATE_UPDATE 10 /* deps updated, needs updating */ | |
7c673cae | 217 | |
1e59de90 TL |
218 | #define T_FATE_BROKEN 11 /* >= BROKEN ruins parents */ |
219 | #define T_FATE_CANTFIND 11 /* no rules to make missing target */ | |
220 | #define T_FATE_CANTMAKE 12 /* can not find dependencies */ | |
7c673cae | 221 | |
1e59de90 | 222 | char progress; /* tracks make1() progress */ |
7c673cae | 223 | |
1e59de90 TL |
224 | #define T_MAKE_INIT 0 /* make1(target) not yet called */ |
225 | #define T_MAKE_ONSTACK 1 /* make1(target) on stack */ | |
226 | #define T_MAKE_ACTIVE 2 /* make1(target) in make1b() */ | |
227 | #define T_MAKE_RUNNING 3 /* make1(target) running commands */ | |
228 | #define T_MAKE_DONE 4 /* make1(target) done */ | |
229 | #define T_MAKE_NOEXEC_DONE 5 /* make1(target) done with -n in effect */ | |
7c673cae FG |
230 | |
231 | #ifdef OPT_SEMAPHORE | |
1e59de90 | 232 | #define T_MAKE_SEMAPHORE 5 /* Special target type for semaphores */ |
7c673cae FG |
233 | #endif |
234 | ||
1e59de90 | 235 | char status; /* exec_cmd() result */ |
7c673cae FG |
236 | |
237 | #ifdef OPT_SEMAPHORE | |
1e59de90 | 238 | target_ptr semaphore; /* used in serialization */ |
7c673cae FG |
239 | #endif |
240 | ||
1e59de90 TL |
241 | int asynccnt; /* child deps outstanding */ |
242 | targets_uptr parents; /* used by make1() for completion */ | |
243 | target_ptr scc_root; /* used by make to resolve cyclic includes | |
244 | */ | |
245 | target_ptr rescanning; /* used by make0 to mark visited targets | |
246 | * when rescanning | |
247 | */ | |
248 | int depth; /* The depth of the target in the make0 | |
249 | * stack. | |
250 | */ | |
251 | char* cmds; /* type-punned command list */ | |
252 | ||
253 | char const* failed; | |
7c673cae FG |
254 | }; |
255 | ||
7c673cae | 256 | /* Action related functions. */ |
1e59de90 TL |
257 | void action_free(action_ptr); |
258 | actions_ptr actionlist(actions_ptr, action_ptr); | |
259 | void freeactions(actions_ptr); | |
260 | settings_ptr addsettings(settings_ptr, int flag, object_ptr symbol, list_ptr value); | |
261 | void pushsettings(module_ptr, settings_ptr); | |
262 | void popsettings(module_ptr, settings_ptr); | |
263 | settings_ptr copysettings(settings_ptr); | |
264 | void freesettings(settings_ptr); | |
265 | void actions_refer(rule_actions_ptr); | |
266 | void actions_free(rule_actions_ptr); | |
7c673cae FG |
267 | |
268 | /* Rule related functions. */ | |
1e59de90 TL |
269 | rule_ptr bindrule(object_ptr rulename, module_ptr); |
270 | rule_ptr import_rule(rule_ptr source, module_ptr, object_ptr name); | |
271 | void rule_localize(rule_ptr rule, module_ptr module); | |
272 | rule_ptr new_rule_body(module_ptr, object_ptr rulename, function_ptr func, int exprt); | |
273 | rule_ptr new_rule_actions(module_ptr, object_ptr rulename, function_ptr command, list_ptr bindlist, int flags); | |
274 | void rule_free(rule_ptr); | |
7c673cae FG |
275 | |
276 | /* Target related functions. */ | |
1e59de90 TL |
277 | void bind_explicitly_located_targets(); |
278 | target_ptr bindtarget(object_ptr const); | |
279 | targets_uptr targetchain(targets_uptr, targets_uptr); | |
280 | void targetentry(targets_uptr&, target_ptr); | |
281 | void target_include(target_ptr const including, | |
282 | target_ptr const included); | |
283 | void target_include_many(target_ptr const including, | |
284 | list_ptr const included_names); | |
285 | void targetlist(targets_uptr&, list_ptr target_names); | |
286 | void touch_target(object_ptr const); | |
287 | void clear_includes(target_ptr); | |
288 | target_ptr target_scc(target_ptr); | |
289 | targets_uptr targets_pop(targets_uptr); | |
7c673cae FG |
290 | |
291 | /* Final module cleanup. */ | |
292 | void rules_done(); | |
293 | ||
294 | #endif |