1*10d63b7dSRichard Lowe /*
2*10d63b7dSRichard Lowe * CDDL HEADER START
3*10d63b7dSRichard Lowe *
4*10d63b7dSRichard Lowe * The contents of this file are subject to the terms of the
5*10d63b7dSRichard Lowe * Common Development and Distribution License (the "License").
6*10d63b7dSRichard Lowe * You may not use this file except in compliance with the License.
7*10d63b7dSRichard Lowe *
8*10d63b7dSRichard Lowe * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*10d63b7dSRichard Lowe * or http://www.opensolaris.org/os/licensing.
10*10d63b7dSRichard Lowe * See the License for the specific language governing permissions
11*10d63b7dSRichard Lowe * and limitations under the License.
12*10d63b7dSRichard Lowe *
13*10d63b7dSRichard Lowe * When distributing Covered Code, include this CDDL HEADER in each
14*10d63b7dSRichard Lowe * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*10d63b7dSRichard Lowe * If applicable, add the following below this CDDL HEADER, with the
16*10d63b7dSRichard Lowe * fields enclosed by brackets "[]" replaced with your own identifying
17*10d63b7dSRichard Lowe * information: Portions Copyright [yyyy] [name of copyright owner]
18*10d63b7dSRichard Lowe *
19*10d63b7dSRichard Lowe * CDDL HEADER END
20*10d63b7dSRichard Lowe */
21*10d63b7dSRichard Lowe /*
22*10d63b7dSRichard Lowe * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
23*10d63b7dSRichard Lowe * Use is subject to license terms.
24*10d63b7dSRichard Lowe */
25*10d63b7dSRichard Lowe
26*10d63b7dSRichard Lowe /*
27*10d63b7dSRichard Lowe * doname.c
28*10d63b7dSRichard Lowe *
29*10d63b7dSRichard Lowe * Figure out which targets are out of date and rebuild them
30*10d63b7dSRichard Lowe */
31*10d63b7dSRichard Lowe
32*10d63b7dSRichard Lowe /*
33*10d63b7dSRichard Lowe * Included files
34*10d63b7dSRichard Lowe */
35*10d63b7dSRichard Lowe #include <alloca.h> /* alloca() */
36*10d63b7dSRichard Lowe #include <fcntl.h>
37*10d63b7dSRichard Lowe #include <mk/defs.h>
38*10d63b7dSRichard Lowe #include <mksh/i18n.h> /* get_char_semantics_value() */
39*10d63b7dSRichard Lowe #include <mksh/macro.h> /* getvar(), expand_value() */
40*10d63b7dSRichard Lowe #include <mksh/misc.h> /* getmem() */
41*10d63b7dSRichard Lowe #include <poll.h>
42*10d63b7dSRichard Lowe #include <libintl.h>
43*10d63b7dSRichard Lowe #include <signal.h>
44*10d63b7dSRichard Lowe #include <stropts.h>
45*10d63b7dSRichard Lowe #include <sys/errno.h>
46*10d63b7dSRichard Lowe #include <sys/stat.h>
47*10d63b7dSRichard Lowe #include <sys/types.h>
48*10d63b7dSRichard Lowe #include <sys/utsname.h> /* uname() */
49*10d63b7dSRichard Lowe #include <sys/wait.h>
50*10d63b7dSRichard Lowe #include <unistd.h> /* close() */
51*10d63b7dSRichard Lowe
52*10d63b7dSRichard Lowe /*
53*10d63b7dSRichard Lowe * Defined macros
54*10d63b7dSRichard Lowe */
55*10d63b7dSRichard Lowe # define LOCALHOST "localhost"
56*10d63b7dSRichard Lowe
57*10d63b7dSRichard Lowe #define MAXRULES 100
58*10d63b7dSRichard Lowe
59*10d63b7dSRichard Lowe // Sleep for .1 seconds between stat()'s
60*10d63b7dSRichard Lowe const int STAT_RETRY_SLEEP_TIME = 100000;
61*10d63b7dSRichard Lowe
62*10d63b7dSRichard Lowe /*
63*10d63b7dSRichard Lowe * typedefs & structs
64*10d63b7dSRichard Lowe */
65*10d63b7dSRichard Lowe
66*10d63b7dSRichard Lowe /*
67*10d63b7dSRichard Lowe * Static variables
68*10d63b7dSRichard Lowe */
69*10d63b7dSRichard Lowe static char hostName[MAXNAMELEN] = "";
70*10d63b7dSRichard Lowe static char userName[MAXNAMELEN] = "";
71*10d63b7dSRichard Lowe
72*10d63b7dSRichard Lowe
73*10d63b7dSRichard Lowe static int second_pass = 0;
74*10d63b7dSRichard Lowe
75*10d63b7dSRichard Lowe /*
76*10d63b7dSRichard Lowe * File table of contents
77*10d63b7dSRichard Lowe */
78*10d63b7dSRichard Lowe extern Doname doname_check(register Name target, register Boolean do_get, register Boolean implicit, register Boolean automatic);
79*10d63b7dSRichard Lowe extern Doname doname(register Name target, register Boolean do_get, register Boolean implicit, register Boolean automatic);
80*10d63b7dSRichard Lowe static Boolean check_dependencies(Doname *result, Property line, Boolean do_get, Name target, Name true_target, Boolean doing_subtree, Chain *out_of_date_tail, Property old_locals, Boolean implicit, Property *command, Name less, Boolean rechecking_target, Boolean recheck_conditionals);
81*10d63b7dSRichard Lowe void dynamic_dependencies(Name target);
82*10d63b7dSRichard Lowe static Doname run_command(register Property line, Boolean print_machine);
83*10d63b7dSRichard Lowe extern Doname execute_serial(Property line);
84*10d63b7dSRichard Lowe extern Name vpath_translation(register Name cmd);
85*10d63b7dSRichard Lowe extern void check_state(Name temp_file_name);
86*10d63b7dSRichard Lowe static void read_dependency_file(register Name filename);
87*10d63b7dSRichard Lowe static void check_read_state_file(void);
88*10d63b7dSRichard Lowe static void do_assign(register Name line, register Name target);
89*10d63b7dSRichard Lowe static void build_command_strings(Name target, register Property line);
90*10d63b7dSRichard Lowe static Doname touch_command(register Property line, register Name target, Doname result);
91*10d63b7dSRichard Lowe extern void update_target(Property line, Doname result);
92*10d63b7dSRichard Lowe static Doname sccs_get(register Name target, register Property *command);
93*10d63b7dSRichard Lowe extern void read_directory_of_file(register Name file);
94*10d63b7dSRichard Lowe static void add_pattern_conditionals(register Name target);
95*10d63b7dSRichard Lowe extern void set_locals(register Name target, register Property old_locals);
96*10d63b7dSRichard Lowe extern void reset_locals(register Name target, register Property old_locals, register Property conditional, register int index);
97*10d63b7dSRichard Lowe extern Boolean check_auto_dependencies(Name target, int auto_count, Name *automatics);
98*10d63b7dSRichard Lowe static void delete_query_chain(Chain ch);
99*10d63b7dSRichard Lowe
100*10d63b7dSRichard Lowe // From read2.cc
101*10d63b7dSRichard Lowe extern Name normalize_name(register wchar_t *name_string, register int length);
102*10d63b7dSRichard Lowe
103*10d63b7dSRichard Lowe
104*10d63b7dSRichard Lowe
105*10d63b7dSRichard Lowe /*
106*10d63b7dSRichard Lowe * DONE.
107*10d63b7dSRichard Lowe *
108*10d63b7dSRichard Lowe * doname_check(target, do_get, implicit, automatic)
109*10d63b7dSRichard Lowe *
110*10d63b7dSRichard Lowe * Will call doname() and then inspect the return value
111*10d63b7dSRichard Lowe *
112*10d63b7dSRichard Lowe * Return value:
113*10d63b7dSRichard Lowe * Indication if the build failed or not
114*10d63b7dSRichard Lowe *
115*10d63b7dSRichard Lowe * Parameters:
116*10d63b7dSRichard Lowe * target The target to build
117*10d63b7dSRichard Lowe * do_get Passed thru to doname()
118*10d63b7dSRichard Lowe * implicit Passed thru to doname()
119*10d63b7dSRichard Lowe * automatic Are we building a hidden dependency?
120*10d63b7dSRichard Lowe *
121*10d63b7dSRichard Lowe * Global variables used:
122*10d63b7dSRichard Lowe * build_failed_seen Set if -k is on and error occurs
123*10d63b7dSRichard Lowe * continue_after_error Indicates that -k is on
124*10d63b7dSRichard Lowe * report_dependencies No error msg if -P is on
125*10d63b7dSRichard Lowe */
126*10d63b7dSRichard Lowe Doname
doname_check(register Name target,register Boolean do_get,register Boolean implicit,register Boolean automatic)127*10d63b7dSRichard Lowe doname_check(register Name target, register Boolean do_get, register Boolean implicit, register Boolean automatic)
128*10d63b7dSRichard Lowe {
129*10d63b7dSRichard Lowe int first_time = 1;
130*10d63b7dSRichard Lowe (void) fflush(stdout);
131*10d63b7dSRichard Lowe try_again:
132*10d63b7dSRichard Lowe switch (doname(target, do_get, implicit, automatic)) {
133*10d63b7dSRichard Lowe case build_ok:
134*10d63b7dSRichard Lowe second_pass = 0;
135*10d63b7dSRichard Lowe return build_ok;
136*10d63b7dSRichard Lowe case build_running:
137*10d63b7dSRichard Lowe second_pass = 0;
138*10d63b7dSRichard Lowe return build_running;
139*10d63b7dSRichard Lowe case build_failed:
140*10d63b7dSRichard Lowe if (!continue_after_error) {
141*10d63b7dSRichard Lowe fatal(gettext("Target `%s' not remade because of errors"),
142*10d63b7dSRichard Lowe target->string_mb);
143*10d63b7dSRichard Lowe }
144*10d63b7dSRichard Lowe build_failed_seen = true;
145*10d63b7dSRichard Lowe second_pass = 0;
146*10d63b7dSRichard Lowe return build_failed;
147*10d63b7dSRichard Lowe case build_dont_know:
148*10d63b7dSRichard Lowe /*
149*10d63b7dSRichard Lowe * If we can't figure out how to build an automatic
150*10d63b7dSRichard Lowe * (hidden) dependency, we just ignore it.
151*10d63b7dSRichard Lowe * We later declare the target to be out of date just in
152*10d63b7dSRichard Lowe * case something changed.
153*10d63b7dSRichard Lowe * Also, don't complain if just reporting the dependencies
154*10d63b7dSRichard Lowe * and not building anything.
155*10d63b7dSRichard Lowe */
156*10d63b7dSRichard Lowe if (automatic || (report_dependencies_level > 0)) {
157*10d63b7dSRichard Lowe second_pass = 0;
158*10d63b7dSRichard Lowe return build_dont_know;
159*10d63b7dSRichard Lowe }
160*10d63b7dSRichard Lowe if(first_time) {
161*10d63b7dSRichard Lowe first_time = 0;
162*10d63b7dSRichard Lowe second_pass = 1;
163*10d63b7dSRichard Lowe goto try_again;
164*10d63b7dSRichard Lowe }
165*10d63b7dSRichard Lowe second_pass = 0;
166*10d63b7dSRichard Lowe if (continue_after_error && !svr4) {
167*10d63b7dSRichard Lowe warning(gettext("Don't know how to make target `%s'"),
168*10d63b7dSRichard Lowe target->string_mb);
169*10d63b7dSRichard Lowe build_failed_seen = true;
170*10d63b7dSRichard Lowe return build_failed;
171*10d63b7dSRichard Lowe }
172*10d63b7dSRichard Lowe fatal(gettext("Don't know how to make target `%s'"), target->string_mb);
173*10d63b7dSRichard Lowe break;
174*10d63b7dSRichard Lowe }
175*10d63b7dSRichard Lowe #ifdef lint
176*10d63b7dSRichard Lowe return build_failed;
177*10d63b7dSRichard Lowe #endif
178*10d63b7dSRichard Lowe }
179*10d63b7dSRichard Lowe
180*10d63b7dSRichard Lowe
181*10d63b7dSRichard Lowe void
enter_explicit_rule_from_dynamic_rule(Name target,Name source)182*10d63b7dSRichard Lowe enter_explicit_rule_from_dynamic_rule(Name target, Name source)
183*10d63b7dSRichard Lowe {
184*10d63b7dSRichard Lowe Property line, source_line;
185*10d63b7dSRichard Lowe Dependency dependency;
186*10d63b7dSRichard Lowe
187*10d63b7dSRichard Lowe source_line = get_prop(source->prop, line_prop);
188*10d63b7dSRichard Lowe line = maybe_append_prop(target, line_prop);
189*10d63b7dSRichard Lowe line->body.line.sccs_command = false;
190*10d63b7dSRichard Lowe line->body.line.target = target;
191*10d63b7dSRichard Lowe if (line->body.line.command_template == NULL) {
192*10d63b7dSRichard Lowe line->body.line.command_template = source_line->body.line.command_template;
193*10d63b7dSRichard Lowe for (dependency = source_line->body.line.dependencies;
194*10d63b7dSRichard Lowe dependency != NULL;
195*10d63b7dSRichard Lowe dependency = dependency->next) {
196*10d63b7dSRichard Lowe enter_dependency(line, dependency->name, false);
197*10d63b7dSRichard Lowe }
198*10d63b7dSRichard Lowe line->body.line.less = target;
199*10d63b7dSRichard Lowe }
200*10d63b7dSRichard Lowe line->body.line.percent = NULL;
201*10d63b7dSRichard Lowe }
202*10d63b7dSRichard Lowe
203*10d63b7dSRichard Lowe
204*10d63b7dSRichard Lowe
205*10d63b7dSRichard Lowe Name
find_dyntarget(Name target)206*10d63b7dSRichard Lowe find_dyntarget(Name target)
207*10d63b7dSRichard Lowe {
208*10d63b7dSRichard Lowe Dyntarget p;
209*10d63b7dSRichard Lowe int i;
210*10d63b7dSRichard Lowe String_rec string;
211*10d63b7dSRichard Lowe wchar_t buffer[STRING_BUFFER_LENGTH];
212*10d63b7dSRichard Lowe wchar_t *pp, * bufend;
213*10d63b7dSRichard Lowe wchar_t tbuffer[MAXPATHLEN];
214*10d63b7dSRichard Lowe Wstring wcb(target);
215*10d63b7dSRichard Lowe
216*10d63b7dSRichard Lowe for (p = dyntarget_list; p != NULL; p = p->next) {
217*10d63b7dSRichard Lowe INIT_STRING_FROM_STACK(string, buffer);
218*10d63b7dSRichard Lowe expand_value(p->name, &string, false);
219*10d63b7dSRichard Lowe i = 0;
220*10d63b7dSRichard Lowe pp = string.buffer.start;
221*10d63b7dSRichard Lowe bufend = pp + STRING_BUFFER_LENGTH;
222*10d63b7dSRichard Lowe while((*pp != nul_char) && (pp < bufend)) {
223*10d63b7dSRichard Lowe if(iswspace(*pp)) {
224*10d63b7dSRichard Lowe tbuffer[i] = nul_char;
225*10d63b7dSRichard Lowe if(i > 0) {
226*10d63b7dSRichard Lowe if (wcb.equal(tbuffer)) {
227*10d63b7dSRichard Lowe enter_explicit_rule_from_dynamic_rule(target, p->name);
228*10d63b7dSRichard Lowe return(target);
229*10d63b7dSRichard Lowe }
230*10d63b7dSRichard Lowe }
231*10d63b7dSRichard Lowe pp++;
232*10d63b7dSRichard Lowe i = 0;
233*10d63b7dSRichard Lowe continue;
234*10d63b7dSRichard Lowe }
235*10d63b7dSRichard Lowe tbuffer[i] = *pp;
236*10d63b7dSRichard Lowe i++;
237*10d63b7dSRichard Lowe pp++;
238*10d63b7dSRichard Lowe if(*pp == nul_char) {
239*10d63b7dSRichard Lowe tbuffer[i] = nul_char;
240*10d63b7dSRichard Lowe if(i > 0) {
241*10d63b7dSRichard Lowe if (wcb.equal(tbuffer)) {
242*10d63b7dSRichard Lowe enter_explicit_rule_from_dynamic_rule(target, p->name);
243*10d63b7dSRichard Lowe return(target);
244*10d63b7dSRichard Lowe }
245*10d63b7dSRichard Lowe }
246*10d63b7dSRichard Lowe break;
247*10d63b7dSRichard Lowe }
248*10d63b7dSRichard Lowe }
249*10d63b7dSRichard Lowe }
250*10d63b7dSRichard Lowe return(NULL);
251*10d63b7dSRichard Lowe }
252*10d63b7dSRichard Lowe
253*10d63b7dSRichard Lowe /*
254*10d63b7dSRichard Lowe * DONE.
255*10d63b7dSRichard Lowe *
256*10d63b7dSRichard Lowe * doname(target, do_get, implicit)
257*10d63b7dSRichard Lowe *
258*10d63b7dSRichard Lowe * Chases all files the target depends on and builds any that
259*10d63b7dSRichard Lowe * are out of date. If the target is out of date it is then rebuilt.
260*10d63b7dSRichard Lowe *
261*10d63b7dSRichard Lowe * Return value:
262*10d63b7dSRichard Lowe * Indiates if build failed or nt
263*10d63b7dSRichard Lowe *
264*10d63b7dSRichard Lowe * Parameters:
265*10d63b7dSRichard Lowe * target Target to build
266*10d63b7dSRichard Lowe * do_get Run sccs get is nessecary
267*10d63b7dSRichard Lowe * implicit doname is trying to find an implicit rule
268*10d63b7dSRichard Lowe *
269*10d63b7dSRichard Lowe * Global variables used:
270*10d63b7dSRichard Lowe * assign_done True if command line assgnment has happened
271*10d63b7dSRichard Lowe * commands_done Preserved for the case that we need local value
272*10d63b7dSRichard Lowe * debug_level Should we trace make's actions?
273*10d63b7dSRichard Lowe * default_rule The rule for ".DEFAULT", used as last resort
274*10d63b7dSRichard Lowe * empty_name The Name "", used when looking for single sfx
275*10d63b7dSRichard Lowe * keep_state Indicates that .KEEP_STATE is on
276*10d63b7dSRichard Lowe * parallel True if building in parallel
277*10d63b7dSRichard Lowe * recursion_level Used for tracing
278*10d63b7dSRichard Lowe * report_dependencies make -P is on
279*10d63b7dSRichard Lowe */
280*10d63b7dSRichard Lowe Doname
doname(register Name target,register Boolean do_get,register Boolean implicit,register Boolean automatic)281*10d63b7dSRichard Lowe doname(register Name target, register Boolean do_get, register Boolean implicit, register Boolean automatic)
282*10d63b7dSRichard Lowe {
283*10d63b7dSRichard Lowe Doname result = build_dont_know;
284*10d63b7dSRichard Lowe Chain out_of_date_list = NULL;
285*10d63b7dSRichard Lowe Chain target_group;
286*10d63b7dSRichard Lowe Property old_locals = NULL;
287*10d63b7dSRichard Lowe register Property line;
288*10d63b7dSRichard Lowe Property command = NULL;
289*10d63b7dSRichard Lowe register Dependency dependency;
290*10d63b7dSRichard Lowe Name less = NULL;
291*10d63b7dSRichard Lowe Name true_target = target;
292*10d63b7dSRichard Lowe Name *automatics = NULL;
293*10d63b7dSRichard Lowe register int auto_count;
294*10d63b7dSRichard Lowe Boolean rechecking_target = false;
295*10d63b7dSRichard Lowe Boolean saved_commands_done;
296*10d63b7dSRichard Lowe Boolean restart = false;
297*10d63b7dSRichard Lowe Boolean save_parallel = parallel;
298*10d63b7dSRichard Lowe Boolean doing_subtree = false;
299*10d63b7dSRichard Lowe
300*10d63b7dSRichard Lowe Boolean recheck_conditionals = false;
301*10d63b7dSRichard Lowe
302*10d63b7dSRichard Lowe if (target->state == build_running) {
303*10d63b7dSRichard Lowe return build_running;
304*10d63b7dSRichard Lowe }
305*10d63b7dSRichard Lowe line = get_prop(target->prop, line_prop);
306*10d63b7dSRichard Lowe if (line != NULL) {
307*10d63b7dSRichard Lowe /*
308*10d63b7dSRichard Lowe * If this target is a member of target group and one of the
309*10d63b7dSRichard Lowe * other members of the group is running, mark this target
310*10d63b7dSRichard Lowe * as running.
311*10d63b7dSRichard Lowe */
312*10d63b7dSRichard Lowe for (target_group = line->body.line.target_group;
313*10d63b7dSRichard Lowe target_group != NULL;
314*10d63b7dSRichard Lowe target_group = target_group->next) {
315*10d63b7dSRichard Lowe if (is_running(target_group->name)) {
316*10d63b7dSRichard Lowe target->state = build_running;
317*10d63b7dSRichard Lowe add_pending(target,
318*10d63b7dSRichard Lowe recursion_level,
319*10d63b7dSRichard Lowe do_get,
320*10d63b7dSRichard Lowe implicit,
321*10d63b7dSRichard Lowe false);
322*10d63b7dSRichard Lowe return build_running;
323*10d63b7dSRichard Lowe }
324*10d63b7dSRichard Lowe }
325*10d63b7dSRichard Lowe }
326*10d63b7dSRichard Lowe /*
327*10d63b7dSRichard Lowe * If the target is a constructed one for a "::" target,
328*10d63b7dSRichard Lowe * we need to consider that.
329*10d63b7dSRichard Lowe */
330*10d63b7dSRichard Lowe if (target->has_target_prop) {
331*10d63b7dSRichard Lowe true_target = get_prop(target->prop,
332*10d63b7dSRichard Lowe target_prop)->body.target.target;
333*10d63b7dSRichard Lowe if (true_target->colon_splits > 0) {
334*10d63b7dSRichard Lowe /* Make sure we have a valid time for :: targets */
335*10d63b7dSRichard Lowe Property time;
336*10d63b7dSRichard Lowe
337*10d63b7dSRichard Lowe time = get_prop(true_target->prop, time_prop);
338*10d63b7dSRichard Lowe if (time != NULL) {
339*10d63b7dSRichard Lowe true_target->stat.time = time->body.time.time;
340*10d63b7dSRichard Lowe }
341*10d63b7dSRichard Lowe }
342*10d63b7dSRichard Lowe }
343*10d63b7dSRichard Lowe (void) exists(true_target);
344*10d63b7dSRichard Lowe /*
345*10d63b7dSRichard Lowe * If the target has been processed, we don't need to do it again,
346*10d63b7dSRichard Lowe * unless it depends on conditional macros or a delayed assignment,
347*10d63b7dSRichard Lowe * or it has been done when KEEP_STATE is on.
348*10d63b7dSRichard Lowe */
349*10d63b7dSRichard Lowe if (target->state == build_ok) {
350*10d63b7dSRichard Lowe if((!keep_state || (!target->depends_on_conditional && !assign_done))) {
351*10d63b7dSRichard Lowe return build_ok;
352*10d63b7dSRichard Lowe } else {
353*10d63b7dSRichard Lowe recheck_conditionals = true;
354*10d63b7dSRichard Lowe }
355*10d63b7dSRichard Lowe }
356*10d63b7dSRichard Lowe if (target->state == build_subtree) {
357*10d63b7dSRichard Lowe /* A dynamic macro subtree is being built */
358*10d63b7dSRichard Lowe target->state = build_dont_know;
359*10d63b7dSRichard Lowe doing_subtree = true;
360*10d63b7dSRichard Lowe if (!target->checking_subtree) {
361*10d63b7dSRichard Lowe /*
362*10d63b7dSRichard Lowe * This target has been started before and therefore
363*10d63b7dSRichard Lowe * not all dependencies have to be built.
364*10d63b7dSRichard Lowe */
365*10d63b7dSRichard Lowe restart = true;
366*10d63b7dSRichard Lowe }
367*10d63b7dSRichard Lowe } else if (target->state == build_pending) {
368*10d63b7dSRichard Lowe target->state = build_dont_know;
369*10d63b7dSRichard Lowe restart = true;
370*10d63b7dSRichard Lowe /*
371*10d63b7dSRichard Lowe } else if (parallel &&
372*10d63b7dSRichard Lowe keep_state &&
373*10d63b7dSRichard Lowe (target->conditional_cnt > 0)) {
374*10d63b7dSRichard Lowe if (!parallel_ok(target, false)) {
375*10d63b7dSRichard Lowe add_subtree(target, recursion_level, do_get, implicit);
376*10d63b7dSRichard Lowe target->state = build_running;
377*10d63b7dSRichard Lowe return build_running;
378*10d63b7dSRichard Lowe }
379*10d63b7dSRichard Lowe */
380*10d63b7dSRichard Lowe }
381*10d63b7dSRichard Lowe /*
382*10d63b7dSRichard Lowe * If KEEP_STATE is on, we have to rebuild the target if the
383*10d63b7dSRichard Lowe * building of it caused new automatic dependencies to be reported.
384*10d63b7dSRichard Lowe * This is where we restart the build.
385*10d63b7dSRichard Lowe */
386*10d63b7dSRichard Lowe if (line != NULL) {
387*10d63b7dSRichard Lowe line->body.line.percent = NULL;
388*10d63b7dSRichard Lowe }
389*10d63b7dSRichard Lowe recheck_target:
390*10d63b7dSRichard Lowe /* Init all local variables */
391*10d63b7dSRichard Lowe result = build_dont_know;
392*10d63b7dSRichard Lowe out_of_date_list = NULL;
393*10d63b7dSRichard Lowe command = NULL;
394*10d63b7dSRichard Lowe less = NULL;
395*10d63b7dSRichard Lowe auto_count = 0;
396*10d63b7dSRichard Lowe if (!restart && line != NULL) {
397*10d63b7dSRichard Lowe /*
398*10d63b7dSRichard Lowe * If this target has never been built before, mark all
399*10d63b7dSRichard Lowe * of the dependencies as never built.
400*10d63b7dSRichard Lowe */
401*10d63b7dSRichard Lowe for (dependency = line->body.line.dependencies;
402*10d63b7dSRichard Lowe dependency != NULL;
403*10d63b7dSRichard Lowe dependency = dependency->next) {
404*10d63b7dSRichard Lowe dependency->built = false;
405*10d63b7dSRichard Lowe }
406*10d63b7dSRichard Lowe }
407*10d63b7dSRichard Lowe /* Save the set of automatic depes defined for this target */
408*10d63b7dSRichard Lowe if (keep_state &&
409*10d63b7dSRichard Lowe (line != NULL) &&
410*10d63b7dSRichard Lowe (line->body.line.dependencies != NULL)) {
411*10d63b7dSRichard Lowe Name *p;
412*10d63b7dSRichard Lowe
413*10d63b7dSRichard Lowe /*
414*10d63b7dSRichard Lowe * First run thru the dependency list to see how many
415*10d63b7dSRichard Lowe * autos there are.
416*10d63b7dSRichard Lowe */
417*10d63b7dSRichard Lowe for (dependency = line->body.line.dependencies;
418*10d63b7dSRichard Lowe dependency != NULL;
419*10d63b7dSRichard Lowe dependency = dependency->next) {
420*10d63b7dSRichard Lowe if (dependency->automatic && !dependency->stale) {
421*10d63b7dSRichard Lowe auto_count++;
422*10d63b7dSRichard Lowe }
423*10d63b7dSRichard Lowe }
424*10d63b7dSRichard Lowe /* Create vector to hold the current autos */
425*10d63b7dSRichard Lowe automatics =
426*10d63b7dSRichard Lowe (Name *) alloca((int) (auto_count * sizeof (Name)));
427*10d63b7dSRichard Lowe /* Copy them */
428*10d63b7dSRichard Lowe for (p = automatics, dependency = line->body.line.dependencies;
429*10d63b7dSRichard Lowe dependency != NULL;
430*10d63b7dSRichard Lowe dependency = dependency->next) {
431*10d63b7dSRichard Lowe if (dependency->automatic && !dependency->stale) {
432*10d63b7dSRichard Lowe *p++ = dependency->name;
433*10d63b7dSRichard Lowe }
434*10d63b7dSRichard Lowe }
435*10d63b7dSRichard Lowe }
436*10d63b7dSRichard Lowe if (debug_level > 1) {
437*10d63b7dSRichard Lowe (void) printf("%*sdoname(%s)\n",
438*10d63b7dSRichard Lowe recursion_level,
439*10d63b7dSRichard Lowe "",
440*10d63b7dSRichard Lowe target->string_mb);
441*10d63b7dSRichard Lowe }
442*10d63b7dSRichard Lowe recursion_level++;
443*10d63b7dSRichard Lowe /* Avoid infinite loops */
444*10d63b7dSRichard Lowe if (target->state == build_in_progress) {
445*10d63b7dSRichard Lowe warning(gettext("Infinite loop: Target `%s' depends on itself"),
446*10d63b7dSRichard Lowe target->string_mb);
447*10d63b7dSRichard Lowe return build_ok;
448*10d63b7dSRichard Lowe }
449*10d63b7dSRichard Lowe target->state = build_in_progress;
450*10d63b7dSRichard Lowe
451*10d63b7dSRichard Lowe /* Activate conditional macros for the target */
452*10d63b7dSRichard Lowe if (!target->added_pattern_conditionals) {
453*10d63b7dSRichard Lowe add_pattern_conditionals(target);
454*10d63b7dSRichard Lowe target->added_pattern_conditionals = true;
455*10d63b7dSRichard Lowe }
456*10d63b7dSRichard Lowe if (target->conditional_cnt > 0) {
457*10d63b7dSRichard Lowe old_locals = (Property) alloca(target->conditional_cnt *
458*10d63b7dSRichard Lowe sizeof (Property_rec));
459*10d63b7dSRichard Lowe set_locals(target, old_locals);
460*10d63b7dSRichard Lowe }
461*10d63b7dSRichard Lowe
462*10d63b7dSRichard Lowe /*
463*10d63b7dSRichard Lowe * after making the call to dynamic_dependecies unconditional we can handle
464*10d63b7dSRichard Lowe * target names that are same as file name. In this case $$@ in the
465*10d63b7dSRichard Lowe * dependencies did not mean anything. WIth this change it expands it
466*10d63b7dSRichard Lowe * as expected.
467*10d63b7dSRichard Lowe */
468*10d63b7dSRichard Lowe if (!target->has_depe_list_expanded)
469*10d63b7dSRichard Lowe {
470*10d63b7dSRichard Lowe dynamic_dependencies(target);
471*10d63b7dSRichard Lowe }
472*10d63b7dSRichard Lowe
473*10d63b7dSRichard Lowe /*
474*10d63b7dSRichard Lowe * FIRST SECTION -- GO THROUGH DEPENDENCIES AND COLLECT EXPLICIT
475*10d63b7dSRichard Lowe * COMMANDS TO RUN
476*10d63b7dSRichard Lowe */
477*10d63b7dSRichard Lowe if ((line = get_prop(target->prop, line_prop)) != NULL) {
478*10d63b7dSRichard Lowe if (check_dependencies(&result,
479*10d63b7dSRichard Lowe line,
480*10d63b7dSRichard Lowe do_get,
481*10d63b7dSRichard Lowe target,
482*10d63b7dSRichard Lowe true_target,
483*10d63b7dSRichard Lowe doing_subtree,
484*10d63b7dSRichard Lowe &out_of_date_list,
485*10d63b7dSRichard Lowe old_locals,
486*10d63b7dSRichard Lowe implicit,
487*10d63b7dSRichard Lowe &command,
488*10d63b7dSRichard Lowe less,
489*10d63b7dSRichard Lowe rechecking_target,
490*10d63b7dSRichard Lowe recheck_conditionals)) {
491*10d63b7dSRichard Lowe return build_running;
492*10d63b7dSRichard Lowe }
493*10d63b7dSRichard Lowe if (line->body.line.query != NULL) {
494*10d63b7dSRichard Lowe delete_query_chain(line->body.line.query);
495*10d63b7dSRichard Lowe }
496*10d63b7dSRichard Lowe line->body.line.query = out_of_date_list;
497*10d63b7dSRichard Lowe }
498*10d63b7dSRichard Lowe
499*10d63b7dSRichard Lowe
500*10d63b7dSRichard Lowe /*
501*10d63b7dSRichard Lowe * If the target is a :: type, do not try to find the rule for the target,
502*10d63b7dSRichard Lowe * all actions will be taken by separate branches.
503*10d63b7dSRichard Lowe * Else, we try to find an implicit rule using various methods,
504*10d63b7dSRichard Lowe * we quit as soon as one is found.
505*10d63b7dSRichard Lowe *
506*10d63b7dSRichard Lowe * [tolik, 12 Sep 2002] Do not try to find implicit rule for the target
507*10d63b7dSRichard Lowe * being rechecked - the target is being rechecked means that it already
508*10d63b7dSRichard Lowe * has explicit dependencies derived from an implicit rule found
509*10d63b7dSRichard Lowe * in previous step.
510*10d63b7dSRichard Lowe */
511*10d63b7dSRichard Lowe if (target->colon_splits == 0 && !rechecking_target) {
512*10d63b7dSRichard Lowe /* Look for percent matched rule */
513*10d63b7dSRichard Lowe if ((result == build_dont_know) &&
514*10d63b7dSRichard Lowe (command == NULL)) {
515*10d63b7dSRichard Lowe switch (find_percent_rule(
516*10d63b7dSRichard Lowe target,
517*10d63b7dSRichard Lowe &command,
518*10d63b7dSRichard Lowe recheck_conditionals)) {
519*10d63b7dSRichard Lowe case build_failed:
520*10d63b7dSRichard Lowe result = build_failed;
521*10d63b7dSRichard Lowe break;
522*10d63b7dSRichard Lowe case build_running:
523*10d63b7dSRichard Lowe target->state = build_running;
524*10d63b7dSRichard Lowe add_pending(target,
525*10d63b7dSRichard Lowe --recursion_level,
526*10d63b7dSRichard Lowe do_get,
527*10d63b7dSRichard Lowe implicit,
528*10d63b7dSRichard Lowe false);
529*10d63b7dSRichard Lowe if (target->conditional_cnt > 0) {
530*10d63b7dSRichard Lowe reset_locals(target,
531*10d63b7dSRichard Lowe old_locals,
532*10d63b7dSRichard Lowe get_prop(target->prop,
533*10d63b7dSRichard Lowe conditional_prop),
534*10d63b7dSRichard Lowe 0);
535*10d63b7dSRichard Lowe }
536*10d63b7dSRichard Lowe return build_running;
537*10d63b7dSRichard Lowe case build_ok:
538*10d63b7dSRichard Lowe result = build_ok;
539*10d63b7dSRichard Lowe break;
540*10d63b7dSRichard Lowe }
541*10d63b7dSRichard Lowe }
542*10d63b7dSRichard Lowe /* Look for double suffix rule */
543*10d63b7dSRichard Lowe if (result == build_dont_know) {
544*10d63b7dSRichard Lowe Property member;
545*10d63b7dSRichard Lowe
546*10d63b7dSRichard Lowe if (target->is_member &&
547*10d63b7dSRichard Lowe ((member = get_prop(target->prop, member_prop)) !=
548*10d63b7dSRichard Lowe NULL)) {
549*10d63b7dSRichard Lowe switch (find_ar_suffix_rule(target,
550*10d63b7dSRichard Lowe member->body.
551*10d63b7dSRichard Lowe member.member,
552*10d63b7dSRichard Lowe &command,
553*10d63b7dSRichard Lowe recheck_conditionals)) {
554*10d63b7dSRichard Lowe case build_failed:
555*10d63b7dSRichard Lowe result = build_failed;
556*10d63b7dSRichard Lowe break;
557*10d63b7dSRichard Lowe case build_running:
558*10d63b7dSRichard Lowe target->state = build_running;
559*10d63b7dSRichard Lowe add_pending(target,
560*10d63b7dSRichard Lowe --recursion_level,
561*10d63b7dSRichard Lowe do_get,
562*10d63b7dSRichard Lowe implicit,
563*10d63b7dSRichard Lowe false);
564*10d63b7dSRichard Lowe if (target->conditional_cnt > 0) {
565*10d63b7dSRichard Lowe reset_locals(target,
566*10d63b7dSRichard Lowe old_locals,
567*10d63b7dSRichard Lowe get_prop(target->prop,
568*10d63b7dSRichard Lowe conditional_prop),
569*10d63b7dSRichard Lowe 0);
570*10d63b7dSRichard Lowe }
571*10d63b7dSRichard Lowe return build_running;
572*10d63b7dSRichard Lowe default:
573*10d63b7dSRichard Lowe /* ALWAYS bind $% for old style */
574*10d63b7dSRichard Lowe /* ar rules */
575*10d63b7dSRichard Lowe if (line == NULL) {
576*10d63b7dSRichard Lowe line =
577*10d63b7dSRichard Lowe maybe_append_prop(target,
578*10d63b7dSRichard Lowe line_prop);
579*10d63b7dSRichard Lowe }
580*10d63b7dSRichard Lowe line->body.line.percent =
581*10d63b7dSRichard Lowe member->body.member.member;
582*10d63b7dSRichard Lowe break;
583*10d63b7dSRichard Lowe }
584*10d63b7dSRichard Lowe } else {
585*10d63b7dSRichard Lowe switch (find_double_suffix_rule(target,
586*10d63b7dSRichard Lowe &command,
587*10d63b7dSRichard Lowe recheck_conditionals)) {
588*10d63b7dSRichard Lowe case build_failed:
589*10d63b7dSRichard Lowe result = build_failed;
590*10d63b7dSRichard Lowe break;
591*10d63b7dSRichard Lowe case build_running:
592*10d63b7dSRichard Lowe target->state = build_running;
593*10d63b7dSRichard Lowe add_pending(target,
594*10d63b7dSRichard Lowe --recursion_level,
595*10d63b7dSRichard Lowe do_get,
596*10d63b7dSRichard Lowe implicit,
597*10d63b7dSRichard Lowe false);
598*10d63b7dSRichard Lowe if (target->conditional_cnt > 0) {
599*10d63b7dSRichard Lowe reset_locals(target,
600*10d63b7dSRichard Lowe old_locals,
601*10d63b7dSRichard Lowe get_prop(target->
602*10d63b7dSRichard Lowe prop,
603*10d63b7dSRichard Lowe conditional_prop),
604*10d63b7dSRichard Lowe 0);
605*10d63b7dSRichard Lowe }
606*10d63b7dSRichard Lowe return build_running;
607*10d63b7dSRichard Lowe }
608*10d63b7dSRichard Lowe }
609*10d63b7dSRichard Lowe }
610*10d63b7dSRichard Lowe /* Look for single suffix rule */
611*10d63b7dSRichard Lowe
612*10d63b7dSRichard Lowe /* /tolik/
613*10d63b7dSRichard Lowe * I commented !implicit to fix bug 1247448: Suffix Rules failed when combine with Pattern Matching Rules.
614*10d63b7dSRichard Lowe * This caused problem with SVR4 tilde rules (infinite recursion). So I made some changes in "implicit.cc"
615*10d63b7dSRichard Lowe */
616*10d63b7dSRichard Lowe /* /tolik, 06.21.96/
617*10d63b7dSRichard Lowe * Regression! See BugId 1255360
618*10d63b7dSRichard Lowe * If more than one percent rules are defined for the same target then
619*10d63b7dSRichard Lowe * the behaviour of 'make' with my previous fix may be different from one
620*10d63b7dSRichard Lowe * of the 'old make'.
621*10d63b7dSRichard Lowe * The global variable second_pass (maybe it should be an argument to doname())
622*10d63b7dSRichard Lowe * is intended to avoid this regression. It is set in doname_check().
623*10d63b7dSRichard Lowe * First, 'make' will work as it worked before. Only when it is
624*10d63b7dSRichard Lowe * going to say "don't know how to make target" it sets second_pass to true and
625*10d63b7dSRichard Lowe * run 'doname' again but now trying to use Single Suffix Rules.
626*10d63b7dSRichard Lowe */
627*10d63b7dSRichard Lowe if ((result == build_dont_know) && !automatic && (!implicit || second_pass) &&
628*10d63b7dSRichard Lowe ((line == NULL) ||
629*10d63b7dSRichard Lowe ((line->body.line.target != NULL) &&
630*10d63b7dSRichard Lowe !line->body.line.target->has_regular_dependency))) {
631*10d63b7dSRichard Lowe switch (find_suffix_rule(target,
632*10d63b7dSRichard Lowe target,
633*10d63b7dSRichard Lowe empty_name,
634*10d63b7dSRichard Lowe &command,
635*10d63b7dSRichard Lowe recheck_conditionals)) {
636*10d63b7dSRichard Lowe case build_failed:
637*10d63b7dSRichard Lowe result = build_failed;
638*10d63b7dSRichard Lowe break;
639*10d63b7dSRichard Lowe case build_running:
640*10d63b7dSRichard Lowe target->state = build_running;
641*10d63b7dSRichard Lowe add_pending(target,
642*10d63b7dSRichard Lowe --recursion_level,
643*10d63b7dSRichard Lowe do_get,
644*10d63b7dSRichard Lowe implicit,
645*10d63b7dSRichard Lowe false);
646*10d63b7dSRichard Lowe if (target->conditional_cnt > 0) {
647*10d63b7dSRichard Lowe reset_locals(target,
648*10d63b7dSRichard Lowe old_locals,
649*10d63b7dSRichard Lowe get_prop(target->prop,
650*10d63b7dSRichard Lowe conditional_prop),
651*10d63b7dSRichard Lowe 0);
652*10d63b7dSRichard Lowe }
653*10d63b7dSRichard Lowe return build_running;
654*10d63b7dSRichard Lowe }
655*10d63b7dSRichard Lowe }
656*10d63b7dSRichard Lowe /* Try to sccs get */
657*10d63b7dSRichard Lowe if ((command == NULL) &&
658*10d63b7dSRichard Lowe (result == build_dont_know) &&
659*10d63b7dSRichard Lowe do_get) {
660*10d63b7dSRichard Lowe result = sccs_get(target, &command);
661*10d63b7dSRichard Lowe }
662*10d63b7dSRichard Lowe
663*10d63b7dSRichard Lowe /* Use .DEFAULT rule if it is defined. */
664*10d63b7dSRichard Lowe if ((command == NULL) &&
665*10d63b7dSRichard Lowe (result == build_dont_know) &&
666*10d63b7dSRichard Lowe (true_target->colons == no_colon) &&
667*10d63b7dSRichard Lowe default_rule &&
668*10d63b7dSRichard Lowe !implicit) {
669*10d63b7dSRichard Lowe /* Make sure we have a line prop */
670*10d63b7dSRichard Lowe line = maybe_append_prop(target, line_prop);
671*10d63b7dSRichard Lowe command = line;
672*10d63b7dSRichard Lowe Boolean out_of_date;
673*10d63b7dSRichard Lowe if (true_target->is_member) {
674*10d63b7dSRichard Lowe out_of_date = (Boolean) OUT_OF_DATE_SEC(true_target->stat.time,
675*10d63b7dSRichard Lowe line->body.line.dependency_time);
676*10d63b7dSRichard Lowe } else {
677*10d63b7dSRichard Lowe out_of_date = (Boolean) OUT_OF_DATE(true_target->stat.time,
678*10d63b7dSRichard Lowe line->body.line.dependency_time);
679*10d63b7dSRichard Lowe }
680*10d63b7dSRichard Lowe if (build_unconditional || out_of_date) {
681*10d63b7dSRichard Lowe line->body.line.is_out_of_date = true;
682*10d63b7dSRichard Lowe if (debug_level > 0) {
683*10d63b7dSRichard Lowe (void) printf(gettext("%*sBuilding %s using .DEFAULT because it is out of date\n"),
684*10d63b7dSRichard Lowe recursion_level,
685*10d63b7dSRichard Lowe "",
686*10d63b7dSRichard Lowe true_target->string_mb);
687*10d63b7dSRichard Lowe }
688*10d63b7dSRichard Lowe }
689*10d63b7dSRichard Lowe line->body.line.sccs_command = false;
690*10d63b7dSRichard Lowe line->body.line.command_template = default_rule;
691*10d63b7dSRichard Lowe line->body.line.target = true_target;
692*10d63b7dSRichard Lowe line->body.line.star = NULL;
693*10d63b7dSRichard Lowe line->body.line.less = true_target;
694*10d63b7dSRichard Lowe line->body.line.percent = NULL;
695*10d63b7dSRichard Lowe }
696*10d63b7dSRichard Lowe }
697*10d63b7dSRichard Lowe
698*10d63b7dSRichard Lowe /* We say "target up to date" if no cmd were executed for the target */
699*10d63b7dSRichard Lowe if (!target->is_double_colon_parent) {
700*10d63b7dSRichard Lowe commands_done = false;
701*10d63b7dSRichard Lowe }
702*10d63b7dSRichard Lowe
703*10d63b7dSRichard Lowe silent = silent_all;
704*10d63b7dSRichard Lowe ignore_errors = ignore_errors_all;
705*10d63b7dSRichard Lowe if (posix)
706*10d63b7dSRichard Lowe {
707*10d63b7dSRichard Lowe if (!silent)
708*10d63b7dSRichard Lowe {
709*10d63b7dSRichard Lowe silent = (Boolean) target->silent_mode;
710*10d63b7dSRichard Lowe }
711*10d63b7dSRichard Lowe if (!ignore_errors)
712*10d63b7dSRichard Lowe {
713*10d63b7dSRichard Lowe ignore_errors = (Boolean) target->ignore_error_mode;
714*10d63b7dSRichard Lowe }
715*10d63b7dSRichard Lowe }
716*10d63b7dSRichard Lowe
717*10d63b7dSRichard Lowe int doname_dyntarget = 0;
718*10d63b7dSRichard Lowe r_command:
719*10d63b7dSRichard Lowe /* Run commands if any. */
720*10d63b7dSRichard Lowe if ((command != NULL) &&
721*10d63b7dSRichard Lowe (command->body.line.command_template != NULL)) {
722*10d63b7dSRichard Lowe if (result != build_failed) {
723*10d63b7dSRichard Lowe result = run_command(command,
724*10d63b7dSRichard Lowe (Boolean) ((parallel || save_parallel) && !silent));
725*10d63b7dSRichard Lowe }
726*10d63b7dSRichard Lowe switch (result) {
727*10d63b7dSRichard Lowe case build_running:
728*10d63b7dSRichard Lowe add_running(target,
729*10d63b7dSRichard Lowe true_target,
730*10d63b7dSRichard Lowe command,
731*10d63b7dSRichard Lowe --recursion_level,
732*10d63b7dSRichard Lowe auto_count,
733*10d63b7dSRichard Lowe automatics,
734*10d63b7dSRichard Lowe do_get,
735*10d63b7dSRichard Lowe implicit);
736*10d63b7dSRichard Lowe target->state = build_running;
737*10d63b7dSRichard Lowe if ((line = get_prop(target->prop,
738*10d63b7dSRichard Lowe line_prop)) != NULL) {
739*10d63b7dSRichard Lowe if (line->body.line.query != NULL) {
740*10d63b7dSRichard Lowe delete_query_chain(line->body.line.query);
741*10d63b7dSRichard Lowe }
742*10d63b7dSRichard Lowe line->body.line.query = NULL;
743*10d63b7dSRichard Lowe }
744*10d63b7dSRichard Lowe if (target->conditional_cnt > 0) {
745*10d63b7dSRichard Lowe reset_locals(target,
746*10d63b7dSRichard Lowe old_locals,
747*10d63b7dSRichard Lowe get_prop(target->prop,
748*10d63b7dSRichard Lowe conditional_prop),
749*10d63b7dSRichard Lowe 0);
750*10d63b7dSRichard Lowe }
751*10d63b7dSRichard Lowe return build_running;
752*10d63b7dSRichard Lowe case build_serial:
753*10d63b7dSRichard Lowe add_serial(target,
754*10d63b7dSRichard Lowe --recursion_level,
755*10d63b7dSRichard Lowe do_get,
756*10d63b7dSRichard Lowe implicit);
757*10d63b7dSRichard Lowe target->state = build_running;
758*10d63b7dSRichard Lowe line = get_prop(target->prop, line_prop);
759*10d63b7dSRichard Lowe if (line != NULL) {
760*10d63b7dSRichard Lowe if (line->body.line.query != NULL) {
761*10d63b7dSRichard Lowe delete_query_chain(line->body.line.query);
762*10d63b7dSRichard Lowe }
763*10d63b7dSRichard Lowe line->body.line.query = NULL;
764*10d63b7dSRichard Lowe }
765*10d63b7dSRichard Lowe if (target->conditional_cnt > 0) {
766*10d63b7dSRichard Lowe reset_locals(target,
767*10d63b7dSRichard Lowe old_locals,
768*10d63b7dSRichard Lowe get_prop(target->prop,
769*10d63b7dSRichard Lowe conditional_prop),
770*10d63b7dSRichard Lowe 0);
771*10d63b7dSRichard Lowe }
772*10d63b7dSRichard Lowe return build_running;
773*10d63b7dSRichard Lowe case build_ok:
774*10d63b7dSRichard Lowe /* If all went OK set a nice timestamp */
775*10d63b7dSRichard Lowe if (true_target->stat.time == file_doesnt_exist) {
776*10d63b7dSRichard Lowe true_target->stat.time = file_max_time;
777*10d63b7dSRichard Lowe }
778*10d63b7dSRichard Lowe break;
779*10d63b7dSRichard Lowe }
780*10d63b7dSRichard Lowe } else {
781*10d63b7dSRichard Lowe /*
782*10d63b7dSRichard Lowe * If no command was found for the target, and it doesn't
783*10d63b7dSRichard Lowe * exist, and it is mentioned as a target in the makefile,
784*10d63b7dSRichard Lowe * we say it is extremely new and that it is OK.
785*10d63b7dSRichard Lowe */
786*10d63b7dSRichard Lowe if (target->colons != no_colon) {
787*10d63b7dSRichard Lowe if (true_target->stat.time == file_doesnt_exist){
788*10d63b7dSRichard Lowe true_target->stat.time = file_max_time;
789*10d63b7dSRichard Lowe }
790*10d63b7dSRichard Lowe result = build_ok;
791*10d63b7dSRichard Lowe }
792*10d63b7dSRichard Lowe /*
793*10d63b7dSRichard Lowe * Trying dynamic targets.
794*10d63b7dSRichard Lowe */
795*10d63b7dSRichard Lowe if(!doname_dyntarget) {
796*10d63b7dSRichard Lowe doname_dyntarget = 1;
797*10d63b7dSRichard Lowe Name dtarg = find_dyntarget(target);
798*10d63b7dSRichard Lowe if(dtarg!=NULL) {
799*10d63b7dSRichard Lowe if (!target->has_depe_list_expanded) {
800*10d63b7dSRichard Lowe dynamic_dependencies(target);
801*10d63b7dSRichard Lowe }
802*10d63b7dSRichard Lowe if ((line = get_prop(target->prop, line_prop)) != NULL) {
803*10d63b7dSRichard Lowe if (check_dependencies(&result,
804*10d63b7dSRichard Lowe line,
805*10d63b7dSRichard Lowe do_get,
806*10d63b7dSRichard Lowe target,
807*10d63b7dSRichard Lowe true_target,
808*10d63b7dSRichard Lowe doing_subtree,
809*10d63b7dSRichard Lowe &out_of_date_list,
810*10d63b7dSRichard Lowe old_locals,
811*10d63b7dSRichard Lowe implicit,
812*10d63b7dSRichard Lowe &command,
813*10d63b7dSRichard Lowe less,
814*10d63b7dSRichard Lowe rechecking_target,
815*10d63b7dSRichard Lowe recheck_conditionals))
816*10d63b7dSRichard Lowe {
817*10d63b7dSRichard Lowe return build_running;
818*10d63b7dSRichard Lowe }
819*10d63b7dSRichard Lowe if (line->body.line.query != NULL) {
820*10d63b7dSRichard Lowe delete_query_chain(line->body.line.query);
821*10d63b7dSRichard Lowe }
822*10d63b7dSRichard Lowe line->body.line.query = out_of_date_list;
823*10d63b7dSRichard Lowe }
824*10d63b7dSRichard Lowe goto r_command;
825*10d63b7dSRichard Lowe }
826*10d63b7dSRichard Lowe }
827*10d63b7dSRichard Lowe /*
828*10d63b7dSRichard Lowe * If the file exists, it is OK that we couldnt figure
829*10d63b7dSRichard Lowe * out how to build it.
830*10d63b7dSRichard Lowe */
831*10d63b7dSRichard Lowe (void) exists(target);
832*10d63b7dSRichard Lowe if ((target->stat.time != file_doesnt_exist) &&
833*10d63b7dSRichard Lowe (result == build_dont_know)) {
834*10d63b7dSRichard Lowe result = build_ok;
835*10d63b7dSRichard Lowe }
836*10d63b7dSRichard Lowe }
837*10d63b7dSRichard Lowe
838*10d63b7dSRichard Lowe /*
839*10d63b7dSRichard Lowe * Some of the following is duplicated in the function finish_doname.
840*10d63b7dSRichard Lowe * If anything is changed here, check to see if it needs to be
841*10d63b7dSRichard Lowe * changed there.
842*10d63b7dSRichard Lowe */
843*10d63b7dSRichard Lowe if ((line = get_prop(target->prop, line_prop)) != NULL) {
844*10d63b7dSRichard Lowe if (line->body.line.query != NULL) {
845*10d63b7dSRichard Lowe delete_query_chain(line->body.line.query);
846*10d63b7dSRichard Lowe }
847*10d63b7dSRichard Lowe line->body.line.query = NULL;
848*10d63b7dSRichard Lowe }
849*10d63b7dSRichard Lowe target->state = result;
850*10d63b7dSRichard Lowe parallel = save_parallel;
851*10d63b7dSRichard Lowe if (target->conditional_cnt > 0) {
852*10d63b7dSRichard Lowe reset_locals(target,
853*10d63b7dSRichard Lowe old_locals,
854*10d63b7dSRichard Lowe get_prop(target->prop, conditional_prop),
855*10d63b7dSRichard Lowe 0);
856*10d63b7dSRichard Lowe }
857*10d63b7dSRichard Lowe recursion_level--;
858*10d63b7dSRichard Lowe if (target->is_member) {
859*10d63b7dSRichard Lowe Property member;
860*10d63b7dSRichard Lowe
861*10d63b7dSRichard Lowe /* Propagate the timestamp from the member file to the member*/
862*10d63b7dSRichard Lowe if ((target->stat.time != file_max_time) &&
863*10d63b7dSRichard Lowe ((member = get_prop(target->prop, member_prop)) != NULL) &&
864*10d63b7dSRichard Lowe (exists(member->body.member.member) > file_doesnt_exist)) {
865*10d63b7dSRichard Lowe target->stat.time =
866*10d63b7dSRichard Lowe member->body.member.member->stat.time;
867*10d63b7dSRichard Lowe }
868*10d63b7dSRichard Lowe }
869*10d63b7dSRichard Lowe /*
870*10d63b7dSRichard Lowe * Check if we found any new auto dependencies when we
871*10d63b7dSRichard Lowe * built the target.
872*10d63b7dSRichard Lowe */
873*10d63b7dSRichard Lowe if ((result == build_ok) && check_auto_dependencies(target,
874*10d63b7dSRichard Lowe auto_count,
875*10d63b7dSRichard Lowe automatics)) {
876*10d63b7dSRichard Lowe if (debug_level > 0) {
877*10d63b7dSRichard Lowe (void) printf(gettext("%*sTarget `%s' acquired new dependencies from build, rechecking all dependencies\n"),
878*10d63b7dSRichard Lowe recursion_level,
879*10d63b7dSRichard Lowe "",
880*10d63b7dSRichard Lowe true_target->string_mb);
881*10d63b7dSRichard Lowe }
882*10d63b7dSRichard Lowe rechecking_target = true;
883*10d63b7dSRichard Lowe saved_commands_done = commands_done;
884*10d63b7dSRichard Lowe goto recheck_target;
885*10d63b7dSRichard Lowe }
886*10d63b7dSRichard Lowe
887*10d63b7dSRichard Lowe if (rechecking_target && !commands_done) {
888*10d63b7dSRichard Lowe commands_done = saved_commands_done;
889*10d63b7dSRichard Lowe }
890*10d63b7dSRichard Lowe
891*10d63b7dSRichard Lowe return result;
892*10d63b7dSRichard Lowe }
893*10d63b7dSRichard Lowe
894*10d63b7dSRichard Lowe /*
895*10d63b7dSRichard Lowe * DONE.
896*10d63b7dSRichard Lowe *
897*10d63b7dSRichard Lowe * check_dependencies(result, line, do_get,
898*10d63b7dSRichard Lowe * target, true_target, doing_subtree, out_of_date_tail,
899*10d63b7dSRichard Lowe * old_locals, implicit, command, less, rechecking_target)
900*10d63b7dSRichard Lowe *
901*10d63b7dSRichard Lowe * Return value:
902*10d63b7dSRichard Lowe * True returned if some dependencies left running
903*10d63b7dSRichard Lowe *
904*10d63b7dSRichard Lowe * Parameters:
905*10d63b7dSRichard Lowe * result Pointer to cell we update if build failed
906*10d63b7dSRichard Lowe * line We get the dependencies from here
907*10d63b7dSRichard Lowe * do_get Allow use of sccs get in recursive doname()
908*10d63b7dSRichard Lowe * target The target to chase dependencies for
909*10d63b7dSRichard Lowe * true_target The real one for :: and lib(member)
910*10d63b7dSRichard Lowe * doing_subtree True if building a conditional macro subtree
911*10d63b7dSRichard Lowe * out_of_date_tail Used to set the $? list
912*10d63b7dSRichard Lowe * old_locals Used for resetting the local macros
913*10d63b7dSRichard Lowe * implicit Called when scanning for implicit rules?
914*10d63b7dSRichard Lowe * command Place to stuff command
915*10d63b7dSRichard Lowe * less Set to $< value
916*10d63b7dSRichard Lowe *
917*10d63b7dSRichard Lowe * Global variables used:
918*10d63b7dSRichard Lowe * command_changed Set if we suspect .make.state needs rewrite
919*10d63b7dSRichard Lowe * debug_level Should we trace actions?
920*10d63b7dSRichard Lowe * force The Name " FORCE", compared against
921*10d63b7dSRichard Lowe * recursion_level Used for tracing
922*10d63b7dSRichard Lowe * rewrite_statefile Set if .make.state needs rewriting
923*10d63b7dSRichard Lowe * wait_name The Name ".WAIT", compared against
924*10d63b7dSRichard Lowe */
925*10d63b7dSRichard Lowe static Boolean
check_dependencies(Doname * result,Property line,Boolean do_get,Name target,Name true_target,Boolean doing_subtree,Chain * out_of_date_tail,Property old_locals,Boolean implicit,Property * command,Name less,Boolean rechecking_target,Boolean recheck_conditionals)926*10d63b7dSRichard Lowe check_dependencies(Doname *result, Property line, Boolean do_get, Name target, Name true_target, Boolean doing_subtree, Chain *out_of_date_tail, Property old_locals, Boolean implicit, Property *command, Name less, Boolean rechecking_target, Boolean recheck_conditionals)
927*10d63b7dSRichard Lowe {
928*10d63b7dSRichard Lowe Boolean dependencies_running;
929*10d63b7dSRichard Lowe register Dependency dependency;
930*10d63b7dSRichard Lowe Doname dep_result;
931*10d63b7dSRichard Lowe Boolean dependency_changed = false;
932*10d63b7dSRichard Lowe
933*10d63b7dSRichard Lowe line->body.line.dependency_time = file_doesnt_exist;
934*10d63b7dSRichard Lowe if (line->body.line.query != NULL) {
935*10d63b7dSRichard Lowe delete_query_chain(line->body.line.query);
936*10d63b7dSRichard Lowe }
937*10d63b7dSRichard Lowe line->body.line.query = NULL;
938*10d63b7dSRichard Lowe line->body.line.is_out_of_date = false;
939*10d63b7dSRichard Lowe dependencies_running = false;
940*10d63b7dSRichard Lowe /*
941*10d63b7dSRichard Lowe * Run thru all the dependencies and call doname() recursively
942*10d63b7dSRichard Lowe * on each of them.
943*10d63b7dSRichard Lowe */
944*10d63b7dSRichard Lowe for (dependency = line->body.line.dependencies;
945*10d63b7dSRichard Lowe dependency != NULL;
946*10d63b7dSRichard Lowe dependency = dependency->next) {
947*10d63b7dSRichard Lowe Boolean this_dependency_changed = false;
948*10d63b7dSRichard Lowe
949*10d63b7dSRichard Lowe if (!dependency->automatic &&
950*10d63b7dSRichard Lowe (rechecking_target || target->rechecking_target)) {
951*10d63b7dSRichard Lowe /*
952*10d63b7dSRichard Lowe * We only bother with the autos when rechecking
953*10d63b7dSRichard Lowe */
954*10d63b7dSRichard Lowe continue;
955*10d63b7dSRichard Lowe }
956*10d63b7dSRichard Lowe
957*10d63b7dSRichard Lowe if (dependency->name == wait_name) {
958*10d63b7dSRichard Lowe /*
959*10d63b7dSRichard Lowe * The special target .WAIT means finish all of
960*10d63b7dSRichard Lowe * the prior dependencies before continuing.
961*10d63b7dSRichard Lowe */
962*10d63b7dSRichard Lowe if (dependencies_running) {
963*10d63b7dSRichard Lowe break;
964*10d63b7dSRichard Lowe }
965*10d63b7dSRichard Lowe } else if ((!parallel_ok(dependency->name, false)) &&
966*10d63b7dSRichard Lowe (dependencies_running)) {
967*10d63b7dSRichard Lowe /*
968*10d63b7dSRichard Lowe * If we can't execute the current dependency in
969*10d63b7dSRichard Lowe * parallel, hold off the dependency processing
970*10d63b7dSRichard Lowe * to preserve the order of the dependencies.
971*10d63b7dSRichard Lowe */
972*10d63b7dSRichard Lowe break;
973*10d63b7dSRichard Lowe } else {
974*10d63b7dSRichard Lowe timestruc_t depe_time = file_doesnt_exist;
975*10d63b7dSRichard Lowe
976*10d63b7dSRichard Lowe
977*10d63b7dSRichard Lowe if (true_target->is_member) {
978*10d63b7dSRichard Lowe depe_time = exists(dependency->name);
979*10d63b7dSRichard Lowe }
980*10d63b7dSRichard Lowe if (dependency->built ||
981*10d63b7dSRichard Lowe (dependency->name->state == build_failed)) {
982*10d63b7dSRichard Lowe dep_result = (Doname) dependency->name->state;
983*10d63b7dSRichard Lowe } else {
984*10d63b7dSRichard Lowe dep_result = doname_check(dependency->name,
985*10d63b7dSRichard Lowe do_get,
986*10d63b7dSRichard Lowe false,
987*10d63b7dSRichard Lowe (Boolean) dependency->automatic);
988*10d63b7dSRichard Lowe }
989*10d63b7dSRichard Lowe if (true_target->is_member || dependency->name->is_member) {
990*10d63b7dSRichard Lowe /* should compare only secs, cause lib members does not have nsec time resolution */
991*10d63b7dSRichard Lowe if (depe_time.tv_sec != dependency->name->stat.time.tv_sec) {
992*10d63b7dSRichard Lowe this_dependency_changed =
993*10d63b7dSRichard Lowe dependency_changed =
994*10d63b7dSRichard Lowe true;
995*10d63b7dSRichard Lowe }
996*10d63b7dSRichard Lowe } else {
997*10d63b7dSRichard Lowe if (depe_time != dependency->name->stat.time) {
998*10d63b7dSRichard Lowe this_dependency_changed =
999*10d63b7dSRichard Lowe dependency_changed =
1000*10d63b7dSRichard Lowe true;
1001*10d63b7dSRichard Lowe }
1002*10d63b7dSRichard Lowe }
1003*10d63b7dSRichard Lowe dependency->built = true;
1004*10d63b7dSRichard Lowe switch (dep_result) {
1005*10d63b7dSRichard Lowe case build_running:
1006*10d63b7dSRichard Lowe dependencies_running = true;
1007*10d63b7dSRichard Lowe continue;
1008*10d63b7dSRichard Lowe case build_failed:
1009*10d63b7dSRichard Lowe *result = build_failed;
1010*10d63b7dSRichard Lowe break;
1011*10d63b7dSRichard Lowe case build_dont_know:
1012*10d63b7dSRichard Lowe /*
1013*10d63b7dSRichard Lowe * If make can't figure out how to make a dependency, maybe the dependency
1014*10d63b7dSRichard Lowe * is out of date. In this case, we just declare the target out of date
1015*10d63b7dSRichard Lowe * and go on. If we really need the dependency, the make'ing of the target
1016*10d63b7dSRichard Lowe * will fail. This will only happen for automatic (hidden) dependencies.
1017*10d63b7dSRichard Lowe */
1018*10d63b7dSRichard Lowe if(!recheck_conditionals) {
1019*10d63b7dSRichard Lowe line->body.line.is_out_of_date = true;
1020*10d63b7dSRichard Lowe }
1021*10d63b7dSRichard Lowe /*
1022*10d63b7dSRichard Lowe * Make sure the dependency is not saved
1023*10d63b7dSRichard Lowe * in the state file.
1024*10d63b7dSRichard Lowe */
1025*10d63b7dSRichard Lowe dependency->stale = true;
1026*10d63b7dSRichard Lowe rewrite_statefile =
1027*10d63b7dSRichard Lowe command_changed =
1028*10d63b7dSRichard Lowe true;
1029*10d63b7dSRichard Lowe if (debug_level > 0) {
1030*10d63b7dSRichard Lowe (void) printf(gettext("Target %s rebuilt because dependency %s does not exist\n"),
1031*10d63b7dSRichard Lowe true_target->string_mb,
1032*10d63b7dSRichard Lowe dependency->name->string_mb);
1033*10d63b7dSRichard Lowe }
1034*10d63b7dSRichard Lowe break;
1035*10d63b7dSRichard Lowe }
1036*10d63b7dSRichard Lowe if (dependency->name->depends_on_conditional) {
1037*10d63b7dSRichard Lowe target->depends_on_conditional = true;
1038*10d63b7dSRichard Lowe }
1039*10d63b7dSRichard Lowe if (dependency->name == force) {
1040*10d63b7dSRichard Lowe target->stat.time =
1041*10d63b7dSRichard Lowe dependency->name->stat.time;
1042*10d63b7dSRichard Lowe }
1043*10d63b7dSRichard Lowe /*
1044*10d63b7dSRichard Lowe * Propagate new timestamp from "member" to
1045*10d63b7dSRichard Lowe * "lib.a(member)".
1046*10d63b7dSRichard Lowe */
1047*10d63b7dSRichard Lowe (void) exists(dependency->name);
1048*10d63b7dSRichard Lowe
1049*10d63b7dSRichard Lowe /* Collect the timestamp of the youngest dependency */
1050*10d63b7dSRichard Lowe line->body.line.dependency_time =
1051*10d63b7dSRichard Lowe MAX(dependency->name->stat.time,
1052*10d63b7dSRichard Lowe line->body.line.dependency_time);
1053*10d63b7dSRichard Lowe
1054*10d63b7dSRichard Lowe /* Correction: do not consider nanosecs for members */
1055*10d63b7dSRichard Lowe if(true_target->is_member || dependency->name->is_member) {
1056*10d63b7dSRichard Lowe line->body.line.dependency_time.tv_nsec = 0;
1057*10d63b7dSRichard Lowe }
1058*10d63b7dSRichard Lowe
1059*10d63b7dSRichard Lowe if (debug_level > 1) {
1060*10d63b7dSRichard Lowe (void) printf(gettext("%*sDate(%s)=%s \n"),
1061*10d63b7dSRichard Lowe recursion_level,
1062*10d63b7dSRichard Lowe "",
1063*10d63b7dSRichard Lowe dependency->name->string_mb,
1064*10d63b7dSRichard Lowe time_to_string(dependency->name->
1065*10d63b7dSRichard Lowe stat.time));
1066*10d63b7dSRichard Lowe if (dependency->name->stat.time > line->body.line.dependency_time) {
1067*10d63b7dSRichard Lowe (void) printf(gettext("%*sDate-dependencies(%s) set to %s\n"),
1068*10d63b7dSRichard Lowe recursion_level,
1069*10d63b7dSRichard Lowe "",
1070*10d63b7dSRichard Lowe true_target->string_mb,
1071*10d63b7dSRichard Lowe time_to_string(line->body.line.
1072*10d63b7dSRichard Lowe dependency_time));
1073*10d63b7dSRichard Lowe }
1074*10d63b7dSRichard Lowe }
1075*10d63b7dSRichard Lowe
1076*10d63b7dSRichard Lowe /* Build the $? list */
1077*10d63b7dSRichard Lowe if (true_target->is_member) {
1078*10d63b7dSRichard Lowe if (this_dependency_changed == true) {
1079*10d63b7dSRichard Lowe true_target->stat.time = dependency->name->stat.time;
1080*10d63b7dSRichard Lowe true_target->stat.time.tv_sec--;
1081*10d63b7dSRichard Lowe } else {
1082*10d63b7dSRichard Lowe /* Dina:
1083*10d63b7dSRichard Lowe * The next statement is commented
1084*10d63b7dSRichard Lowe * out as a fix for bug #1051032.
1085*10d63b7dSRichard Lowe * if dependency hasn't changed
1086*10d63b7dSRichard Lowe * then there's no need to invalidate
1087*10d63b7dSRichard Lowe * true_target. This statemnt causes
1088*10d63b7dSRichard Lowe * make to take much longer to process
1089*10d63b7dSRichard Lowe * an already-built archive. Soren
1090*10d63b7dSRichard Lowe * said it was a quick fix for some
1091*10d63b7dSRichard Lowe * problem he doesn't remember.
1092*10d63b7dSRichard Lowe true_target->stat.time = file_no_time;
1093*10d63b7dSRichard Lowe */
1094*10d63b7dSRichard Lowe (void) exists(true_target);
1095*10d63b7dSRichard Lowe }
1096*10d63b7dSRichard Lowe } else {
1097*10d63b7dSRichard Lowe (void) exists(true_target);
1098*10d63b7dSRichard Lowe }
1099*10d63b7dSRichard Lowe Boolean out_of_date;
1100*10d63b7dSRichard Lowe if (true_target->is_member || dependency->name->is_member) {
1101*10d63b7dSRichard Lowe out_of_date = (Boolean) OUT_OF_DATE_SEC(true_target->stat.time,
1102*10d63b7dSRichard Lowe dependency->name->stat.time);
1103*10d63b7dSRichard Lowe } else {
1104*10d63b7dSRichard Lowe out_of_date = (Boolean) OUT_OF_DATE(true_target->stat.time,
1105*10d63b7dSRichard Lowe dependency->name->stat.time);
1106*10d63b7dSRichard Lowe }
1107*10d63b7dSRichard Lowe if ((build_unconditional || out_of_date) &&
1108*10d63b7dSRichard Lowe (dependency->name != force) &&
1109*10d63b7dSRichard Lowe (dependency->stale == false)) {
1110*10d63b7dSRichard Lowe *out_of_date_tail = ALLOC(Chain);
1111*10d63b7dSRichard Lowe if (dependency->name->is_member &&
1112*10d63b7dSRichard Lowe (get_prop(dependency->name->prop,
1113*10d63b7dSRichard Lowe member_prop) != NULL)) {
1114*10d63b7dSRichard Lowe (*out_of_date_tail)->name =
1115*10d63b7dSRichard Lowe get_prop(dependency->name->prop,
1116*10d63b7dSRichard Lowe member_prop)->
1117*10d63b7dSRichard Lowe body.member.member;
1118*10d63b7dSRichard Lowe } else {
1119*10d63b7dSRichard Lowe (*out_of_date_tail)->name =
1120*10d63b7dSRichard Lowe dependency->name;
1121*10d63b7dSRichard Lowe }
1122*10d63b7dSRichard Lowe (*out_of_date_tail)->next = NULL;
1123*10d63b7dSRichard Lowe out_of_date_tail = &(*out_of_date_tail)->next;
1124*10d63b7dSRichard Lowe if (debug_level > 0) {
1125*10d63b7dSRichard Lowe if (dependency->name->stat.time == file_max_time) {
1126*10d63b7dSRichard Lowe (void) printf(gettext("%*sBuilding %s because %s does not exist\n"),
1127*10d63b7dSRichard Lowe recursion_level,
1128*10d63b7dSRichard Lowe "",
1129*10d63b7dSRichard Lowe true_target->string_mb,
1130*10d63b7dSRichard Lowe dependency->name->string_mb);
1131*10d63b7dSRichard Lowe } else {
1132*10d63b7dSRichard Lowe (void) printf(gettext("%*sBuilding %s because it is out of date relative to %s\n"),
1133*10d63b7dSRichard Lowe recursion_level,
1134*10d63b7dSRichard Lowe "",
1135*10d63b7dSRichard Lowe true_target->string_mb,
1136*10d63b7dSRichard Lowe dependency->name->string_mb);
1137*10d63b7dSRichard Lowe }
1138*10d63b7dSRichard Lowe }
1139*10d63b7dSRichard Lowe }
1140*10d63b7dSRichard Lowe if (dependency->name == force) {
1141*10d63b7dSRichard Lowe force->stat.time =
1142*10d63b7dSRichard Lowe file_max_time;
1143*10d63b7dSRichard Lowe force->state = build_dont_know;
1144*10d63b7dSRichard Lowe }
1145*10d63b7dSRichard Lowe }
1146*10d63b7dSRichard Lowe }
1147*10d63b7dSRichard Lowe if (dependencies_running) {
1148*10d63b7dSRichard Lowe if (doing_subtree) {
1149*10d63b7dSRichard Lowe if (target->conditional_cnt > 0) {
1150*10d63b7dSRichard Lowe reset_locals(target,
1151*10d63b7dSRichard Lowe old_locals,
1152*10d63b7dSRichard Lowe get_prop(target->prop,
1153*10d63b7dSRichard Lowe conditional_prop),
1154*10d63b7dSRichard Lowe 0);
1155*10d63b7dSRichard Lowe }
1156*10d63b7dSRichard Lowe return true;
1157*10d63b7dSRichard Lowe } else {
1158*10d63b7dSRichard Lowe target->state = build_running;
1159*10d63b7dSRichard Lowe add_pending(target,
1160*10d63b7dSRichard Lowe --recursion_level,
1161*10d63b7dSRichard Lowe do_get,
1162*10d63b7dSRichard Lowe implicit,
1163*10d63b7dSRichard Lowe false);
1164*10d63b7dSRichard Lowe if (target->conditional_cnt > 0) {
1165*10d63b7dSRichard Lowe reset_locals(target,
1166*10d63b7dSRichard Lowe old_locals,
1167*10d63b7dSRichard Lowe get_prop(target->prop,
1168*10d63b7dSRichard Lowe conditional_prop),
1169*10d63b7dSRichard Lowe 0);
1170*10d63b7dSRichard Lowe }
1171*10d63b7dSRichard Lowe return true;
1172*10d63b7dSRichard Lowe }
1173*10d63b7dSRichard Lowe }
1174*10d63b7dSRichard Lowe /*
1175*10d63b7dSRichard Lowe * Collect the timestamp of the youngest double colon target
1176*10d63b7dSRichard Lowe * dependency.
1177*10d63b7dSRichard Lowe */
1178*10d63b7dSRichard Lowe if (target->is_double_colon_parent) {
1179*10d63b7dSRichard Lowe for (dependency = line->body.line.dependencies;
1180*10d63b7dSRichard Lowe dependency != NULL;
1181*10d63b7dSRichard Lowe dependency = dependency->next) {
1182*10d63b7dSRichard Lowe Property tmp_line;
1183*10d63b7dSRichard Lowe
1184*10d63b7dSRichard Lowe if ((tmp_line = get_prop(dependency->name->prop, line_prop)) != NULL) {
1185*10d63b7dSRichard Lowe if(tmp_line->body.line.dependency_time != file_max_time) {
1186*10d63b7dSRichard Lowe target->stat.time =
1187*10d63b7dSRichard Lowe MAX(tmp_line->body.line.dependency_time,
1188*10d63b7dSRichard Lowe target->stat.time);
1189*10d63b7dSRichard Lowe }
1190*10d63b7dSRichard Lowe }
1191*10d63b7dSRichard Lowe }
1192*10d63b7dSRichard Lowe }
1193*10d63b7dSRichard Lowe if ((true_target->is_member) && (dependency_changed == true)) {
1194*10d63b7dSRichard Lowe true_target->stat.time = file_no_time;
1195*10d63b7dSRichard Lowe }
1196*10d63b7dSRichard Lowe /*
1197*10d63b7dSRichard Lowe * After scanning all the dependencies, we check the rule
1198*10d63b7dSRichard Lowe * if we found one.
1199*10d63b7dSRichard Lowe */
1200*10d63b7dSRichard Lowe if (line->body.line.command_template != NULL) {
1201*10d63b7dSRichard Lowe if (line->body.line.command_template_redefined) {
1202*10d63b7dSRichard Lowe warning(gettext("Too many rules defined for target %s"),
1203*10d63b7dSRichard Lowe target->string_mb);
1204*10d63b7dSRichard Lowe }
1205*10d63b7dSRichard Lowe *command = line;
1206*10d63b7dSRichard Lowe /* Check if the target is out of date */
1207*10d63b7dSRichard Lowe Boolean out_of_date;
1208*10d63b7dSRichard Lowe if (true_target->is_member) {
1209*10d63b7dSRichard Lowe out_of_date = (Boolean) OUT_OF_DATE_SEC(true_target->stat.time,
1210*10d63b7dSRichard Lowe line->body.line.dependency_time);
1211*10d63b7dSRichard Lowe } else {
1212*10d63b7dSRichard Lowe out_of_date = (Boolean) OUT_OF_DATE(true_target->stat.time,
1213*10d63b7dSRichard Lowe line->body.line.dependency_time);
1214*10d63b7dSRichard Lowe }
1215*10d63b7dSRichard Lowe if (build_unconditional || out_of_date){
1216*10d63b7dSRichard Lowe if(!recheck_conditionals) {
1217*10d63b7dSRichard Lowe line->body.line.is_out_of_date = true;
1218*10d63b7dSRichard Lowe }
1219*10d63b7dSRichard Lowe }
1220*10d63b7dSRichard Lowe line->body.line.sccs_command = false;
1221*10d63b7dSRichard Lowe line->body.line.target = true_target;
1222*10d63b7dSRichard Lowe if(gnu_style) {
1223*10d63b7dSRichard Lowe
1224*10d63b7dSRichard Lowe // set $< for explicit rule
1225*10d63b7dSRichard Lowe if(line->body.line.dependencies != NULL) {
1226*10d63b7dSRichard Lowe less = line->body.line.dependencies->name;
1227*10d63b7dSRichard Lowe }
1228*10d63b7dSRichard Lowe
1229*10d63b7dSRichard Lowe // set $* for explicit rule
1230*10d63b7dSRichard Lowe Name target_body;
1231*10d63b7dSRichard Lowe Name tt = true_target;
1232*10d63b7dSRichard Lowe Property member;
1233*10d63b7dSRichard Lowe register wchar_t *target_end;
1234*10d63b7dSRichard Lowe register Dependency suffix;
1235*10d63b7dSRichard Lowe register int suffix_length;
1236*10d63b7dSRichard Lowe Wstring targ_string;
1237*10d63b7dSRichard Lowe Wstring suf_string;
1238*10d63b7dSRichard Lowe
1239*10d63b7dSRichard Lowe if (true_target->is_member &&
1240*10d63b7dSRichard Lowe ((member = get_prop(target->prop, member_prop)) !=
1241*10d63b7dSRichard Lowe NULL)) {
1242*10d63b7dSRichard Lowe tt = member->body.member.member;
1243*10d63b7dSRichard Lowe }
1244*10d63b7dSRichard Lowe targ_string.init(tt);
1245*10d63b7dSRichard Lowe target_end = targ_string.get_string() + tt->hash.length;
1246*10d63b7dSRichard Lowe for (suffix = suffixes; suffix != NULL; suffix = suffix->next) {
1247*10d63b7dSRichard Lowe suffix_length = suffix->name->hash.length;
1248*10d63b7dSRichard Lowe suf_string.init(suffix->name);
1249*10d63b7dSRichard Lowe if (tt->hash.length < suffix_length) {
1250*10d63b7dSRichard Lowe continue;
1251*10d63b7dSRichard Lowe } else if (!IS_WEQUALN(suf_string.get_string(),
1252*10d63b7dSRichard Lowe (target_end - suffix_length),
1253*10d63b7dSRichard Lowe suffix_length)) {
1254*10d63b7dSRichard Lowe continue;
1255*10d63b7dSRichard Lowe }
1256*10d63b7dSRichard Lowe target_body = GETNAME(
1257*10d63b7dSRichard Lowe targ_string.get_string(),
1258*10d63b7dSRichard Lowe (int)(tt->hash.length - suffix_length)
1259*10d63b7dSRichard Lowe );
1260*10d63b7dSRichard Lowe line->body.line.star = target_body;
1261*10d63b7dSRichard Lowe }
1262*10d63b7dSRichard Lowe
1263*10d63b7dSRichard Lowe // set result = build_ok so that implicit rules are not used.
1264*10d63b7dSRichard Lowe if(*result == build_dont_know) {
1265*10d63b7dSRichard Lowe *result = build_ok;
1266*10d63b7dSRichard Lowe }
1267*10d63b7dSRichard Lowe }
1268*10d63b7dSRichard Lowe if (less != NULL) {
1269*10d63b7dSRichard Lowe line->body.line.less = less;
1270*10d63b7dSRichard Lowe }
1271*10d63b7dSRichard Lowe }
1272*10d63b7dSRichard Lowe
1273*10d63b7dSRichard Lowe return false;
1274*10d63b7dSRichard Lowe }
1275*10d63b7dSRichard Lowe
1276*10d63b7dSRichard Lowe /*
1277*10d63b7dSRichard Lowe * dynamic_dependencies(target)
1278*10d63b7dSRichard Lowe *
1279*10d63b7dSRichard Lowe * Checks if any dependency contains a macro ref
1280*10d63b7dSRichard Lowe * If so, it replaces the dependency with the expanded version.
1281*10d63b7dSRichard Lowe * Here, "$@" gets translated to target->string. That is
1282*10d63b7dSRichard Lowe * the current name on the left of the colon in the
1283*10d63b7dSRichard Lowe * makefile. Thus,
1284*10d63b7dSRichard Lowe * xyz: s.$@.c
1285*10d63b7dSRichard Lowe * translates into
1286*10d63b7dSRichard Lowe * xyz: s.xyz.c
1287*10d63b7dSRichard Lowe *
1288*10d63b7dSRichard Lowe * Also, "$(@F)" translates to the same thing without a preceeding
1289*10d63b7dSRichard Lowe * directory path (if one exists).
1290*10d63b7dSRichard Lowe * Note, to enter "$@" on a dependency line in a makefile
1291*10d63b7dSRichard Lowe * "$$@" must be typed. This is because make expands
1292*10d63b7dSRichard Lowe * macros in dependency lists upon reading them.
1293*10d63b7dSRichard Lowe * dynamic_dependencies() also expands file wildcards.
1294*10d63b7dSRichard Lowe * If there are any Shell meta characters in the name,
1295*10d63b7dSRichard Lowe * search the directory, and replace the dependency
1296*10d63b7dSRichard Lowe * with the set of files the pattern matches
1297*10d63b7dSRichard Lowe *
1298*10d63b7dSRichard Lowe * Parameters:
1299*10d63b7dSRichard Lowe * target Target to sanitize dependencies for
1300*10d63b7dSRichard Lowe *
1301*10d63b7dSRichard Lowe * Global variables used:
1302*10d63b7dSRichard Lowe * c_at The Name "@", used to set macro value
1303*10d63b7dSRichard Lowe * debug_level Should we trace actions?
1304*10d63b7dSRichard Lowe * dot The Name ".", used to read directory
1305*10d63b7dSRichard Lowe * recursion_level Used for tracing
1306*10d63b7dSRichard Lowe */
1307*10d63b7dSRichard Lowe void
dynamic_dependencies(Name target)1308*10d63b7dSRichard Lowe dynamic_dependencies(Name target)
1309*10d63b7dSRichard Lowe {
1310*10d63b7dSRichard Lowe wchar_t pattern[MAXPATHLEN];
1311*10d63b7dSRichard Lowe register wchar_t *p;
1312*10d63b7dSRichard Lowe Property line;
1313*10d63b7dSRichard Lowe register Dependency dependency;
1314*10d63b7dSRichard Lowe register Dependency *remove;
1315*10d63b7dSRichard Lowe String_rec string;
1316*10d63b7dSRichard Lowe wchar_t buffer[MAXPATHLEN];
1317*10d63b7dSRichard Lowe register Boolean set_at = false;
1318*10d63b7dSRichard Lowe register wchar_t *start;
1319*10d63b7dSRichard Lowe Dependency new_depe;
1320*10d63b7dSRichard Lowe register Boolean reuse_cell;
1321*10d63b7dSRichard Lowe Dependency first_member;
1322*10d63b7dSRichard Lowe Name directory;
1323*10d63b7dSRichard Lowe Name lib;
1324*10d63b7dSRichard Lowe Name member;
1325*10d63b7dSRichard Lowe Property prop;
1326*10d63b7dSRichard Lowe Name true_target = target;
1327*10d63b7dSRichard Lowe wchar_t *library;
1328*10d63b7dSRichard Lowe
1329*10d63b7dSRichard Lowe if ((line = get_prop(target->prop, line_prop)) == NULL) {
1330*10d63b7dSRichard Lowe return;
1331*10d63b7dSRichard Lowe }
1332*10d63b7dSRichard Lowe /* If the target is constructed from a "::" target we consider that */
1333*10d63b7dSRichard Lowe if (target->has_target_prop) {
1334*10d63b7dSRichard Lowe true_target = get_prop(target->prop,
1335*10d63b7dSRichard Lowe target_prop)->body.target.target;
1336*10d63b7dSRichard Lowe }
1337*10d63b7dSRichard Lowe /* Scan all dependencies and process the ones that contain "$" chars */
1338*10d63b7dSRichard Lowe for (dependency = line->body.line.dependencies;
1339*10d63b7dSRichard Lowe dependency != NULL;
1340*10d63b7dSRichard Lowe dependency = dependency->next) {
1341*10d63b7dSRichard Lowe if (!dependency->name->dollar) {
1342*10d63b7dSRichard Lowe continue;
1343*10d63b7dSRichard Lowe }
1344*10d63b7dSRichard Lowe target->has_depe_list_expanded = true;
1345*10d63b7dSRichard Lowe
1346*10d63b7dSRichard Lowe /* The make macro $@ is bound to the target name once per */
1347*10d63b7dSRichard Lowe /* invocation of dynamic_dependencies() */
1348*10d63b7dSRichard Lowe if (!set_at) {
1349*10d63b7dSRichard Lowe (void) SETVAR(c_at, true_target, false);
1350*10d63b7dSRichard Lowe set_at = true;
1351*10d63b7dSRichard Lowe }
1352*10d63b7dSRichard Lowe /* Expand this dependency string */
1353*10d63b7dSRichard Lowe INIT_STRING_FROM_STACK(string, buffer);
1354*10d63b7dSRichard Lowe expand_value(dependency->name, &string, false);
1355*10d63b7dSRichard Lowe /* Scan the expanded string. It could contain whitespace */
1356*10d63b7dSRichard Lowe /* which mean it expands to several dependencies */
1357*10d63b7dSRichard Lowe start = string.buffer.start;
1358*10d63b7dSRichard Lowe while (iswspace(*start)) {
1359*10d63b7dSRichard Lowe start++;
1360*10d63b7dSRichard Lowe }
1361*10d63b7dSRichard Lowe /* Remove the cell (later) if the macro was empty */
1362*10d63b7dSRichard Lowe if (start[0] == (int) nul_char) {
1363*10d63b7dSRichard Lowe dependency->name = NULL;
1364*10d63b7dSRichard Lowe }
1365*10d63b7dSRichard Lowe
1366*10d63b7dSRichard Lowe /* azv 10/26/95 to fix bug BID_1170218 */
1367*10d63b7dSRichard Lowe if ((start[0] == (int) period_char) &&
1368*10d63b7dSRichard Lowe (start[1] == (int) slash_char)) {
1369*10d63b7dSRichard Lowe start += 2;
1370*10d63b7dSRichard Lowe }
1371*10d63b7dSRichard Lowe /* azv */
1372*10d63b7dSRichard Lowe
1373*10d63b7dSRichard Lowe first_member = NULL;
1374*10d63b7dSRichard Lowe /* We use the original dependency cell for the first */
1375*10d63b7dSRichard Lowe /* dependency from the expansion */
1376*10d63b7dSRichard Lowe reuse_cell = true;
1377*10d63b7dSRichard Lowe /* We also have to deal with dependencies that expand to */
1378*10d63b7dSRichard Lowe /* lib.a(members) notation */
1379*10d63b7dSRichard Lowe for (p = start; *p != (int) nul_char; p++) {
1380*10d63b7dSRichard Lowe if ((*p == (int) parenleft_char)) {
1381*10d63b7dSRichard Lowe lib = GETNAME(start, p - start);
1382*10d63b7dSRichard Lowe lib->is_member = true;
1383*10d63b7dSRichard Lowe first_member = dependency;
1384*10d63b7dSRichard Lowe start = p + 1;
1385*10d63b7dSRichard Lowe while (iswspace(*start)) {
1386*10d63b7dSRichard Lowe start++;
1387*10d63b7dSRichard Lowe }
1388*10d63b7dSRichard Lowe break;
1389*10d63b7dSRichard Lowe }
1390*10d63b7dSRichard Lowe }
1391*10d63b7dSRichard Lowe do {
1392*10d63b7dSRichard Lowe /* First skip whitespace */
1393*10d63b7dSRichard Lowe for (p = start; *p != (int) nul_char; p++) {
1394*10d63b7dSRichard Lowe if ((*p == (int) nul_char) ||
1395*10d63b7dSRichard Lowe iswspace(*p) ||
1396*10d63b7dSRichard Lowe (*p == (int) parenright_char)) {
1397*10d63b7dSRichard Lowe break;
1398*10d63b7dSRichard Lowe }
1399*10d63b7dSRichard Lowe }
1400*10d63b7dSRichard Lowe /* Enter dependency from expansion */
1401*10d63b7dSRichard Lowe if (p != start) {
1402*10d63b7dSRichard Lowe /* Create new dependency cell if */
1403*10d63b7dSRichard Lowe /* this is not the first dependency */
1404*10d63b7dSRichard Lowe /* picked from the expansion */
1405*10d63b7dSRichard Lowe if (!reuse_cell) {
1406*10d63b7dSRichard Lowe new_depe = ALLOC(Dependency);
1407*10d63b7dSRichard Lowe new_depe->next = dependency->next;
1408*10d63b7dSRichard Lowe new_depe->automatic = false;
1409*10d63b7dSRichard Lowe new_depe->stale = false;
1410*10d63b7dSRichard Lowe new_depe->built = false;
1411*10d63b7dSRichard Lowe dependency->next = new_depe;
1412*10d63b7dSRichard Lowe dependency = new_depe;
1413*10d63b7dSRichard Lowe }
1414*10d63b7dSRichard Lowe reuse_cell = false;
1415*10d63b7dSRichard Lowe /* Internalize the dependency name */
1416*10d63b7dSRichard Lowe // tolik. Fix for bug 4110429: inconsistent expansion for macros that
1417*10d63b7dSRichard Lowe // include "//" and "/./"
1418*10d63b7dSRichard Lowe //dependency->name = GETNAME(start, p - start);
1419*10d63b7dSRichard Lowe dependency->name = normalize_name(start, p - start);
1420*10d63b7dSRichard Lowe if ((debug_level > 0) &&
1421*10d63b7dSRichard Lowe (first_member == NULL)) {
1422*10d63b7dSRichard Lowe (void) printf(gettext("%*sDynamic dependency `%s' for target `%s'\n"),
1423*10d63b7dSRichard Lowe recursion_level,
1424*10d63b7dSRichard Lowe "",
1425*10d63b7dSRichard Lowe dependency->name->string_mb,
1426*10d63b7dSRichard Lowe true_target->string_mb);
1427*10d63b7dSRichard Lowe }
1428*10d63b7dSRichard Lowe for (start = p; iswspace(*start); start++);
1429*10d63b7dSRichard Lowe p = start;
1430*10d63b7dSRichard Lowe }
1431*10d63b7dSRichard Lowe } while ((*p != (int) nul_char) &&
1432*10d63b7dSRichard Lowe (*p != (int) parenright_char));
1433*10d63b7dSRichard Lowe /* If the expansion was of lib.a(members) format we now */
1434*10d63b7dSRichard Lowe /* enter the proper member cells */
1435*10d63b7dSRichard Lowe if (first_member != NULL) {
1436*10d63b7dSRichard Lowe /* Scan the new dependencies and transform them from */
1437*10d63b7dSRichard Lowe /* "foo" to "lib.a(foo)" */
1438*10d63b7dSRichard Lowe for (; 1; first_member = first_member->next) {
1439*10d63b7dSRichard Lowe /* Build "lib.a(foo)" name */
1440*10d63b7dSRichard Lowe INIT_STRING_FROM_STACK(string, buffer);
1441*10d63b7dSRichard Lowe APPEND_NAME(lib,
1442*10d63b7dSRichard Lowe &string,
1443*10d63b7dSRichard Lowe (int) lib->hash.length);
1444*10d63b7dSRichard Lowe append_char((int) parenleft_char, &string);
1445*10d63b7dSRichard Lowe APPEND_NAME(first_member->name,
1446*10d63b7dSRichard Lowe &string,
1447*10d63b7dSRichard Lowe FIND_LENGTH);
1448*10d63b7dSRichard Lowe append_char((int) parenright_char, &string);
1449*10d63b7dSRichard Lowe member = first_member->name;
1450*10d63b7dSRichard Lowe /* Replace "foo" with "lib.a(foo)" */
1451*10d63b7dSRichard Lowe first_member->name =
1452*10d63b7dSRichard Lowe GETNAME(string.buffer.start, FIND_LENGTH);
1453*10d63b7dSRichard Lowe if (string.free_after_use) {
1454*10d63b7dSRichard Lowe retmem(string.buffer.start);
1455*10d63b7dSRichard Lowe }
1456*10d63b7dSRichard Lowe if (debug_level > 0) {
1457*10d63b7dSRichard Lowe (void) printf(gettext("%*sDynamic dependency `%s' for target `%s'\n"),
1458*10d63b7dSRichard Lowe recursion_level,
1459*10d63b7dSRichard Lowe "",
1460*10d63b7dSRichard Lowe first_member->name->
1461*10d63b7dSRichard Lowe string_mb,
1462*10d63b7dSRichard Lowe true_target->string_mb);
1463*10d63b7dSRichard Lowe }
1464*10d63b7dSRichard Lowe first_member->name->is_member = lib->is_member;
1465*10d63b7dSRichard Lowe /* Add member property to member */
1466*10d63b7dSRichard Lowe prop = maybe_append_prop(first_member->name,
1467*10d63b7dSRichard Lowe member_prop);
1468*10d63b7dSRichard Lowe prop->body.member.library = lib;
1469*10d63b7dSRichard Lowe prop->body.member.entry = NULL;
1470*10d63b7dSRichard Lowe prop->body.member.member = member;
1471*10d63b7dSRichard Lowe if (first_member == dependency) {
1472*10d63b7dSRichard Lowe break;
1473*10d63b7dSRichard Lowe }
1474*10d63b7dSRichard Lowe }
1475*10d63b7dSRichard Lowe }
1476*10d63b7dSRichard Lowe }
1477*10d63b7dSRichard Lowe Wstring wcb;
1478*10d63b7dSRichard Lowe /* Then scan all the dependencies again. This time we want to expand */
1479*10d63b7dSRichard Lowe /* shell file wildcards */
1480*10d63b7dSRichard Lowe for (remove = &line->body.line.dependencies, dependency = *remove;
1481*10d63b7dSRichard Lowe dependency != NULL;
1482*10d63b7dSRichard Lowe dependency = *remove) {
1483*10d63b7dSRichard Lowe if (dependency->name == NULL) {
1484*10d63b7dSRichard Lowe dependency = *remove = (*remove)->next;
1485*10d63b7dSRichard Lowe continue;
1486*10d63b7dSRichard Lowe }
1487*10d63b7dSRichard Lowe /* If dependency name string contains shell wildcards */
1488*10d63b7dSRichard Lowe /* replace the name with the expansion */
1489*10d63b7dSRichard Lowe if (dependency->name->wildcard) {
1490*10d63b7dSRichard Lowe wcb.init(dependency->name);
1491*10d63b7dSRichard Lowe if ((start = (wchar_t *) wcschr(wcb.get_string(),
1492*10d63b7dSRichard Lowe (int) parenleft_char)) != NULL) {
1493*10d63b7dSRichard Lowe /* lib(*) type pattern */
1494*10d63b7dSRichard Lowe library = buffer;
1495*10d63b7dSRichard Lowe (void) wcsncpy(buffer,
1496*10d63b7dSRichard Lowe wcb.get_string(),
1497*10d63b7dSRichard Lowe start - wcb.get_string());
1498*10d63b7dSRichard Lowe buffer[start-wcb.get_string()] =
1499*10d63b7dSRichard Lowe (int) nul_char;
1500*10d63b7dSRichard Lowe (void) wcsncpy(pattern,
1501*10d63b7dSRichard Lowe start + 1,
1502*10d63b7dSRichard Lowe (int) (dependency->name->hash.length-(start-wcb.get_string())-2));
1503*10d63b7dSRichard Lowe pattern[dependency->name->hash.length -
1504*10d63b7dSRichard Lowe (start-wcb.get_string()) - 2] =
1505*10d63b7dSRichard Lowe (int) nul_char;
1506*10d63b7dSRichard Lowe } else {
1507*10d63b7dSRichard Lowe library = NULL;
1508*10d63b7dSRichard Lowe (void) wcsncpy(pattern,
1509*10d63b7dSRichard Lowe wcb.get_string(),
1510*10d63b7dSRichard Lowe (int) dependency->name->hash.length);
1511*10d63b7dSRichard Lowe pattern[dependency->name->hash.length] =
1512*10d63b7dSRichard Lowe (int) nul_char;
1513*10d63b7dSRichard Lowe }
1514*10d63b7dSRichard Lowe start = (wchar_t *) wcsrchr(pattern, (int) slash_char);
1515*10d63b7dSRichard Lowe if (start == NULL) {
1516*10d63b7dSRichard Lowe directory = dot;
1517*10d63b7dSRichard Lowe p = pattern;
1518*10d63b7dSRichard Lowe } else {
1519*10d63b7dSRichard Lowe directory = GETNAME(pattern, start-pattern);
1520*10d63b7dSRichard Lowe p = start+1;
1521*10d63b7dSRichard Lowe }
1522*10d63b7dSRichard Lowe /* The expansion is handled by the read_dir() routine*/
1523*10d63b7dSRichard Lowe if (read_dir(directory, p, line, library)) {
1524*10d63b7dSRichard Lowe *remove = (*remove)->next;
1525*10d63b7dSRichard Lowe } else {
1526*10d63b7dSRichard Lowe remove = &dependency->next;
1527*10d63b7dSRichard Lowe }
1528*10d63b7dSRichard Lowe } else {
1529*10d63b7dSRichard Lowe remove = &dependency->next;
1530*10d63b7dSRichard Lowe }
1531*10d63b7dSRichard Lowe }
1532*10d63b7dSRichard Lowe
1533*10d63b7dSRichard Lowe /* Then unbind $@ */
1534*10d63b7dSRichard Lowe (void) SETVAR(c_at, (Name) NULL, false);
1535*10d63b7dSRichard Lowe }
1536*10d63b7dSRichard Lowe
1537*10d63b7dSRichard Lowe /*
1538*10d63b7dSRichard Lowe * DONE.
1539*10d63b7dSRichard Lowe *
1540*10d63b7dSRichard Lowe * run_command(line)
1541*10d63b7dSRichard Lowe *
1542*10d63b7dSRichard Lowe * Takes one Cmd_line and runs the commands from it.
1543*10d63b7dSRichard Lowe *
1544*10d63b7dSRichard Lowe * Return value:
1545*10d63b7dSRichard Lowe * Indicates if the command failed or not
1546*10d63b7dSRichard Lowe *
1547*10d63b7dSRichard Lowe * Parameters:
1548*10d63b7dSRichard Lowe * line The command line to run
1549*10d63b7dSRichard Lowe *
1550*10d63b7dSRichard Lowe * Global variables used:
1551*10d63b7dSRichard Lowe * commands_done Set if we do run command
1552*10d63b7dSRichard Lowe * current_line Set to the line we run a command from
1553*10d63b7dSRichard Lowe * current_target Set to the target we run a command for
1554*10d63b7dSRichard Lowe * file_number Used to form temp file name
1555*10d63b7dSRichard Lowe * keep_state Indicates that .KEEP_STATE is on
1556*10d63b7dSRichard Lowe * make_state The Name ".make.state", used to check timestamp
1557*10d63b7dSRichard Lowe * parallel True if currently building in parallel
1558*10d63b7dSRichard Lowe * parallel_process_cnt Count of parallel processes running
1559*10d63b7dSRichard Lowe * quest Indicates that make -q is on
1560*10d63b7dSRichard Lowe * rewrite_statefile Set if we do run a command
1561*10d63b7dSRichard Lowe * sunpro_dependencies The Name "SUNPRO_DEPENDENCIES", set value
1562*10d63b7dSRichard Lowe * temp_file_directory Used to form temp fie name
1563*10d63b7dSRichard Lowe * temp_file_name Set to the name of the temp file
1564*10d63b7dSRichard Lowe * touch Indicates that make -t is on
1565*10d63b7dSRichard Lowe */
1566*10d63b7dSRichard Lowe static Doname
run_command(register Property line,Boolean)1567*10d63b7dSRichard Lowe run_command(register Property line, Boolean)
1568*10d63b7dSRichard Lowe {
1569*10d63b7dSRichard Lowe register Doname result = build_ok;
1570*10d63b7dSRichard Lowe register Boolean remember_only = false;
1571*10d63b7dSRichard Lowe register Name target = line->body.line.target;
1572*10d63b7dSRichard Lowe wchar_t *string;
1573*10d63b7dSRichard Lowe char tmp_file_path[MAXPATHLEN];
1574*10d63b7dSRichard Lowe
1575*10d63b7dSRichard Lowe if (!line->body.line.is_out_of_date && target->rechecking_target) {
1576*10d63b7dSRichard Lowe target->rechecking_target = false;
1577*10d63b7dSRichard Lowe return build_ok;
1578*10d63b7dSRichard Lowe }
1579*10d63b7dSRichard Lowe
1580*10d63b7dSRichard Lowe /*
1581*10d63b7dSRichard Lowe * Build the command if we know the target is out of date,
1582*10d63b7dSRichard Lowe * or if we want to check cmd consistency.
1583*10d63b7dSRichard Lowe */
1584*10d63b7dSRichard Lowe if (line->body.line.is_out_of_date || keep_state) {
1585*10d63b7dSRichard Lowe /* Hack for handling conditional macros in DMake. */
1586*10d63b7dSRichard Lowe if (!line->body.line.dont_rebuild_command_used) {
1587*10d63b7dSRichard Lowe build_command_strings(target, line);
1588*10d63b7dSRichard Lowe }
1589*10d63b7dSRichard Lowe }
1590*10d63b7dSRichard Lowe /* Never mind */
1591*10d63b7dSRichard Lowe if (!line->body.line.is_out_of_date) {
1592*10d63b7dSRichard Lowe return build_ok;
1593*10d63b7dSRichard Lowe }
1594*10d63b7dSRichard Lowe /* If quest, then exit(1) because the target is out of date */
1595*10d63b7dSRichard Lowe if (quest) {
1596*10d63b7dSRichard Lowe if (posix) {
1597*10d63b7dSRichard Lowe result = execute_parallel(line, true);
1598*10d63b7dSRichard Lowe }
1599*10d63b7dSRichard Lowe exit_status = 1;
1600*10d63b7dSRichard Lowe exit(1);
1601*10d63b7dSRichard Lowe }
1602*10d63b7dSRichard Lowe /* We actually had to do something this time */
1603*10d63b7dSRichard Lowe rewrite_statefile = commands_done = true;
1604*10d63b7dSRichard Lowe /*
1605*10d63b7dSRichard Lowe * If this is an sccs command, we have to do some extra checking
1606*10d63b7dSRichard Lowe * and possibly complain. If the file can't be gotten because it's
1607*10d63b7dSRichard Lowe * checked out, we complain and behave as if the command was
1608*10d63b7dSRichard Lowe * executed eventhough we ignored the command.
1609*10d63b7dSRichard Lowe */
1610*10d63b7dSRichard Lowe if (!touch &&
1611*10d63b7dSRichard Lowe line->body.line.sccs_command &&
1612*10d63b7dSRichard Lowe (target->stat.time != file_doesnt_exist) &&
1613*10d63b7dSRichard Lowe ((target->stat.mode & 0222) != 0)) {
1614*10d63b7dSRichard Lowe fatal(gettext("%s is writable so it cannot be sccs gotten"),
1615*10d63b7dSRichard Lowe target->string_mb);
1616*10d63b7dSRichard Lowe target->has_complained = remember_only = true;
1617*10d63b7dSRichard Lowe }
1618*10d63b7dSRichard Lowe /*
1619*10d63b7dSRichard Lowe * If KEEP_STATE is on, we make sure we have the timestamp for
1620*10d63b7dSRichard Lowe * .make.state. If .make.state changes during the command run,
1621*10d63b7dSRichard Lowe * we reread .make.state after the command. We also setup the
1622*10d63b7dSRichard Lowe * environment variable that asks utilities to report dependencies.
1623*10d63b7dSRichard Lowe */
1624*10d63b7dSRichard Lowe if (!touch &&
1625*10d63b7dSRichard Lowe keep_state &&
1626*10d63b7dSRichard Lowe !remember_only) {
1627*10d63b7dSRichard Lowe (void) exists(make_state);
1628*10d63b7dSRichard Lowe if((strlen(temp_file_directory) == 1) &&
1629*10d63b7dSRichard Lowe (temp_file_directory[0] == '/')) {
1630*10d63b7dSRichard Lowe tmp_file_path[0] = '\0';
1631*10d63b7dSRichard Lowe } else {
1632*10d63b7dSRichard Lowe strcpy(tmp_file_path, temp_file_directory);
1633*10d63b7dSRichard Lowe }
1634*10d63b7dSRichard Lowe sprintf(mbs_buffer,
1635*10d63b7dSRichard Lowe "%s/.make.dependency.%08x.%d.%d",
1636*10d63b7dSRichard Lowe tmp_file_path,
1637*10d63b7dSRichard Lowe hostid,
1638*10d63b7dSRichard Lowe getpid(),
1639*10d63b7dSRichard Lowe file_number++);
1640*10d63b7dSRichard Lowe MBSTOWCS(wcs_buffer, mbs_buffer);
1641*10d63b7dSRichard Lowe Boolean fnd;
1642*10d63b7dSRichard Lowe temp_file_name = getname_fn(wcs_buffer, FIND_LENGTH, false, &fnd);
1643*10d63b7dSRichard Lowe temp_file_name->stat.is_file = true;
1644*10d63b7dSRichard Lowe int len = 2*MAXPATHLEN + strlen(target->string_mb) + 2;
1645*10d63b7dSRichard Lowe wchar_t *to = string = ALLOC_WC(len);
1646*10d63b7dSRichard Lowe for (wchar_t *from = wcs_buffer; *from != (int) nul_char; ) {
1647*10d63b7dSRichard Lowe if (*from == (int) space_char) {
1648*10d63b7dSRichard Lowe *to++ = (int) backslash_char;
1649*10d63b7dSRichard Lowe }
1650*10d63b7dSRichard Lowe *to++ = *from++;
1651*10d63b7dSRichard Lowe }
1652*10d63b7dSRichard Lowe *to++ = (int) space_char;
1653*10d63b7dSRichard Lowe MBSTOWCS(to, target->string_mb);
1654*10d63b7dSRichard Lowe Name sprodep_name = getname_fn(string, FIND_LENGTH, false, &fnd);
1655*10d63b7dSRichard Lowe (void) SETVAR(sunpro_dependencies,
1656*10d63b7dSRichard Lowe sprodep_name,
1657*10d63b7dSRichard Lowe false);
1658*10d63b7dSRichard Lowe retmem(string);
1659*10d63b7dSRichard Lowe } else {
1660*10d63b7dSRichard Lowe temp_file_name = NULL;
1661*10d63b7dSRichard Lowe }
1662*10d63b7dSRichard Lowe
1663*10d63b7dSRichard Lowe /*
1664*10d63b7dSRichard Lowe * In case we are interrupted, we need to know what was going on.
1665*10d63b7dSRichard Lowe */
1666*10d63b7dSRichard Lowe current_target = target;
1667*10d63b7dSRichard Lowe /*
1668*10d63b7dSRichard Lowe * We also need to be able to save an empty command instead of the
1669*10d63b7dSRichard Lowe * interrupted one in .make.state.
1670*10d63b7dSRichard Lowe */
1671*10d63b7dSRichard Lowe current_line = line;
1672*10d63b7dSRichard Lowe if (remember_only) {
1673*10d63b7dSRichard Lowe /* Empty block!!! */
1674*10d63b7dSRichard Lowe } else if (touch) {
1675*10d63b7dSRichard Lowe result = touch_command(line, target, result);
1676*10d63b7dSRichard Lowe if (posix) {
1677*10d63b7dSRichard Lowe result = execute_parallel(line, true);
1678*10d63b7dSRichard Lowe }
1679*10d63b7dSRichard Lowe } else {
1680*10d63b7dSRichard Lowe /*
1681*10d63b7dSRichard Lowe * If this is not a touch run, we need to execute the
1682*10d63b7dSRichard Lowe * proper command(s) for the target.
1683*10d63b7dSRichard Lowe */
1684*10d63b7dSRichard Lowe if (parallel) {
1685*10d63b7dSRichard Lowe if (!parallel_ok(target, true)) {
1686*10d63b7dSRichard Lowe /*
1687*10d63b7dSRichard Lowe * We are building in parallel, but
1688*10d63b7dSRichard Lowe * this target must be built in serial.
1689*10d63b7dSRichard Lowe */
1690*10d63b7dSRichard Lowe /*
1691*10d63b7dSRichard Lowe * If nothing else is building,
1692*10d63b7dSRichard Lowe * do this one, else wait.
1693*10d63b7dSRichard Lowe */
1694*10d63b7dSRichard Lowe if (parallel_process_cnt == 0) {
1695*10d63b7dSRichard Lowe result = execute_parallel(line, true, target->localhost);
1696*10d63b7dSRichard Lowe } else {
1697*10d63b7dSRichard Lowe current_target = NULL;
1698*10d63b7dSRichard Lowe current_line = NULL;
1699*10d63b7dSRichard Lowe /*
1700*10d63b7dSRichard Lowe line->body.line.command_used = NULL;
1701*10d63b7dSRichard Lowe */
1702*10d63b7dSRichard Lowe line->body.line.dont_rebuild_command_used = true;
1703*10d63b7dSRichard Lowe return build_serial;
1704*10d63b7dSRichard Lowe }
1705*10d63b7dSRichard Lowe } else {
1706*10d63b7dSRichard Lowe result = execute_parallel(line, false);
1707*10d63b7dSRichard Lowe switch (result) {
1708*10d63b7dSRichard Lowe case build_running:
1709*10d63b7dSRichard Lowe return build_running;
1710*10d63b7dSRichard Lowe case build_serial:
1711*10d63b7dSRichard Lowe if (parallel_process_cnt == 0) {
1712*10d63b7dSRichard Lowe result = execute_parallel(line, true, target->localhost);
1713*10d63b7dSRichard Lowe } else {
1714*10d63b7dSRichard Lowe current_target = NULL;
1715*10d63b7dSRichard Lowe current_line = NULL;
1716*10d63b7dSRichard Lowe target->parallel = false;
1717*10d63b7dSRichard Lowe line->body.line.command_used =
1718*10d63b7dSRichard Lowe NULL;
1719*10d63b7dSRichard Lowe return build_serial;
1720*10d63b7dSRichard Lowe }
1721*10d63b7dSRichard Lowe }
1722*10d63b7dSRichard Lowe }
1723*10d63b7dSRichard Lowe } else {
1724*10d63b7dSRichard Lowe result = execute_parallel(line, true, target->localhost);
1725*10d63b7dSRichard Lowe }
1726*10d63b7dSRichard Lowe }
1727*10d63b7dSRichard Lowe temp_file_name = NULL;
1728*10d63b7dSRichard Lowe if (report_dependencies_level == 0){
1729*10d63b7dSRichard Lowe update_target(line, result);
1730*10d63b7dSRichard Lowe }
1731*10d63b7dSRichard Lowe current_target = NULL;
1732*10d63b7dSRichard Lowe current_line = NULL;
1733*10d63b7dSRichard Lowe return result;
1734*10d63b7dSRichard Lowe }
1735*10d63b7dSRichard Lowe
1736*10d63b7dSRichard Lowe /*
1737*10d63b7dSRichard Lowe * execute_serial(line)
1738*10d63b7dSRichard Lowe *
1739*10d63b7dSRichard Lowe * Runs thru the command line for the target and
1740*10d63b7dSRichard Lowe * executes the rules one by one.
1741*10d63b7dSRichard Lowe *
1742*10d63b7dSRichard Lowe * Return value:
1743*10d63b7dSRichard Lowe * The result of the command build
1744*10d63b7dSRichard Lowe *
1745*10d63b7dSRichard Lowe * Parameters:
1746*10d63b7dSRichard Lowe * line The command to execute
1747*10d63b7dSRichard Lowe *
1748*10d63b7dSRichard Lowe * Static variables used:
1749*10d63b7dSRichard Lowe *
1750*10d63b7dSRichard Lowe * Global variables used:
1751*10d63b7dSRichard Lowe * continue_after_error -k flag
1752*10d63b7dSRichard Lowe * do_not_exec_rule -n flag
1753*10d63b7dSRichard Lowe * report_dependencies -P flag
1754*10d63b7dSRichard Lowe * silent Don't echo commands before executing
1755*10d63b7dSRichard Lowe * temp_file_name Temp file for auto dependencies
1756*10d63b7dSRichard Lowe * vpath_defined If true, translate path for command
1757*10d63b7dSRichard Lowe */
1758*10d63b7dSRichard Lowe Doname
execute_serial(Property line)1759*10d63b7dSRichard Lowe execute_serial(Property line)
1760*10d63b7dSRichard Lowe {
1761*10d63b7dSRichard Lowe int child_pid = 0;
1762*10d63b7dSRichard Lowe Boolean printed_serial;
1763*10d63b7dSRichard Lowe Doname result = build_ok;
1764*10d63b7dSRichard Lowe Cmd_line rule, cmd_tail, command = NULL;
1765*10d63b7dSRichard Lowe char mbstring[MAXPATHLEN];
1766*10d63b7dSRichard Lowe int filed;
1767*10d63b7dSRichard Lowe Name target = line->body.line.target;
1768*10d63b7dSRichard Lowe
1769*10d63b7dSRichard Lowe target->has_recursive_dependency = false;
1770*10d63b7dSRichard Lowe // We have to create a copy of the rules chain for processing because
1771*10d63b7dSRichard Lowe // the original one can be destroyed during .make.state file rereading.
1772*10d63b7dSRichard Lowe for (rule = line->body.line.command_used;
1773*10d63b7dSRichard Lowe rule != NULL;
1774*10d63b7dSRichard Lowe rule = rule->next) {
1775*10d63b7dSRichard Lowe if (command == NULL) {
1776*10d63b7dSRichard Lowe command = cmd_tail = ALLOC(Cmd_line);
1777*10d63b7dSRichard Lowe } else {
1778*10d63b7dSRichard Lowe cmd_tail->next = ALLOC(Cmd_line);
1779*10d63b7dSRichard Lowe cmd_tail = cmd_tail->next;
1780*10d63b7dSRichard Lowe }
1781*10d63b7dSRichard Lowe *cmd_tail = *rule;
1782*10d63b7dSRichard Lowe }
1783*10d63b7dSRichard Lowe if (command) {
1784*10d63b7dSRichard Lowe cmd_tail->next = NULL;
1785*10d63b7dSRichard Lowe }
1786*10d63b7dSRichard Lowe for (rule = command; rule != NULL; rule = rule->next) {
1787*10d63b7dSRichard Lowe if (posix && (touch || quest) && !rule->always_exec) {
1788*10d63b7dSRichard Lowe continue;
1789*10d63b7dSRichard Lowe }
1790*10d63b7dSRichard Lowe if (vpath_defined) {
1791*10d63b7dSRichard Lowe rule->command_line =
1792*10d63b7dSRichard Lowe vpath_translation(rule->command_line);
1793*10d63b7dSRichard Lowe }
1794*10d63b7dSRichard Lowe /* Echo command line, maybe. */
1795*10d63b7dSRichard Lowe if ((rule->command_line->hash.length > 0) &&
1796*10d63b7dSRichard Lowe !silent &&
1797*10d63b7dSRichard Lowe (!rule->silent || do_not_exec_rule) &&
1798*10d63b7dSRichard Lowe (report_dependencies_level == 0)) {
1799*10d63b7dSRichard Lowe (void) printf("%s\n", rule->command_line->string_mb);
1800*10d63b7dSRichard Lowe }
1801*10d63b7dSRichard Lowe if (rule->command_line->hash.length > 0) {
1802*10d63b7dSRichard Lowe /* Do assignment if command line prefixed with "=" */
1803*10d63b7dSRichard Lowe if (rule->assign) {
1804*10d63b7dSRichard Lowe result = build_ok;
1805*10d63b7dSRichard Lowe do_assign(rule->command_line, target);
1806*10d63b7dSRichard Lowe } else if (report_dependencies_level == 0) {
1807*10d63b7dSRichard Lowe /* Execute command line. */
1808*10d63b7dSRichard Lowe setvar_envvar();
1809*10d63b7dSRichard Lowe result = dosys(rule->command_line,
1810*10d63b7dSRichard Lowe (Boolean) rule->ignore_error,
1811*10d63b7dSRichard Lowe (Boolean) rule->make_refd,
1812*10d63b7dSRichard Lowe /* ds 98.04.23 bug #4085164. make should always show error messages */
1813*10d63b7dSRichard Lowe false,
1814*10d63b7dSRichard Lowe /* BOOLEAN(rule->silent &&
1815*10d63b7dSRichard Lowe rule->ignore_error), */
1816*10d63b7dSRichard Lowe (Boolean) rule->always_exec,
1817*10d63b7dSRichard Lowe target);
1818*10d63b7dSRichard Lowe check_state(temp_file_name);
1819*10d63b7dSRichard Lowe }
1820*10d63b7dSRichard Lowe } else {
1821*10d63b7dSRichard Lowe result = build_ok;
1822*10d63b7dSRichard Lowe }
1823*10d63b7dSRichard Lowe if (result == build_failed) {
1824*10d63b7dSRichard Lowe if (silent || rule->silent) {
1825*10d63b7dSRichard Lowe (void) printf(gettext("The following command caused the error:\n%s\n"),
1826*10d63b7dSRichard Lowe rule->command_line->string_mb);
1827*10d63b7dSRichard Lowe }
1828*10d63b7dSRichard Lowe if (!rule->ignore_error && !ignore_errors) {
1829*10d63b7dSRichard Lowe if (!continue_after_error) {
1830*10d63b7dSRichard Lowe fatal(gettext("Command failed for target `%s'"),
1831*10d63b7dSRichard Lowe target->string_mb);
1832*10d63b7dSRichard Lowe }
1833*10d63b7dSRichard Lowe /*
1834*10d63b7dSRichard Lowe * Make sure a failing command is not
1835*10d63b7dSRichard Lowe * saved in .make.state.
1836*10d63b7dSRichard Lowe */
1837*10d63b7dSRichard Lowe line->body.line.command_used = NULL;
1838*10d63b7dSRichard Lowe break;
1839*10d63b7dSRichard Lowe } else {
1840*10d63b7dSRichard Lowe result = build_ok;
1841*10d63b7dSRichard Lowe }
1842*10d63b7dSRichard Lowe }
1843*10d63b7dSRichard Lowe }
1844*10d63b7dSRichard Lowe for (rule = command; rule != NULL; rule = cmd_tail) {
1845*10d63b7dSRichard Lowe cmd_tail = rule->next;
1846*10d63b7dSRichard Lowe free(rule);
1847*10d63b7dSRichard Lowe }
1848*10d63b7dSRichard Lowe command = NULL;
1849*10d63b7dSRichard Lowe if (temp_file_name != NULL) {
1850*10d63b7dSRichard Lowe free_name(temp_file_name);
1851*10d63b7dSRichard Lowe }
1852*10d63b7dSRichard Lowe temp_file_name = NULL;
1853*10d63b7dSRichard Lowe
1854*10d63b7dSRichard Lowe Property spro = get_prop(sunpro_dependencies->prop, macro_prop);
1855*10d63b7dSRichard Lowe if(spro != NULL) {
1856*10d63b7dSRichard Lowe Name val = spro->body.macro.value;
1857*10d63b7dSRichard Lowe if(val != NULL) {
1858*10d63b7dSRichard Lowe free_name(val);
1859*10d63b7dSRichard Lowe spro->body.macro.value = NULL;
1860*10d63b7dSRichard Lowe }
1861*10d63b7dSRichard Lowe }
1862*10d63b7dSRichard Lowe spro = get_prop(sunpro_dependencies->prop, env_mem_prop);
1863*10d63b7dSRichard Lowe if(spro) {
1864*10d63b7dSRichard Lowe char *val = spro->body.env_mem.value;
1865*10d63b7dSRichard Lowe if(val != NULL) {
1866*10d63b7dSRichard Lowe /*
1867*10d63b7dSRichard Lowe * Do not return memory allocated for SUNPRO_DEPENDENCIES
1868*10d63b7dSRichard Lowe * It will be returned in setvar_daemon() in macro.cc
1869*10d63b7dSRichard Lowe */
1870*10d63b7dSRichard Lowe // retmem_mb(val);
1871*10d63b7dSRichard Lowe spro->body.env_mem.value = NULL;
1872*10d63b7dSRichard Lowe }
1873*10d63b7dSRichard Lowe }
1874*10d63b7dSRichard Lowe
1875*10d63b7dSRichard Lowe return result;
1876*10d63b7dSRichard Lowe }
1877*10d63b7dSRichard Lowe
1878*10d63b7dSRichard Lowe
1879*10d63b7dSRichard Lowe
1880*10d63b7dSRichard Lowe /*
1881*10d63b7dSRichard Lowe * vpath_translation(cmd)
1882*10d63b7dSRichard Lowe *
1883*10d63b7dSRichard Lowe * Translates one command line by
1884*10d63b7dSRichard Lowe * checking each word. If the word has an alias it is translated.
1885*10d63b7dSRichard Lowe *
1886*10d63b7dSRichard Lowe * Return value:
1887*10d63b7dSRichard Lowe * The translated command
1888*10d63b7dSRichard Lowe *
1889*10d63b7dSRichard Lowe * Parameters:
1890*10d63b7dSRichard Lowe * cmd Command to translate
1891*10d63b7dSRichard Lowe *
1892*10d63b7dSRichard Lowe * Global variables used:
1893*10d63b7dSRichard Lowe */
1894*10d63b7dSRichard Lowe Name
vpath_translation(register Name cmd)1895*10d63b7dSRichard Lowe vpath_translation(register Name cmd)
1896*10d63b7dSRichard Lowe {
1897*10d63b7dSRichard Lowe wchar_t buffer[STRING_BUFFER_LENGTH];
1898*10d63b7dSRichard Lowe String_rec new_cmd;
1899*10d63b7dSRichard Lowe wchar_t *p;
1900*10d63b7dSRichard Lowe wchar_t *start;
1901*10d63b7dSRichard Lowe
1902*10d63b7dSRichard Lowe if (!vpath_defined || (cmd == NULL) || (cmd->hash.length == 0)) {
1903*10d63b7dSRichard Lowe return cmd;
1904*10d63b7dSRichard Lowe }
1905*10d63b7dSRichard Lowe INIT_STRING_FROM_STACK(new_cmd, buffer);
1906*10d63b7dSRichard Lowe
1907*10d63b7dSRichard Lowe Wstring wcb(cmd);
1908*10d63b7dSRichard Lowe p = wcb.get_string();
1909*10d63b7dSRichard Lowe
1910*10d63b7dSRichard Lowe while (*p != (int) nul_char) {
1911*10d63b7dSRichard Lowe while (iswspace(*p) && (*p != (int) nul_char)) {
1912*10d63b7dSRichard Lowe append_char(*p++, &new_cmd);
1913*10d63b7dSRichard Lowe }
1914*10d63b7dSRichard Lowe start = p;
1915*10d63b7dSRichard Lowe while (!iswspace(*p) && (*p != (int) nul_char)) {
1916*10d63b7dSRichard Lowe p++;
1917*10d63b7dSRichard Lowe }
1918*10d63b7dSRichard Lowe cmd = GETNAME(start, p - start);
1919*10d63b7dSRichard Lowe if (cmd->has_vpath_alias_prop) {
1920*10d63b7dSRichard Lowe cmd = get_prop(cmd->prop, vpath_alias_prop)->
1921*10d63b7dSRichard Lowe body.vpath_alias.alias;
1922*10d63b7dSRichard Lowe APPEND_NAME(cmd,
1923*10d63b7dSRichard Lowe &new_cmd,
1924*10d63b7dSRichard Lowe (int) cmd->hash.length);
1925*10d63b7dSRichard Lowe } else {
1926*10d63b7dSRichard Lowe append_string(start, &new_cmd, p - start);
1927*10d63b7dSRichard Lowe }
1928*10d63b7dSRichard Lowe }
1929*10d63b7dSRichard Lowe cmd = GETNAME(new_cmd.buffer.start, FIND_LENGTH);
1930*10d63b7dSRichard Lowe if (new_cmd.free_after_use) {
1931*10d63b7dSRichard Lowe retmem(new_cmd.buffer.start);
1932*10d63b7dSRichard Lowe }
1933*10d63b7dSRichard Lowe return cmd;
1934*10d63b7dSRichard Lowe }
1935*10d63b7dSRichard Lowe
1936*10d63b7dSRichard Lowe /*
1937*10d63b7dSRichard Lowe * check_state(temp_file_name)
1938*10d63b7dSRichard Lowe *
1939*10d63b7dSRichard Lowe * Reads and checks the state changed by the previously executed command.
1940*10d63b7dSRichard Lowe *
1941*10d63b7dSRichard Lowe * Parameters:
1942*10d63b7dSRichard Lowe * temp_file_name The auto dependency temp file
1943*10d63b7dSRichard Lowe *
1944*10d63b7dSRichard Lowe * Global variables used:
1945*10d63b7dSRichard Lowe */
1946*10d63b7dSRichard Lowe void
check_state(Name temp_file_name)1947*10d63b7dSRichard Lowe check_state(Name temp_file_name)
1948*10d63b7dSRichard Lowe {
1949*10d63b7dSRichard Lowe if (!keep_state) {
1950*10d63b7dSRichard Lowe return;
1951*10d63b7dSRichard Lowe }
1952*10d63b7dSRichard Lowe
1953*10d63b7dSRichard Lowe /*
1954*10d63b7dSRichard Lowe * Then read the temp file that now might
1955*10d63b7dSRichard Lowe * contain dependency reports from utilities
1956*10d63b7dSRichard Lowe */
1957*10d63b7dSRichard Lowe read_dependency_file(temp_file_name);
1958*10d63b7dSRichard Lowe
1959*10d63b7dSRichard Lowe /*
1960*10d63b7dSRichard Lowe * And reread .make.state if it
1961*10d63b7dSRichard Lowe * changed (the command ran recursive makes)
1962*10d63b7dSRichard Lowe */
1963*10d63b7dSRichard Lowe check_read_state_file();
1964*10d63b7dSRichard Lowe if (temp_file_name != NULL) {
1965*10d63b7dSRichard Lowe (void) unlink(temp_file_name->string_mb);
1966*10d63b7dSRichard Lowe }
1967*10d63b7dSRichard Lowe }
1968*10d63b7dSRichard Lowe
1969*10d63b7dSRichard Lowe /*
1970*10d63b7dSRichard Lowe * read_dependency_file(filename)
1971*10d63b7dSRichard Lowe *
1972*10d63b7dSRichard Lowe * Read the temp file used for reporting dependencies to make
1973*10d63b7dSRichard Lowe *
1974*10d63b7dSRichard Lowe * Parameters:
1975*10d63b7dSRichard Lowe * filename The name of the file with the state info
1976*10d63b7dSRichard Lowe *
1977*10d63b7dSRichard Lowe * Global variables used:
1978*10d63b7dSRichard Lowe * makefile_type The type of makefile being read
1979*10d63b7dSRichard Lowe * read_trace_level Debug flag
1980*10d63b7dSRichard Lowe * temp_file_number The always increasing number for unique files
1981*10d63b7dSRichard Lowe * trace_reader Debug flag
1982*10d63b7dSRichard Lowe */
1983*10d63b7dSRichard Lowe static void
read_dependency_file(register Name filename)1984*10d63b7dSRichard Lowe read_dependency_file(register Name filename)
1985*10d63b7dSRichard Lowe {
1986*10d63b7dSRichard Lowe register Makefile_type save_makefile_type;
1987*10d63b7dSRichard Lowe
1988*10d63b7dSRichard Lowe if (filename == NULL) {
1989*10d63b7dSRichard Lowe return;
1990*10d63b7dSRichard Lowe }
1991*10d63b7dSRichard Lowe filename->stat.time = file_no_time;
1992*10d63b7dSRichard Lowe if (exists(filename) > file_doesnt_exist) {
1993*10d63b7dSRichard Lowe save_makefile_type = makefile_type;
1994*10d63b7dSRichard Lowe makefile_type = reading_cpp_file;
1995*10d63b7dSRichard Lowe if (read_trace_level > 1) {
1996*10d63b7dSRichard Lowe trace_reader = true;
1997*10d63b7dSRichard Lowe }
1998*10d63b7dSRichard Lowe temp_file_number++;
1999*10d63b7dSRichard Lowe (void) read_simple_file(filename,
2000*10d63b7dSRichard Lowe false,
2001*10d63b7dSRichard Lowe false,
2002*10d63b7dSRichard Lowe false,
2003*10d63b7dSRichard Lowe false,
2004*10d63b7dSRichard Lowe false,
2005*10d63b7dSRichard Lowe false);
2006*10d63b7dSRichard Lowe trace_reader = false;
2007*10d63b7dSRichard Lowe makefile_type = save_makefile_type;
2008*10d63b7dSRichard Lowe }
2009*10d63b7dSRichard Lowe }
2010*10d63b7dSRichard Lowe
2011*10d63b7dSRichard Lowe /*
2012*10d63b7dSRichard Lowe * check_read_state_file()
2013*10d63b7dSRichard Lowe *
2014*10d63b7dSRichard Lowe * Check if .make.state has changed
2015*10d63b7dSRichard Lowe * If it has we reread it
2016*10d63b7dSRichard Lowe *
2017*10d63b7dSRichard Lowe * Parameters:
2018*10d63b7dSRichard Lowe *
2019*10d63b7dSRichard Lowe * Global variables used:
2020*10d63b7dSRichard Lowe * make_state Make state file name
2021*10d63b7dSRichard Lowe * makefile_type Type of makefile being read
2022*10d63b7dSRichard Lowe * read_trace_level Debug flag
2023*10d63b7dSRichard Lowe * trace_reader Debug flag
2024*10d63b7dSRichard Lowe */
2025*10d63b7dSRichard Lowe static void
check_read_state_file(void)2026*10d63b7dSRichard Lowe check_read_state_file(void)
2027*10d63b7dSRichard Lowe {
2028*10d63b7dSRichard Lowe timestruc_t previous = make_state->stat.time;
2029*10d63b7dSRichard Lowe register Makefile_type save_makefile_type;
2030*10d63b7dSRichard Lowe register Property makefile;
2031*10d63b7dSRichard Lowe
2032*10d63b7dSRichard Lowe make_state->stat.time = file_no_time;
2033*10d63b7dSRichard Lowe if ((exists(make_state) == file_doesnt_exist) ||
2034*10d63b7dSRichard Lowe (make_state->stat.time == previous)) {
2035*10d63b7dSRichard Lowe return;
2036*10d63b7dSRichard Lowe }
2037*10d63b7dSRichard Lowe save_makefile_type = makefile_type;
2038*10d63b7dSRichard Lowe makefile_type = rereading_statefile;
2039*10d63b7dSRichard Lowe /* Make sure we clear the old cached contents of .make.state */
2040*10d63b7dSRichard Lowe makefile = maybe_append_prop(make_state, makefile_prop);
2041*10d63b7dSRichard Lowe if (makefile->body.makefile.contents != NULL) {
2042*10d63b7dSRichard Lowe retmem(makefile->body.makefile.contents);
2043*10d63b7dSRichard Lowe makefile->body.makefile.contents = NULL;
2044*10d63b7dSRichard Lowe }
2045*10d63b7dSRichard Lowe if (read_trace_level > 1) {
2046*10d63b7dSRichard Lowe trace_reader = true;
2047*10d63b7dSRichard Lowe }
2048*10d63b7dSRichard Lowe temp_file_number++;
2049*10d63b7dSRichard Lowe (void) read_simple_file(make_state,
2050*10d63b7dSRichard Lowe false,
2051*10d63b7dSRichard Lowe false,
2052*10d63b7dSRichard Lowe false,
2053*10d63b7dSRichard Lowe false,
2054*10d63b7dSRichard Lowe false,
2055*10d63b7dSRichard Lowe true);
2056*10d63b7dSRichard Lowe trace_reader = false;
2057*10d63b7dSRichard Lowe makefile_type = save_makefile_type;
2058*10d63b7dSRichard Lowe }
2059*10d63b7dSRichard Lowe
2060*10d63b7dSRichard Lowe /*
2061*10d63b7dSRichard Lowe * do_assign(line, target)
2062*10d63b7dSRichard Lowe *
2063*10d63b7dSRichard Lowe * Handles runtime assignments for command lines prefixed with "=".
2064*10d63b7dSRichard Lowe *
2065*10d63b7dSRichard Lowe * Parameters:
2066*10d63b7dSRichard Lowe * line The command that contains an assignment
2067*10d63b7dSRichard Lowe * target The Name of the target, used for error reports
2068*10d63b7dSRichard Lowe *
2069*10d63b7dSRichard Lowe * Global variables used:
2070*10d63b7dSRichard Lowe * assign_done Set to indicate doname needs to reprocess
2071*10d63b7dSRichard Lowe */
2072*10d63b7dSRichard Lowe static void
do_assign(register Name line,register Name target)2073*10d63b7dSRichard Lowe do_assign(register Name line, register Name target)
2074*10d63b7dSRichard Lowe {
2075*10d63b7dSRichard Lowe Wstring wcb(line);
2076*10d63b7dSRichard Lowe register wchar_t *string = wcb.get_string();
2077*10d63b7dSRichard Lowe register wchar_t *equal;
2078*10d63b7dSRichard Lowe register Name name;
2079*10d63b7dSRichard Lowe register Boolean append = false;
2080*10d63b7dSRichard Lowe
2081*10d63b7dSRichard Lowe /*
2082*10d63b7dSRichard Lowe * If any runtime assignments are done, doname() must reprocess all
2083*10d63b7dSRichard Lowe * targets in the future since the macro values used to build the
2084*10d63b7dSRichard Lowe * command lines for the targets might have changed.
2085*10d63b7dSRichard Lowe */
2086*10d63b7dSRichard Lowe assign_done = true;
2087*10d63b7dSRichard Lowe /* Skip white space. */
2088*10d63b7dSRichard Lowe while (iswspace(*string)) {
2089*10d63b7dSRichard Lowe string++;
2090*10d63b7dSRichard Lowe }
2091*10d63b7dSRichard Lowe equal = string;
2092*10d63b7dSRichard Lowe /* Find "+=" or "=". */
2093*10d63b7dSRichard Lowe while (!iswspace(*equal) &&
2094*10d63b7dSRichard Lowe (*equal != (int) plus_char) &&
2095*10d63b7dSRichard Lowe (*equal != (int) equal_char)) {
2096*10d63b7dSRichard Lowe equal++;
2097*10d63b7dSRichard Lowe }
2098*10d63b7dSRichard Lowe /* Internalize macro name. */
2099*10d63b7dSRichard Lowe name = GETNAME(string, equal - string);
2100*10d63b7dSRichard Lowe /* Skip over "+=" "=". */
2101*10d63b7dSRichard Lowe while (!((*equal == (int) nul_char) ||
2102*10d63b7dSRichard Lowe (*equal == (int) equal_char) ||
2103*10d63b7dSRichard Lowe (*equal == (int) plus_char))) {
2104*10d63b7dSRichard Lowe equal++;
2105*10d63b7dSRichard Lowe }
2106*10d63b7dSRichard Lowe switch (*equal) {
2107*10d63b7dSRichard Lowe case nul_char:
2108*10d63b7dSRichard Lowe fatal(gettext("= expected in rule `%s' for target `%s'"),
2109*10d63b7dSRichard Lowe line->string_mb,
2110*10d63b7dSRichard Lowe target->string_mb);
2111*10d63b7dSRichard Lowe case plus_char:
2112*10d63b7dSRichard Lowe append = true;
2113*10d63b7dSRichard Lowe equal++;
2114*10d63b7dSRichard Lowe break;
2115*10d63b7dSRichard Lowe }
2116*10d63b7dSRichard Lowe equal++;
2117*10d63b7dSRichard Lowe /* Skip over whitespace in front of value. */
2118*10d63b7dSRichard Lowe while (iswspace(*equal)) {
2119*10d63b7dSRichard Lowe equal++;
2120*10d63b7dSRichard Lowe }
2121*10d63b7dSRichard Lowe /* Enter new macro value. */
2122*10d63b7dSRichard Lowe enter_equal(name,
2123*10d63b7dSRichard Lowe GETNAME(equal, wcb.get_string() + line->hash.length - equal),
2124*10d63b7dSRichard Lowe append);
2125*10d63b7dSRichard Lowe }
2126*10d63b7dSRichard Lowe
2127*10d63b7dSRichard Lowe /*
2128*10d63b7dSRichard Lowe * build_command_strings(target, line)
2129*10d63b7dSRichard Lowe *
2130*10d63b7dSRichard Lowe * Builds the command string to used when
2131*10d63b7dSRichard Lowe * building a target. If the string is different from the previous one
2132*10d63b7dSRichard Lowe * is_out_of_date is set.
2133*10d63b7dSRichard Lowe *
2134*10d63b7dSRichard Lowe * Parameters:
2135*10d63b7dSRichard Lowe * target Target to build commands for
2136*10d63b7dSRichard Lowe * line Where to stuff result
2137*10d63b7dSRichard Lowe *
2138*10d63b7dSRichard Lowe * Global variables used:
2139*10d63b7dSRichard Lowe * c_at The Name "@", used to set macro value
2140*10d63b7dSRichard Lowe * command_changed Set if command is different from old
2141*10d63b7dSRichard Lowe * debug_level Should we trace activities?
2142*10d63b7dSRichard Lowe * do_not_exec_rule Always echo when running -n
2143*10d63b7dSRichard Lowe * empty_name The Name "", used for empty rule
2144*10d63b7dSRichard Lowe * funny Semantics of characters
2145*10d63b7dSRichard Lowe * ignore_errors Used to init field for line
2146*10d63b7dSRichard Lowe * is_conditional Set to false befor evaling macro, checked
2147*10d63b7dSRichard Lowe * after expanding macros
2148*10d63b7dSRichard Lowe * keep_state Indicates that .KEEP_STATE is on
2149*10d63b7dSRichard Lowe * make_word_mentioned Set by macro eval, inits field for cmd
2150*10d63b7dSRichard Lowe * query The Name "?", used to set macro value
2151*10d63b7dSRichard Lowe * query_mentioned Set by macro eval, inits field for cmd
2152*10d63b7dSRichard Lowe * recursion_level Used for tracing
2153*10d63b7dSRichard Lowe * silent Used to init field for line
2154*10d63b7dSRichard Lowe */
2155*10d63b7dSRichard Lowe static void
build_command_strings(Name target,register Property line)2156*10d63b7dSRichard Lowe build_command_strings(Name target, register Property line)
2157*10d63b7dSRichard Lowe {
2158*10d63b7dSRichard Lowe String_rec command_line;
2159*10d63b7dSRichard Lowe register Cmd_line command_template = line->body.line.command_template;
2160*10d63b7dSRichard Lowe register Cmd_line *insert = &line->body.line.command_used;
2161*10d63b7dSRichard Lowe register Cmd_line used = *insert;
2162*10d63b7dSRichard Lowe wchar_t buffer[STRING_BUFFER_LENGTH];
2163*10d63b7dSRichard Lowe wchar_t *start;
2164*10d63b7dSRichard Lowe Name new_command_line;
2165*10d63b7dSRichard Lowe register Boolean new_command_longer = false;
2166*10d63b7dSRichard Lowe register Boolean ignore_all_command_dependency = true;
2167*10d63b7dSRichard Lowe Property member;
2168*10d63b7dSRichard Lowe static Name less_name;
2169*10d63b7dSRichard Lowe static Name percent_name;
2170*10d63b7dSRichard Lowe static Name star;
2171*10d63b7dSRichard Lowe Name tmp_name;
2172*10d63b7dSRichard Lowe
2173*10d63b7dSRichard Lowe if (less_name == NULL) {
2174*10d63b7dSRichard Lowe MBSTOWCS(wcs_buffer, "<");
2175*10d63b7dSRichard Lowe less_name = GETNAME(wcs_buffer, FIND_LENGTH);
2176*10d63b7dSRichard Lowe MBSTOWCS(wcs_buffer, "%");
2177*10d63b7dSRichard Lowe percent_name = GETNAME(wcs_buffer, FIND_LENGTH);
2178*10d63b7dSRichard Lowe MBSTOWCS(wcs_buffer, "*");
2179*10d63b7dSRichard Lowe star = GETNAME(wcs_buffer, FIND_LENGTH);
2180*10d63b7dSRichard Lowe }
2181*10d63b7dSRichard Lowe
2182*10d63b7dSRichard Lowe /* We have to check if a target depends on conditional macros */
2183*10d63b7dSRichard Lowe /* Targets that do must be reprocessed by doname() each time around */
2184*10d63b7dSRichard Lowe /* since the macro values used when building the target might have */
2185*10d63b7dSRichard Lowe /* changed */
2186*10d63b7dSRichard Lowe conditional_macro_used = false;
2187*10d63b7dSRichard Lowe /* If we are building a lib.a(member) target $@ should be bound */
2188*10d63b7dSRichard Lowe /* to lib.a */
2189*10d63b7dSRichard Lowe if (target->is_member &&
2190*10d63b7dSRichard Lowe ((member = get_prop(target->prop, member_prop)) != NULL)) {
2191*10d63b7dSRichard Lowe target = member->body.member.library;
2192*10d63b7dSRichard Lowe }
2193*10d63b7dSRichard Lowe /* If we are building a "::" help target $@ should be bound to */
2194*10d63b7dSRichard Lowe /* the real target name */
2195*10d63b7dSRichard Lowe /* A lib.a(member) target is never :: */
2196*10d63b7dSRichard Lowe if (target->has_target_prop) {
2197*10d63b7dSRichard Lowe target = get_prop(target->prop, target_prop)->
2198*10d63b7dSRichard Lowe body.target.target;
2199*10d63b7dSRichard Lowe }
2200*10d63b7dSRichard Lowe /* Bind the magic macros that make supplies */
2201*10d63b7dSRichard Lowe tmp_name = target;
2202*10d63b7dSRichard Lowe if(tmp_name != NULL) {
2203*10d63b7dSRichard Lowe if (tmp_name->has_vpath_alias_prop) {
2204*10d63b7dSRichard Lowe tmp_name = get_prop(tmp_name->prop, vpath_alias_prop)->
2205*10d63b7dSRichard Lowe body.vpath_alias.alias;
2206*10d63b7dSRichard Lowe }
2207*10d63b7dSRichard Lowe }
2208*10d63b7dSRichard Lowe (void) SETVAR(c_at, tmp_name, false);
2209*10d63b7dSRichard Lowe
2210*10d63b7dSRichard Lowe tmp_name = line->body.line.star;
2211*10d63b7dSRichard Lowe if(tmp_name != NULL) {
2212*10d63b7dSRichard Lowe if (tmp_name->has_vpath_alias_prop) {
2213*10d63b7dSRichard Lowe tmp_name = get_prop(tmp_name->prop, vpath_alias_prop)->
2214*10d63b7dSRichard Lowe body.vpath_alias.alias;
2215*10d63b7dSRichard Lowe }
2216*10d63b7dSRichard Lowe }
2217*10d63b7dSRichard Lowe (void) SETVAR(star, tmp_name, false);
2218*10d63b7dSRichard Lowe
2219*10d63b7dSRichard Lowe tmp_name = line->body.line.less;
2220*10d63b7dSRichard Lowe if(tmp_name != NULL) {
2221*10d63b7dSRichard Lowe if (tmp_name->has_vpath_alias_prop) {
2222*10d63b7dSRichard Lowe tmp_name = get_prop(tmp_name->prop, vpath_alias_prop)->
2223*10d63b7dSRichard Lowe body.vpath_alias.alias;
2224*10d63b7dSRichard Lowe }
2225*10d63b7dSRichard Lowe }
2226*10d63b7dSRichard Lowe (void) SETVAR(less_name, tmp_name, false);
2227*10d63b7dSRichard Lowe
2228*10d63b7dSRichard Lowe tmp_name = line->body.line.percent;
2229*10d63b7dSRichard Lowe if(tmp_name != NULL) {
2230*10d63b7dSRichard Lowe if (tmp_name->has_vpath_alias_prop) {
2231*10d63b7dSRichard Lowe tmp_name = get_prop(tmp_name->prop, vpath_alias_prop)->
2232*10d63b7dSRichard Lowe body.vpath_alias.alias;
2233*10d63b7dSRichard Lowe }
2234*10d63b7dSRichard Lowe }
2235*10d63b7dSRichard Lowe (void) SETVAR(percent_name, tmp_name, false);
2236*10d63b7dSRichard Lowe
2237*10d63b7dSRichard Lowe /* $? is seldom used and it is expensive to build */
2238*10d63b7dSRichard Lowe /* so we store the list form and build the string on demand */
2239*10d63b7dSRichard Lowe Chain query_list = NULL;
2240*10d63b7dSRichard Lowe Chain *query_list_tail = &query_list;
2241*10d63b7dSRichard Lowe
2242*10d63b7dSRichard Lowe for (Chain ch = line->body.line.query; ch != NULL; ch = ch->next) {
2243*10d63b7dSRichard Lowe *query_list_tail = ALLOC(Chain);
2244*10d63b7dSRichard Lowe (*query_list_tail)->name = ch->name;
2245*10d63b7dSRichard Lowe if ((*query_list_tail)->name->has_vpath_alias_prop) {
2246*10d63b7dSRichard Lowe (*query_list_tail)->name =
2247*10d63b7dSRichard Lowe get_prop((*query_list_tail)->name->prop,
2248*10d63b7dSRichard Lowe vpath_alias_prop)->body.vpath_alias.alias;
2249*10d63b7dSRichard Lowe }
2250*10d63b7dSRichard Lowe (*query_list_tail)->next = NULL;
2251*10d63b7dSRichard Lowe query_list_tail = &(*query_list_tail)->next;
2252*10d63b7dSRichard Lowe }
2253*10d63b7dSRichard Lowe (void) setvar_daemon(query,
2254*10d63b7dSRichard Lowe (Name) query_list,
2255*10d63b7dSRichard Lowe false,
2256*10d63b7dSRichard Lowe chain_daemon,
2257*10d63b7dSRichard Lowe false,
2258*10d63b7dSRichard Lowe debug_level);
2259*10d63b7dSRichard Lowe
2260*10d63b7dSRichard Lowe /* build $^ */
2261*10d63b7dSRichard Lowe Chain hat_list = NULL;
2262*10d63b7dSRichard Lowe Chain *hat_list_tail = &hat_list;
2263*10d63b7dSRichard Lowe
2264*10d63b7dSRichard Lowe for (Dependency dependency = line->body.line.dependencies;
2265*10d63b7dSRichard Lowe dependency != NULL;
2266*10d63b7dSRichard Lowe dependency = dependency->next) {
2267*10d63b7dSRichard Lowe /* skip automatic dependencies */
2268*10d63b7dSRichard Lowe if (!dependency->automatic) {
2269*10d63b7dSRichard Lowe if ((dependency->name != force) &&
2270*10d63b7dSRichard Lowe (dependency->stale == false)) {
2271*10d63b7dSRichard Lowe *hat_list_tail = ALLOC(Chain);
2272*10d63b7dSRichard Lowe
2273*10d63b7dSRichard Lowe if (dependency->name->is_member &&
2274*10d63b7dSRichard Lowe (get_prop(dependency->name->prop, member_prop) != NULL)) {
2275*10d63b7dSRichard Lowe (*hat_list_tail)->name =
2276*10d63b7dSRichard Lowe get_prop(dependency->name->prop,
2277*10d63b7dSRichard Lowe member_prop)->body.member.member;
2278*10d63b7dSRichard Lowe } else {
2279*10d63b7dSRichard Lowe (*hat_list_tail)->name = dependency->name;
2280*10d63b7dSRichard Lowe }
2281*10d63b7dSRichard Lowe
2282*10d63b7dSRichard Lowe if((*hat_list_tail)->name != NULL) {
2283*10d63b7dSRichard Lowe if ((*hat_list_tail)->name->has_vpath_alias_prop) {
2284*10d63b7dSRichard Lowe (*hat_list_tail)->name =
2285*10d63b7dSRichard Lowe get_prop((*hat_list_tail)->name->prop,
2286*10d63b7dSRichard Lowe vpath_alias_prop)->body.vpath_alias.alias;
2287*10d63b7dSRichard Lowe }
2288*10d63b7dSRichard Lowe }
2289*10d63b7dSRichard Lowe
2290*10d63b7dSRichard Lowe (*hat_list_tail)->next = NULL;
2291*10d63b7dSRichard Lowe hat_list_tail = &(*hat_list_tail)->next;
2292*10d63b7dSRichard Lowe }
2293*10d63b7dSRichard Lowe }
2294*10d63b7dSRichard Lowe }
2295*10d63b7dSRichard Lowe (void) setvar_daemon(hat,
2296*10d63b7dSRichard Lowe (Name) hat_list,
2297*10d63b7dSRichard Lowe false,
2298*10d63b7dSRichard Lowe chain_daemon,
2299*10d63b7dSRichard Lowe false,
2300*10d63b7dSRichard Lowe debug_level);
2301*10d63b7dSRichard Lowe
2302*10d63b7dSRichard Lowe /* We have two command sequences we need to handle */
2303*10d63b7dSRichard Lowe /* The old one that we probably read from .make.state */
2304*10d63b7dSRichard Lowe /* and the new one we are building that will replace the old one */
2305*10d63b7dSRichard Lowe /* Even when KEEP_STATE is not on we build a new command sequence and store */
2306*10d63b7dSRichard Lowe /* it in the line prop. This command sequence is then executed by */
2307*10d63b7dSRichard Lowe /* run_command(). If KEEP_STATE is on it is also later written to */
2308*10d63b7dSRichard Lowe /* .make.state. The routine replaces the old command line by line with the */
2309*10d63b7dSRichard Lowe /* new one trying to reuse Cmd_lines */
2310*10d63b7dSRichard Lowe
2311*10d63b7dSRichard Lowe /* If there is no old command_used we have to start creating */
2312*10d63b7dSRichard Lowe /* Cmd_lines to keep the new cmd in */
2313*10d63b7dSRichard Lowe if (used == NULL) {
2314*10d63b7dSRichard Lowe new_command_longer = true;
2315*10d63b7dSRichard Lowe *insert = used = ALLOC(Cmd_line);
2316*10d63b7dSRichard Lowe used->next = NULL;
2317*10d63b7dSRichard Lowe used->command_line = NULL;
2318*10d63b7dSRichard Lowe insert = &used->next;
2319*10d63b7dSRichard Lowe }
2320*10d63b7dSRichard Lowe /* Run thru the template for the new command and build the expanded */
2321*10d63b7dSRichard Lowe /* new command lines */
2322*10d63b7dSRichard Lowe for (;
2323*10d63b7dSRichard Lowe command_template != NULL;
2324*10d63b7dSRichard Lowe command_template = command_template->next, insert = &used->next, used = *insert) {
2325*10d63b7dSRichard Lowe /* If there is no old command_used Cmd_line we need to */
2326*10d63b7dSRichard Lowe /* create one and say that cmd consistency failed */
2327*10d63b7dSRichard Lowe if (used == NULL) {
2328*10d63b7dSRichard Lowe new_command_longer = true;
2329*10d63b7dSRichard Lowe *insert = used = ALLOC(Cmd_line);
2330*10d63b7dSRichard Lowe used->next = NULL;
2331*10d63b7dSRichard Lowe used->command_line = empty_name;
2332*10d63b7dSRichard Lowe }
2333*10d63b7dSRichard Lowe /* Prepare the Cmd_line for the processing */
2334*10d63b7dSRichard Lowe /* The command line prefixes "@-=?" are stripped and that */
2335*10d63b7dSRichard Lowe /* information is saved in the Cmd_line */
2336*10d63b7dSRichard Lowe used->assign = false;
2337*10d63b7dSRichard Lowe used->ignore_error = ignore_errors;
2338*10d63b7dSRichard Lowe used->silent = silent;
2339*10d63b7dSRichard Lowe used->always_exec = false;
2340*10d63b7dSRichard Lowe /* Expand the macros in the command line */
2341*10d63b7dSRichard Lowe INIT_STRING_FROM_STACK(command_line, buffer);
2342*10d63b7dSRichard Lowe make_word_mentioned =
2343*10d63b7dSRichard Lowe query_mentioned =
2344*10d63b7dSRichard Lowe false;
2345*10d63b7dSRichard Lowe expand_value(command_template->command_line, &command_line, true);
2346*10d63b7dSRichard Lowe /* If the macro $(MAKE) is mentioned in the command */
2347*10d63b7dSRichard Lowe /* "make -n" runs actually execute the command */
2348*10d63b7dSRichard Lowe used->make_refd = make_word_mentioned;
2349*10d63b7dSRichard Lowe used->ignore_command_dependency = query_mentioned;
2350*10d63b7dSRichard Lowe /* Strip the prefixes */
2351*10d63b7dSRichard Lowe start = command_line.buffer.start;
2352*10d63b7dSRichard Lowe for (;
2353*10d63b7dSRichard Lowe iswspace(*start) ||
2354*10d63b7dSRichard Lowe (get_char_semantics_value(*start) & (int) command_prefix_sem);
2355*10d63b7dSRichard Lowe start++) {
2356*10d63b7dSRichard Lowe switch (*start) {
2357*10d63b7dSRichard Lowe case question_char:
2358*10d63b7dSRichard Lowe used->ignore_command_dependency = true;
2359*10d63b7dSRichard Lowe break;
2360*10d63b7dSRichard Lowe case exclam_char:
2361*10d63b7dSRichard Lowe used->ignore_command_dependency = false;
2362*10d63b7dSRichard Lowe break;
2363*10d63b7dSRichard Lowe case equal_char:
2364*10d63b7dSRichard Lowe used->assign = true;
2365*10d63b7dSRichard Lowe break;
2366*10d63b7dSRichard Lowe case hyphen_char:
2367*10d63b7dSRichard Lowe used->ignore_error = true;
2368*10d63b7dSRichard Lowe break;
2369*10d63b7dSRichard Lowe case at_char:
2370*10d63b7dSRichard Lowe if (!do_not_exec_rule) {
2371*10d63b7dSRichard Lowe used->silent = true;
2372*10d63b7dSRichard Lowe }
2373*10d63b7dSRichard Lowe break;
2374*10d63b7dSRichard Lowe case plus_char:
2375*10d63b7dSRichard Lowe if(posix) {
2376*10d63b7dSRichard Lowe used->always_exec = true;
2377*10d63b7dSRichard Lowe }
2378*10d63b7dSRichard Lowe break;
2379*10d63b7dSRichard Lowe }
2380*10d63b7dSRichard Lowe }
2381*10d63b7dSRichard Lowe /* If all command lines of the template are prefixed with "?"*/
2382*10d63b7dSRichard Lowe /* the VIRTUAL_ROOT is not used for cmd consistency checks */
2383*10d63b7dSRichard Lowe if (!used->ignore_command_dependency) {
2384*10d63b7dSRichard Lowe ignore_all_command_dependency = false;
2385*10d63b7dSRichard Lowe }
2386*10d63b7dSRichard Lowe /* Internalize the expanded and stripped command line */
2387*10d63b7dSRichard Lowe new_command_line = GETNAME(start, FIND_LENGTH);
2388*10d63b7dSRichard Lowe if ((used->command_line == NULL) &&
2389*10d63b7dSRichard Lowe (line->body.line.sccs_command)) {
2390*10d63b7dSRichard Lowe used->command_line = new_command_line;
2391*10d63b7dSRichard Lowe new_command_longer = false;
2392*10d63b7dSRichard Lowe }
2393*10d63b7dSRichard Lowe /* Compare it with the old one for command consistency */
2394*10d63b7dSRichard Lowe if (used->command_line != new_command_line) {
2395*10d63b7dSRichard Lowe Name vpath_translated = vpath_translation(new_command_line);
2396*10d63b7dSRichard Lowe if (keep_state &&
2397*10d63b7dSRichard Lowe !used->ignore_command_dependency && (vpath_translated != used->command_line)) {
2398*10d63b7dSRichard Lowe if (debug_level > 0) {
2399*10d63b7dSRichard Lowe if (used->command_line != NULL
2400*10d63b7dSRichard Lowe && *used->command_line->string_mb !=
2401*10d63b7dSRichard Lowe '\0') {
2402*10d63b7dSRichard Lowe (void) printf(gettext("%*sBuilding %s because new command \n\t%s\n%*sdifferent from old\n\t%s\n"),
2403*10d63b7dSRichard Lowe recursion_level,
2404*10d63b7dSRichard Lowe "",
2405*10d63b7dSRichard Lowe target->string_mb,
2406*10d63b7dSRichard Lowe vpath_translated->string_mb,
2407*10d63b7dSRichard Lowe recursion_level,
2408*10d63b7dSRichard Lowe "",
2409*10d63b7dSRichard Lowe used->
2410*10d63b7dSRichard Lowe command_line->
2411*10d63b7dSRichard Lowe string_mb);
2412*10d63b7dSRichard Lowe } else {
2413*10d63b7dSRichard Lowe (void) printf(gettext("%*sBuilding %s because new command \n\t%s\n%*sdifferent from empty old command\n"),
2414*10d63b7dSRichard Lowe recursion_level,
2415*10d63b7dSRichard Lowe "",
2416*10d63b7dSRichard Lowe target->string_mb,
2417*10d63b7dSRichard Lowe vpath_translated->string_mb,
2418*10d63b7dSRichard Lowe recursion_level,
2419*10d63b7dSRichard Lowe "");
2420*10d63b7dSRichard Lowe }
2421*10d63b7dSRichard Lowe }
2422*10d63b7dSRichard Lowe command_changed = true;
2423*10d63b7dSRichard Lowe line->body.line.is_out_of_date = true;
2424*10d63b7dSRichard Lowe }
2425*10d63b7dSRichard Lowe used->command_line = new_command_line;
2426*10d63b7dSRichard Lowe }
2427*10d63b7dSRichard Lowe if (command_line.free_after_use) {
2428*10d63b7dSRichard Lowe retmem(command_line.buffer.start);
2429*10d63b7dSRichard Lowe }
2430*10d63b7dSRichard Lowe }
2431*10d63b7dSRichard Lowe /* Check if the old command is longer than the new for */
2432*10d63b7dSRichard Lowe /* command consistency */
2433*10d63b7dSRichard Lowe if (used != NULL) {
2434*10d63b7dSRichard Lowe *insert = NULL;
2435*10d63b7dSRichard Lowe if (keep_state &&
2436*10d63b7dSRichard Lowe !ignore_all_command_dependency) {
2437*10d63b7dSRichard Lowe if (debug_level > 0) {
2438*10d63b7dSRichard Lowe (void) printf(gettext("%*sBuilding %s because new command shorter than old\n"),
2439*10d63b7dSRichard Lowe recursion_level,
2440*10d63b7dSRichard Lowe "",
2441*10d63b7dSRichard Lowe target->string_mb);
2442*10d63b7dSRichard Lowe }
2443*10d63b7dSRichard Lowe command_changed = true;
2444*10d63b7dSRichard Lowe line->body.line.is_out_of_date = true;
2445*10d63b7dSRichard Lowe }
2446*10d63b7dSRichard Lowe }
2447*10d63b7dSRichard Lowe /* Check if the new command is longer than the old command for */
2448*10d63b7dSRichard Lowe /* command consistency */
2449*10d63b7dSRichard Lowe if (new_command_longer &&
2450*10d63b7dSRichard Lowe !ignore_all_command_dependency &&
2451*10d63b7dSRichard Lowe keep_state) {
2452*10d63b7dSRichard Lowe if (debug_level > 0) {
2453*10d63b7dSRichard Lowe (void) printf(gettext("%*sBuilding %s because new command longer than old\n"),
2454*10d63b7dSRichard Lowe recursion_level,
2455*10d63b7dSRichard Lowe "",
2456*10d63b7dSRichard Lowe target->string_mb);
2457*10d63b7dSRichard Lowe }
2458*10d63b7dSRichard Lowe command_changed = true;
2459*10d63b7dSRichard Lowe line->body.line.is_out_of_date = true;
2460*10d63b7dSRichard Lowe }
2461*10d63b7dSRichard Lowe /* Unbind the magic macros */
2462*10d63b7dSRichard Lowe (void) SETVAR(c_at, (Name) NULL, false);
2463*10d63b7dSRichard Lowe (void) SETVAR(star, (Name) NULL, false);
2464*10d63b7dSRichard Lowe (void) SETVAR(less_name, (Name) NULL, false);
2465*10d63b7dSRichard Lowe (void) SETVAR(percent_name, (Name) NULL, false);
2466*10d63b7dSRichard Lowe (void) SETVAR(query, (Name) NULL, false);
2467*10d63b7dSRichard Lowe if (query_list != NULL) {
2468*10d63b7dSRichard Lowe delete_query_chain(query_list);
2469*10d63b7dSRichard Lowe }
2470*10d63b7dSRichard Lowe (void) SETVAR(hat, (Name) NULL, false);
2471*10d63b7dSRichard Lowe if (hat_list != NULL) {
2472*10d63b7dSRichard Lowe delete_query_chain(hat_list);
2473*10d63b7dSRichard Lowe }
2474*10d63b7dSRichard Lowe
2475*10d63b7dSRichard Lowe if (conditional_macro_used) {
2476*10d63b7dSRichard Lowe target->conditional_macro_list = cond_macro_list;
2477*10d63b7dSRichard Lowe cond_macro_list = NULL;
2478*10d63b7dSRichard Lowe target->depends_on_conditional = true;
2479*10d63b7dSRichard Lowe }
2480*10d63b7dSRichard Lowe }
2481*10d63b7dSRichard Lowe
2482*10d63b7dSRichard Lowe /*
2483*10d63b7dSRichard Lowe * touch_command(line, target, result)
2484*10d63b7dSRichard Lowe *
2485*10d63b7dSRichard Lowe * If this is an "make -t" run we do this.
2486*10d63b7dSRichard Lowe * We touch all targets in the target group ("foo + fie:") if any.
2487*10d63b7dSRichard Lowe *
2488*10d63b7dSRichard Lowe * Return value:
2489*10d63b7dSRichard Lowe * Indicates if the command failed or not
2490*10d63b7dSRichard Lowe *
2491*10d63b7dSRichard Lowe * Parameters:
2492*10d63b7dSRichard Lowe * line The command line to update
2493*10d63b7dSRichard Lowe * target The target we are touching
2494*10d63b7dSRichard Lowe * result Initial value for the result we return
2495*10d63b7dSRichard Lowe *
2496*10d63b7dSRichard Lowe * Global variables used:
2497*10d63b7dSRichard Lowe * do_not_exec_rule Indicates that -n is on
2498*10d63b7dSRichard Lowe * silent Do not echo commands
2499*10d63b7dSRichard Lowe */
2500*10d63b7dSRichard Lowe static Doname
touch_command(register Property line,register Name target,Doname result)2501*10d63b7dSRichard Lowe touch_command(register Property line, register Name target, Doname result)
2502*10d63b7dSRichard Lowe {
2503*10d63b7dSRichard Lowe Name name;
2504*10d63b7dSRichard Lowe register Chain target_group;
2505*10d63b7dSRichard Lowe String_rec touch_string;
2506*10d63b7dSRichard Lowe wchar_t buffer[MAXPATHLEN];
2507*10d63b7dSRichard Lowe Name touch_cmd;
2508*10d63b7dSRichard Lowe Cmd_line rule;
2509*10d63b7dSRichard Lowe
2510*10d63b7dSRichard Lowe for (name = target, target_group = NULL; name != NULL;) {
2511*10d63b7dSRichard Lowe if (!name->is_member) {
2512*10d63b7dSRichard Lowe /*
2513*10d63b7dSRichard Lowe * Build a touch command that can be passed
2514*10d63b7dSRichard Lowe * to dosys(). If KEEP_STATE is on, "make -t"
2515*10d63b7dSRichard Lowe * will save the proper command, not the
2516*10d63b7dSRichard Lowe * "touch" in .make.state.
2517*10d63b7dSRichard Lowe */
2518*10d63b7dSRichard Lowe INIT_STRING_FROM_STACK(touch_string, buffer);
2519*10d63b7dSRichard Lowe MBSTOWCS(wcs_buffer, "touch ");
2520*10d63b7dSRichard Lowe append_string(wcs_buffer, &touch_string, FIND_LENGTH);
2521*10d63b7dSRichard Lowe touch_cmd = name;
2522*10d63b7dSRichard Lowe if (name->has_vpath_alias_prop) {
2523*10d63b7dSRichard Lowe touch_cmd = get_prop(name->prop,
2524*10d63b7dSRichard Lowe vpath_alias_prop)->
2525*10d63b7dSRichard Lowe body.vpath_alias.alias;
2526*10d63b7dSRichard Lowe }
2527*10d63b7dSRichard Lowe APPEND_NAME(touch_cmd,
2528*10d63b7dSRichard Lowe &touch_string,
2529*10d63b7dSRichard Lowe FIND_LENGTH);
2530*10d63b7dSRichard Lowe touch_cmd = GETNAME(touch_string.buffer.start,
2531*10d63b7dSRichard Lowe FIND_LENGTH);
2532*10d63b7dSRichard Lowe if (touch_string.free_after_use) {
2533*10d63b7dSRichard Lowe retmem(touch_string.buffer.start);
2534*10d63b7dSRichard Lowe }
2535*10d63b7dSRichard Lowe if (!silent ||
2536*10d63b7dSRichard Lowe do_not_exec_rule &&
2537*10d63b7dSRichard Lowe (target_group == NULL)) {
2538*10d63b7dSRichard Lowe (void) printf("%s\n", touch_cmd->string_mb);
2539*10d63b7dSRichard Lowe }
2540*10d63b7dSRichard Lowe /* Run the touch command, or simulate it */
2541*10d63b7dSRichard Lowe if (!do_not_exec_rule) {
2542*10d63b7dSRichard Lowe result = dosys(touch_cmd,
2543*10d63b7dSRichard Lowe false,
2544*10d63b7dSRichard Lowe false,
2545*10d63b7dSRichard Lowe false,
2546*10d63b7dSRichard Lowe false,
2547*10d63b7dSRichard Lowe name);
2548*10d63b7dSRichard Lowe } else {
2549*10d63b7dSRichard Lowe result = build_ok;
2550*10d63b7dSRichard Lowe }
2551*10d63b7dSRichard Lowe } else {
2552*10d63b7dSRichard Lowe result = build_ok;
2553*10d63b7dSRichard Lowe }
2554*10d63b7dSRichard Lowe if (target_group == NULL) {
2555*10d63b7dSRichard Lowe target_group = line->body.line.target_group;
2556*10d63b7dSRichard Lowe } else {
2557*10d63b7dSRichard Lowe target_group = target_group->next;
2558*10d63b7dSRichard Lowe }
2559*10d63b7dSRichard Lowe if (target_group != NULL) {
2560*10d63b7dSRichard Lowe name = target_group->name;
2561*10d63b7dSRichard Lowe } else {
2562*10d63b7dSRichard Lowe name = NULL;
2563*10d63b7dSRichard Lowe }
2564*10d63b7dSRichard Lowe }
2565*10d63b7dSRichard Lowe return result;
2566*10d63b7dSRichard Lowe }
2567*10d63b7dSRichard Lowe
2568*10d63b7dSRichard Lowe /*
2569*10d63b7dSRichard Lowe * update_target(line, result)
2570*10d63b7dSRichard Lowe *
2571*10d63b7dSRichard Lowe * updates the status of a target after executing its commands.
2572*10d63b7dSRichard Lowe *
2573*10d63b7dSRichard Lowe * Parameters:
2574*10d63b7dSRichard Lowe * line The command line block to update
2575*10d63b7dSRichard Lowe * result Indicates that build is OK so can update
2576*10d63b7dSRichard Lowe *
2577*10d63b7dSRichard Lowe * Global variables used:
2578*10d63b7dSRichard Lowe * do_not_exec_rule Indicates that -n is on
2579*10d63b7dSRichard Lowe * touch Fake the new timestamp if we are just touching
2580*10d63b7dSRichard Lowe */
2581*10d63b7dSRichard Lowe void
update_target(Property line,Doname result)2582*10d63b7dSRichard Lowe update_target(Property line, Doname result)
2583*10d63b7dSRichard Lowe {
2584*10d63b7dSRichard Lowe Name target;
2585*10d63b7dSRichard Lowe Chain target_group;
2586*10d63b7dSRichard Lowe Property line2;
2587*10d63b7dSRichard Lowe timestruc_t old_stat_time;
2588*10d63b7dSRichard Lowe Property member;
2589*10d63b7dSRichard Lowe
2590*10d63b7dSRichard Lowe /*
2591*10d63b7dSRichard Lowe * [tolik] Additional fix for bug 1063790. It was fixed
2592*10d63b7dSRichard Lowe * for serial make long ago, but DMake dumps core when
2593*10d63b7dSRichard Lowe * target is a symlink and sccs file is newer then target.
2594*10d63b7dSRichard Lowe * In this case, finish_children() calls update_target()
2595*10d63b7dSRichard Lowe * with line==NULL.
2596*10d63b7dSRichard Lowe */
2597*10d63b7dSRichard Lowe if(line == NULL) {
2598*10d63b7dSRichard Lowe /* XXX. Should we do anything here? */
2599*10d63b7dSRichard Lowe return;
2600*10d63b7dSRichard Lowe }
2601*10d63b7dSRichard Lowe
2602*10d63b7dSRichard Lowe target = line->body.line.target;
2603*10d63b7dSRichard Lowe
2604*10d63b7dSRichard Lowe if ((result == build_ok) && (line->body.line.command_used != NULL)) {
2605*10d63b7dSRichard Lowe if (do_not_exec_rule ||
2606*10d63b7dSRichard Lowe touch ||
2607*10d63b7dSRichard Lowe (target->is_member &&
2608*10d63b7dSRichard Lowe (line->body.line.command_template != NULL) &&
2609*10d63b7dSRichard Lowe (line->body.line.command_template->command_line->string_mb[0] == 0) &&
2610*10d63b7dSRichard Lowe (line->body.line.command_template->next == NULL))) {
2611*10d63b7dSRichard Lowe /* If we are simulating execution we need to fake a */
2612*10d63b7dSRichard Lowe /* new timestamp for the target we didnt build */
2613*10d63b7dSRichard Lowe target->stat.time = file_max_time;
2614*10d63b7dSRichard Lowe } else {
2615*10d63b7dSRichard Lowe /*
2616*10d63b7dSRichard Lowe * If we really built the target we read the new
2617*10d63b7dSRichard Lowe * timestamp.
2618*10d63b7dSRichard Lowe * Fix for bug #1110906: if .c file is newer than
2619*10d63b7dSRichard Lowe * the corresponding .o file which is in an archive
2620*10d63b7dSRichard Lowe * file, make will compile the .c file but it won't
2621*10d63b7dSRichard Lowe * update the object in the .a file.
2622*10d63b7dSRichard Lowe */
2623*10d63b7dSRichard Lowe old_stat_time = target->stat.time;
2624*10d63b7dSRichard Lowe target->stat.time = file_no_time;
2625*10d63b7dSRichard Lowe (void) exists(target);
2626*10d63b7dSRichard Lowe if ((target->is_member) &&
2627*10d63b7dSRichard Lowe (target->stat.time == old_stat_time)) {
2628*10d63b7dSRichard Lowe member = get_prop(target->prop, member_prop);
2629*10d63b7dSRichard Lowe if (member != NULL) {
2630*10d63b7dSRichard Lowe target->stat.time = member->body.member.library->stat.time;
2631*10d63b7dSRichard Lowe target->stat.time.tv_sec++;
2632*10d63b7dSRichard Lowe }
2633*10d63b7dSRichard Lowe }
2634*10d63b7dSRichard Lowe }
2635*10d63b7dSRichard Lowe /* If the target is part of a group we need to propagate the */
2636*10d63b7dSRichard Lowe /* result of the run to all members */
2637*10d63b7dSRichard Lowe for (target_group = line->body.line.target_group;
2638*10d63b7dSRichard Lowe target_group != NULL;
2639*10d63b7dSRichard Lowe target_group = target_group->next) {
2640*10d63b7dSRichard Lowe target_group->name->stat.time = target->stat.time;
2641*10d63b7dSRichard Lowe line2 = maybe_append_prop(target_group->name,
2642*10d63b7dSRichard Lowe line_prop);
2643*10d63b7dSRichard Lowe line2->body.line.command_used =
2644*10d63b7dSRichard Lowe line->body.line.command_used;
2645*10d63b7dSRichard Lowe line2->body.line.target = target_group->name;
2646*10d63b7dSRichard Lowe }
2647*10d63b7dSRichard Lowe }
2648*10d63b7dSRichard Lowe target->has_built = true;
2649*10d63b7dSRichard Lowe }
2650*10d63b7dSRichard Lowe
2651*10d63b7dSRichard Lowe /*
2652*10d63b7dSRichard Lowe * sccs_get(target, command)
2653*10d63b7dSRichard Lowe *
2654*10d63b7dSRichard Lowe * Figures out if it possible to sccs get a file
2655*10d63b7dSRichard Lowe * and builds the command to do it if it is.
2656*10d63b7dSRichard Lowe *
2657*10d63b7dSRichard Lowe * Return value:
2658*10d63b7dSRichard Lowe * Indicates if sccs get failed or not
2659*10d63b7dSRichard Lowe *
2660*10d63b7dSRichard Lowe * Parameters:
2661*10d63b7dSRichard Lowe * target Target to get
2662*10d63b7dSRichard Lowe * command Where to deposit command to use
2663*10d63b7dSRichard Lowe *
2664*10d63b7dSRichard Lowe * Global variables used:
2665*10d63b7dSRichard Lowe * debug_level Should we trace activities?
2666*10d63b7dSRichard Lowe * recursion_level Used for tracing
2667*10d63b7dSRichard Lowe * sccs_get_rule The rule to used for sccs getting
2668*10d63b7dSRichard Lowe */
2669*10d63b7dSRichard Lowe static Doname
sccs_get(register Name target,register Property * command)2670*10d63b7dSRichard Lowe sccs_get(register Name target, register Property *command)
2671*10d63b7dSRichard Lowe {
2672*10d63b7dSRichard Lowe register int result;
2673*10d63b7dSRichard Lowe char link[MAXPATHLEN];
2674*10d63b7dSRichard Lowe String_rec string;
2675*10d63b7dSRichard Lowe wchar_t name[MAXPATHLEN];
2676*10d63b7dSRichard Lowe register wchar_t *p;
2677*10d63b7dSRichard Lowe timestruc_t sccs_time;
2678*10d63b7dSRichard Lowe register Property line;
2679*10d63b7dSRichard Lowe int sym_link_depth = 0;
2680*10d63b7dSRichard Lowe
2681*10d63b7dSRichard Lowe /* For sccs, we need to chase symlinks. */
2682*10d63b7dSRichard Lowe while (target->stat.is_sym_link) {
2683*10d63b7dSRichard Lowe if (sym_link_depth++ > 90) {
2684*10d63b7dSRichard Lowe fatal(gettext("Can't read symbolic link `%s': Number of symbolic links encountered during path name traversal exceeds 90."),
2685*10d63b7dSRichard Lowe target->string_mb);
2686*10d63b7dSRichard Lowe }
2687*10d63b7dSRichard Lowe /* Read the value of the link. */
2688*10d63b7dSRichard Lowe result = readlink_vroot(target->string_mb,
2689*10d63b7dSRichard Lowe link,
2690*10d63b7dSRichard Lowe sizeof(link),
2691*10d63b7dSRichard Lowe NULL,
2692*10d63b7dSRichard Lowe VROOT_DEFAULT);
2693*10d63b7dSRichard Lowe if (result == -1) {
2694*10d63b7dSRichard Lowe fatal(gettext("Can't read symbolic link `%s': %s"),
2695*10d63b7dSRichard Lowe target->string_mb, errmsg(errno));
2696*10d63b7dSRichard Lowe }
2697*10d63b7dSRichard Lowe link[result] = 0;
2698*10d63b7dSRichard Lowe /* Use the value to build the proper filename. */
2699*10d63b7dSRichard Lowe INIT_STRING_FROM_STACK(string, name);
2700*10d63b7dSRichard Lowe
2701*10d63b7dSRichard Lowe Wstring wcb(target);
2702*10d63b7dSRichard Lowe if ((link[0] != slash_char) &&
2703*10d63b7dSRichard Lowe ((p = (wchar_t *) wcsrchr(wcb.get_string(), slash_char)) != NULL)) {
2704*10d63b7dSRichard Lowe append_string(wcb.get_string(), &string, p - wcb.get_string() + 1);
2705*10d63b7dSRichard Lowe }
2706*10d63b7dSRichard Lowe append_string(link, &string, result);
2707*10d63b7dSRichard Lowe /* Replace the old name with the translated name. */
2708*10d63b7dSRichard Lowe target = normalize_name(string.buffer.start, string.text.p - string.buffer.start);
2709*10d63b7dSRichard Lowe (void) exists(target);
2710*10d63b7dSRichard Lowe if (string.free_after_use) {
2711*10d63b7dSRichard Lowe retmem(string.buffer.start);
2712*10d63b7dSRichard Lowe }
2713*10d63b7dSRichard Lowe }
2714*10d63b7dSRichard Lowe
2715*10d63b7dSRichard Lowe /*
2716*10d63b7dSRichard Lowe * read_dir() also reads the ?/SCCS dir and saves information
2717*10d63b7dSRichard Lowe * about which files have SCSC/s. files.
2718*10d63b7dSRichard Lowe */
2719*10d63b7dSRichard Lowe if (target->stat.has_sccs == DONT_KNOW_SCCS) {
2720*10d63b7dSRichard Lowe read_directory_of_file(target);
2721*10d63b7dSRichard Lowe }
2722*10d63b7dSRichard Lowe switch (target->stat.has_sccs) {
2723*10d63b7dSRichard Lowe case DONT_KNOW_SCCS:
2724*10d63b7dSRichard Lowe /* We dont know by now there is no SCCS/s.* */
2725*10d63b7dSRichard Lowe target->stat.has_sccs = NO_SCCS;
2726*10d63b7dSRichard Lowe case NO_SCCS:
2727*10d63b7dSRichard Lowe /*
2728*10d63b7dSRichard Lowe * If there is no SCCS/s.* but the plain file exists,
2729*10d63b7dSRichard Lowe * we say things are OK.
2730*10d63b7dSRichard Lowe */
2731*10d63b7dSRichard Lowe if (target->stat.time > file_doesnt_exist) {
2732*10d63b7dSRichard Lowe return build_ok;
2733*10d63b7dSRichard Lowe }
2734*10d63b7dSRichard Lowe /* If we cant find the plain file, we give up. */
2735*10d63b7dSRichard Lowe return build_dont_know;
2736*10d63b7dSRichard Lowe case HAS_SCCS:
2737*10d63b7dSRichard Lowe /*
2738*10d63b7dSRichard Lowe * Pay dirt. We now need to figure out if the plain file
2739*10d63b7dSRichard Lowe * is out of date relative to the SCCS/s.* file.
2740*10d63b7dSRichard Lowe */
2741*10d63b7dSRichard Lowe sccs_time = exists(get_prop(target->prop,
2742*10d63b7dSRichard Lowe sccs_prop)->body.sccs.file);
2743*10d63b7dSRichard Lowe break;
2744*10d63b7dSRichard Lowe }
2745*10d63b7dSRichard Lowe
2746*10d63b7dSRichard Lowe if ((!target->has_complained &&
2747*10d63b7dSRichard Lowe (sccs_time != file_doesnt_exist) &&
2748*10d63b7dSRichard Lowe (sccs_get_rule != NULL))) {
2749*10d63b7dSRichard Lowe /* only checking */
2750*10d63b7dSRichard Lowe if (command == NULL) {
2751*10d63b7dSRichard Lowe return build_ok;
2752*10d63b7dSRichard Lowe }
2753*10d63b7dSRichard Lowe /*
2754*10d63b7dSRichard Lowe * We provide a command line for the target. The line is a
2755*10d63b7dSRichard Lowe * "sccs get" command from default.mk.
2756*10d63b7dSRichard Lowe */
2757*10d63b7dSRichard Lowe line = maybe_append_prop(target, line_prop);
2758*10d63b7dSRichard Lowe *command = line;
2759*10d63b7dSRichard Lowe if (sccs_time > target->stat.time) {
2760*10d63b7dSRichard Lowe /*
2761*10d63b7dSRichard Lowe * And only if the plain file is out of date do we
2762*10d63b7dSRichard Lowe * request execution of the command.
2763*10d63b7dSRichard Lowe */
2764*10d63b7dSRichard Lowe line->body.line.is_out_of_date = true;
2765*10d63b7dSRichard Lowe if (debug_level > 0) {
2766*10d63b7dSRichard Lowe (void) printf(gettext("%*sSccs getting %s because s. file is younger than source file\n"),
2767*10d63b7dSRichard Lowe recursion_level,
2768*10d63b7dSRichard Lowe "",
2769*10d63b7dSRichard Lowe target->string_mb);
2770*10d63b7dSRichard Lowe }
2771*10d63b7dSRichard Lowe }
2772*10d63b7dSRichard Lowe line->body.line.sccs_command = true;
2773*10d63b7dSRichard Lowe line->body.line.command_template = sccs_get_rule;
2774*10d63b7dSRichard Lowe if(!svr4 && (!allrules_read || posix)) {
2775*10d63b7dSRichard Lowe if((target->prop) &&
2776*10d63b7dSRichard Lowe (target->prop->body.sccs.file) &&
2777*10d63b7dSRichard Lowe (target->prop->body.sccs.file->string_mb)) {
2778*10d63b7dSRichard Lowe if((strlen(target->prop->body.sccs.file->string_mb) ==
2779*10d63b7dSRichard Lowe strlen(target->string_mb) + 2) &&
2780*10d63b7dSRichard Lowe (target->prop->body.sccs.file->string_mb[0] == 's') &&
2781*10d63b7dSRichard Lowe (target->prop->body.sccs.file->string_mb[1] == '.')) {
2782*10d63b7dSRichard Lowe
2783*10d63b7dSRichard Lowe line->body.line.command_template = get_posix_rule;
2784*10d63b7dSRichard Lowe }
2785*10d63b7dSRichard Lowe }
2786*10d63b7dSRichard Lowe }
2787*10d63b7dSRichard Lowe line->body.line.target = target;
2788*10d63b7dSRichard Lowe /*
2789*10d63b7dSRichard Lowe * Also make sure the rule is build with $* and $<
2790*10d63b7dSRichard Lowe * bound properly.
2791*10d63b7dSRichard Lowe */
2792*10d63b7dSRichard Lowe line->body.line.star = NULL;
2793*10d63b7dSRichard Lowe line->body.line.less = NULL;
2794*10d63b7dSRichard Lowe line->body.line.percent = NULL;
2795*10d63b7dSRichard Lowe return build_ok;
2796*10d63b7dSRichard Lowe }
2797*10d63b7dSRichard Lowe return build_dont_know;
2798*10d63b7dSRichard Lowe }
2799*10d63b7dSRichard Lowe
2800*10d63b7dSRichard Lowe /*
2801*10d63b7dSRichard Lowe * read_directory_of_file(file)
2802*10d63b7dSRichard Lowe *
2803*10d63b7dSRichard Lowe * Reads the directory the specified file lives in.
2804*10d63b7dSRichard Lowe *
2805*10d63b7dSRichard Lowe * Parameters:
2806*10d63b7dSRichard Lowe * file The file we need to read dir for
2807*10d63b7dSRichard Lowe *
2808*10d63b7dSRichard Lowe * Global variables used:
2809*10d63b7dSRichard Lowe * dot The Name ".", used as the default dir
2810*10d63b7dSRichard Lowe */
2811*10d63b7dSRichard Lowe void
read_directory_of_file(register Name file)2812*10d63b7dSRichard Lowe read_directory_of_file(register Name file)
2813*10d63b7dSRichard Lowe {
2814*10d63b7dSRichard Lowe
2815*10d63b7dSRichard Lowe Wstring file_string(file);
2816*10d63b7dSRichard Lowe wchar_t * wcb = file_string.get_string();
2817*10d63b7dSRichard Lowe wchar_t usr_include_buf[MAXPATHLEN];
2818*10d63b7dSRichard Lowe wchar_t usr_include_sys_buf[MAXPATHLEN];
2819*10d63b7dSRichard Lowe
2820*10d63b7dSRichard Lowe register Name directory = dot;
2821*10d63b7dSRichard Lowe register wchar_t *p = (wchar_t *) wcsrchr(wcb,
2822*10d63b7dSRichard Lowe (int) slash_char);
2823*10d63b7dSRichard Lowe register int length = p - wcb;
2824*10d63b7dSRichard Lowe static Name usr_include;
2825*10d63b7dSRichard Lowe static Name usr_include_sys;
2826*10d63b7dSRichard Lowe
2827*10d63b7dSRichard Lowe if (usr_include == NULL) {
2828*10d63b7dSRichard Lowe MBSTOWCS(usr_include_buf, "/usr/include");
2829*10d63b7dSRichard Lowe usr_include = GETNAME(usr_include_buf, FIND_LENGTH);
2830*10d63b7dSRichard Lowe MBSTOWCS(usr_include_sys_buf, "/usr/include/sys");
2831*10d63b7dSRichard Lowe usr_include_sys = GETNAME(usr_include_sys_buf, FIND_LENGTH);
2832*10d63b7dSRichard Lowe }
2833*10d63b7dSRichard Lowe
2834*10d63b7dSRichard Lowe /*
2835*10d63b7dSRichard Lowe * If the filename contains a "/" we have to extract the path
2836*10d63b7dSRichard Lowe * Else the path defaults to ".".
2837*10d63b7dSRichard Lowe */
2838*10d63b7dSRichard Lowe if (p != NULL) {
2839*10d63b7dSRichard Lowe /*
2840*10d63b7dSRichard Lowe * Check some popular directories first to possibly
2841*10d63b7dSRichard Lowe * save time. Compare string length first to gain speed.
2842*10d63b7dSRichard Lowe */
2843*10d63b7dSRichard Lowe if ((usr_include->hash.length == length) &&
2844*10d63b7dSRichard Lowe IS_WEQUALN(usr_include_buf,
2845*10d63b7dSRichard Lowe wcb,
2846*10d63b7dSRichard Lowe length)) {
2847*10d63b7dSRichard Lowe directory = usr_include;
2848*10d63b7dSRichard Lowe } else if ((usr_include_sys->hash.length == length) &&
2849*10d63b7dSRichard Lowe IS_WEQUALN(usr_include_sys_buf,
2850*10d63b7dSRichard Lowe wcb,
2851*10d63b7dSRichard Lowe length)) {
2852*10d63b7dSRichard Lowe directory = usr_include_sys;
2853*10d63b7dSRichard Lowe } else {
2854*10d63b7dSRichard Lowe directory = GETNAME(wcb, length);
2855*10d63b7dSRichard Lowe }
2856*10d63b7dSRichard Lowe }
2857*10d63b7dSRichard Lowe (void) read_dir(directory,
2858*10d63b7dSRichard Lowe (wchar_t *) NULL,
2859*10d63b7dSRichard Lowe (Property) NULL,
2860*10d63b7dSRichard Lowe (wchar_t *) NULL);
2861*10d63b7dSRichard Lowe }
2862*10d63b7dSRichard Lowe
2863*10d63b7dSRichard Lowe /*
2864*10d63b7dSRichard Lowe * add_pattern_conditionals(target)
2865*10d63b7dSRichard Lowe *
2866*10d63b7dSRichard Lowe * Scan the list of conditionals defined for pattern targets and add any
2867*10d63b7dSRichard Lowe * that match this target to its list of conditionals.
2868*10d63b7dSRichard Lowe *
2869*10d63b7dSRichard Lowe * Parameters:
2870*10d63b7dSRichard Lowe * target The target we should add conditionals for
2871*10d63b7dSRichard Lowe *
2872*10d63b7dSRichard Lowe * Global variables used:
2873*10d63b7dSRichard Lowe * conditionals The list of pattern conditionals
2874*10d63b7dSRichard Lowe */
2875*10d63b7dSRichard Lowe static void
add_pattern_conditionals(register Name target)2876*10d63b7dSRichard Lowe add_pattern_conditionals(register Name target)
2877*10d63b7dSRichard Lowe {
2878*10d63b7dSRichard Lowe register Property conditional;
2879*10d63b7dSRichard Lowe Property new_prop;
2880*10d63b7dSRichard Lowe Property *previous;
2881*10d63b7dSRichard Lowe Name_rec dummy;
2882*10d63b7dSRichard Lowe wchar_t *pattern;
2883*10d63b7dSRichard Lowe wchar_t *percent;
2884*10d63b7dSRichard Lowe int length;
2885*10d63b7dSRichard Lowe
2886*10d63b7dSRichard Lowe Wstring wcb(target);
2887*10d63b7dSRichard Lowe Wstring wcb1;
2888*10d63b7dSRichard Lowe
2889*10d63b7dSRichard Lowe for (conditional = get_prop(conditionals->prop, conditional_prop);
2890*10d63b7dSRichard Lowe conditional != NULL;
2891*10d63b7dSRichard Lowe conditional = get_prop(conditional->next, conditional_prop)) {
2892*10d63b7dSRichard Lowe wcb1.init(conditional->body.conditional.target);
2893*10d63b7dSRichard Lowe pattern = wcb1.get_string();
2894*10d63b7dSRichard Lowe if (pattern[1] != 0) {
2895*10d63b7dSRichard Lowe percent = (wchar_t *) wcschr(pattern, (int) percent_char);
2896*10d63b7dSRichard Lowe if (!wcb.equaln(pattern, percent-pattern) ||
2897*10d63b7dSRichard Lowe !IS_WEQUAL(wcb.get_string(wcb.length()-wcslen(percent+1)), percent+1)) {
2898*10d63b7dSRichard Lowe continue;
2899*10d63b7dSRichard Lowe }
2900*10d63b7dSRichard Lowe }
2901*10d63b7dSRichard Lowe for (previous = &target->prop;
2902*10d63b7dSRichard Lowe *previous != NULL;
2903*10d63b7dSRichard Lowe previous = &(*previous)->next) {
2904*10d63b7dSRichard Lowe if (((*previous)->type == conditional_prop) &&
2905*10d63b7dSRichard Lowe ((*previous)->body.conditional.sequence >
2906*10d63b7dSRichard Lowe conditional->body.conditional.sequence)) {
2907*10d63b7dSRichard Lowe break;
2908*10d63b7dSRichard Lowe }
2909*10d63b7dSRichard Lowe }
2910*10d63b7dSRichard Lowe if (*previous == NULL) {
2911*10d63b7dSRichard Lowe new_prop = append_prop(target, conditional_prop);
2912*10d63b7dSRichard Lowe } else {
2913*10d63b7dSRichard Lowe dummy.prop = NULL;
2914*10d63b7dSRichard Lowe new_prop = append_prop(&dummy, conditional_prop);
2915*10d63b7dSRichard Lowe new_prop->next = *previous;
2916*10d63b7dSRichard Lowe *previous = new_prop;
2917*10d63b7dSRichard Lowe }
2918*10d63b7dSRichard Lowe target->conditional_cnt++;
2919*10d63b7dSRichard Lowe new_prop->body.conditional = conditional->body.conditional;
2920*10d63b7dSRichard Lowe }
2921*10d63b7dSRichard Lowe }
2922*10d63b7dSRichard Lowe
2923*10d63b7dSRichard Lowe /*
2924*10d63b7dSRichard Lowe * set_locals(target, old_locals)
2925*10d63b7dSRichard Lowe *
2926*10d63b7dSRichard Lowe * Sets any conditional macros for the target.
2927*10d63b7dSRichard Lowe * Each target carries a possibly empty set of conditional properties.
2928*10d63b7dSRichard Lowe *
2929*10d63b7dSRichard Lowe * Parameters:
2930*10d63b7dSRichard Lowe * target The target to set conditional macros for
2931*10d63b7dSRichard Lowe * old_locals Space to store old values in
2932*10d63b7dSRichard Lowe *
2933*10d63b7dSRichard Lowe * Global variables used:
2934*10d63b7dSRichard Lowe * debug_level Should we trace activity?
2935*10d63b7dSRichard Lowe * is_conditional We need to preserve this value
2936*10d63b7dSRichard Lowe * recursion_level Used for tracing
2937*10d63b7dSRichard Lowe */
2938*10d63b7dSRichard Lowe void
set_locals(register Name target,register Property old_locals)2939*10d63b7dSRichard Lowe set_locals(register Name target, register Property old_locals)
2940*10d63b7dSRichard Lowe {
2941*10d63b7dSRichard Lowe register Property conditional;
2942*10d63b7dSRichard Lowe register int i;
2943*10d63b7dSRichard Lowe register Boolean saved_conditional_macro_used;
2944*10d63b7dSRichard Lowe Chain cond_name;
2945*10d63b7dSRichard Lowe Chain cond_chain;
2946*10d63b7dSRichard Lowe
2947*10d63b7dSRichard Lowe if (target->dont_activate_cond_values) {
2948*10d63b7dSRichard Lowe return;
2949*10d63b7dSRichard Lowe }
2950*10d63b7dSRichard Lowe
2951*10d63b7dSRichard Lowe saved_conditional_macro_used = conditional_macro_used;
2952*10d63b7dSRichard Lowe
2953*10d63b7dSRichard Lowe /* Scan the list of conditional properties and apply each one */
2954*10d63b7dSRichard Lowe for (conditional = get_prop(target->prop, conditional_prop), i = 0;
2955*10d63b7dSRichard Lowe conditional != NULL;
2956*10d63b7dSRichard Lowe conditional = get_prop(conditional->next, conditional_prop),
2957*10d63b7dSRichard Lowe i++) {
2958*10d63b7dSRichard Lowe /* Save the old value */
2959*10d63b7dSRichard Lowe old_locals[i].body.macro =
2960*10d63b7dSRichard Lowe maybe_append_prop(conditional->body.conditional.name,
2961*10d63b7dSRichard Lowe macro_prop)->body.macro;
2962*10d63b7dSRichard Lowe if (debug_level > 1) {
2963*10d63b7dSRichard Lowe (void) printf(gettext("%*sActivating conditional value: "),
2964*10d63b7dSRichard Lowe recursion_level,
2965*10d63b7dSRichard Lowe "");
2966*10d63b7dSRichard Lowe }
2967*10d63b7dSRichard Lowe /* Set the conditional value. Macros are expanded when the */
2968*10d63b7dSRichard Lowe /* macro is refd as usual */
2969*10d63b7dSRichard Lowe if ((conditional->body.conditional.name != virtual_root) ||
2970*10d63b7dSRichard Lowe (conditional->body.conditional.value != virtual_root)) {
2971*10d63b7dSRichard Lowe (void) SETVAR(conditional->body.conditional.name,
2972*10d63b7dSRichard Lowe conditional->body.conditional.value,
2973*10d63b7dSRichard Lowe (Boolean) conditional->body.conditional.append);
2974*10d63b7dSRichard Lowe }
2975*10d63b7dSRichard Lowe cond_name = ALLOC(Chain);
2976*10d63b7dSRichard Lowe cond_name->name = conditional->body.conditional.name;
2977*10d63b7dSRichard Lowe }
2978*10d63b7dSRichard Lowe /* Put this target on the front of the chain of conditional targets */
2979*10d63b7dSRichard Lowe cond_chain = ALLOC(Chain);
2980*10d63b7dSRichard Lowe cond_chain->name = target;
2981*10d63b7dSRichard Lowe cond_chain->next = conditional_targets;
2982*10d63b7dSRichard Lowe conditional_targets = cond_chain;
2983*10d63b7dSRichard Lowe conditional_macro_used = saved_conditional_macro_used;
2984*10d63b7dSRichard Lowe }
2985*10d63b7dSRichard Lowe
2986*10d63b7dSRichard Lowe /*
2987*10d63b7dSRichard Lowe * reset_locals(target, old_locals, conditional, index)
2988*10d63b7dSRichard Lowe *
2989*10d63b7dSRichard Lowe * Removes any conditional macros for the target.
2990*10d63b7dSRichard Lowe *
2991*10d63b7dSRichard Lowe * Parameters:
2992*10d63b7dSRichard Lowe * target The target we are retoring values for
2993*10d63b7dSRichard Lowe * old_locals The values to restore
2994*10d63b7dSRichard Lowe * conditional The first conditional block for the target
2995*10d63b7dSRichard Lowe * index into the old_locals vector
2996*10d63b7dSRichard Lowe * Global variables used:
2997*10d63b7dSRichard Lowe * debug_level Should we trace activities?
2998*10d63b7dSRichard Lowe * recursion_level Used for tracing
2999*10d63b7dSRichard Lowe */
3000*10d63b7dSRichard Lowe void
reset_locals(register Name target,register Property old_locals,register Property conditional,register int index)3001*10d63b7dSRichard Lowe reset_locals(register Name target, register Property old_locals, register Property conditional, register int index)
3002*10d63b7dSRichard Lowe {
3003*10d63b7dSRichard Lowe register Property this_conditional;
3004*10d63b7dSRichard Lowe Chain cond_chain;
3005*10d63b7dSRichard Lowe
3006*10d63b7dSRichard Lowe if (target->dont_activate_cond_values) {
3007*10d63b7dSRichard Lowe return;
3008*10d63b7dSRichard Lowe }
3009*10d63b7dSRichard Lowe
3010*10d63b7dSRichard Lowe /* Scan the list of conditional properties and restore the old value */
3011*10d63b7dSRichard Lowe /* to each one Reverse the order relative to when we assigned macros */
3012*10d63b7dSRichard Lowe this_conditional = get_prop(conditional->next, conditional_prop);
3013*10d63b7dSRichard Lowe if (this_conditional != NULL) {
3014*10d63b7dSRichard Lowe reset_locals(target, old_locals, this_conditional, index+1);
3015*10d63b7dSRichard Lowe } else {
3016*10d63b7dSRichard Lowe /* Remove conditional target from chain */
3017*10d63b7dSRichard Lowe if (conditional_targets == NULL ||
3018*10d63b7dSRichard Lowe conditional_targets->name != target) {
3019*10d63b7dSRichard Lowe warning(gettext("Internal error: reset target not at head of condtional_targets chain"));
3020*10d63b7dSRichard Lowe } else {
3021*10d63b7dSRichard Lowe cond_chain = conditional_targets->next;
3022*10d63b7dSRichard Lowe retmem_mb((caddr_t) conditional_targets);
3023*10d63b7dSRichard Lowe conditional_targets = cond_chain;
3024*10d63b7dSRichard Lowe }
3025*10d63b7dSRichard Lowe }
3026*10d63b7dSRichard Lowe get_prop(conditional->body.conditional.name->prop,
3027*10d63b7dSRichard Lowe macro_prop)->body.macro = old_locals[index].body.macro;
3028*10d63b7dSRichard Lowe if (conditional->body.conditional.name == virtual_root) {
3029*10d63b7dSRichard Lowe (void) SETVAR(virtual_root, getvar(virtual_root), false);
3030*10d63b7dSRichard Lowe }
3031*10d63b7dSRichard Lowe if (debug_level > 1) {
3032*10d63b7dSRichard Lowe if (old_locals[index].body.macro.value != NULL) {
3033*10d63b7dSRichard Lowe (void) printf(gettext("%*sdeactivating conditional value: %s= %s\n"),
3034*10d63b7dSRichard Lowe recursion_level,
3035*10d63b7dSRichard Lowe "",
3036*10d63b7dSRichard Lowe conditional->body.conditional.name->
3037*10d63b7dSRichard Lowe string_mb,
3038*10d63b7dSRichard Lowe old_locals[index].body.macro.value->
3039*10d63b7dSRichard Lowe string_mb);
3040*10d63b7dSRichard Lowe } else {
3041*10d63b7dSRichard Lowe (void) printf(gettext("%*sdeactivating conditional value: %s =\n"),
3042*10d63b7dSRichard Lowe recursion_level,
3043*10d63b7dSRichard Lowe "",
3044*10d63b7dSRichard Lowe conditional->body.conditional.name->
3045*10d63b7dSRichard Lowe string_mb);
3046*10d63b7dSRichard Lowe }
3047*10d63b7dSRichard Lowe }
3048*10d63b7dSRichard Lowe }
3049*10d63b7dSRichard Lowe
3050*10d63b7dSRichard Lowe /*
3051*10d63b7dSRichard Lowe * check_auto_dependencies(target, auto_count, automatics)
3052*10d63b7dSRichard Lowe *
3053*10d63b7dSRichard Lowe * Returns true if the target now has a dependency
3054*10d63b7dSRichard Lowe * it didn't previously have (saved on automatics).
3055*10d63b7dSRichard Lowe *
3056*10d63b7dSRichard Lowe * Return value:
3057*10d63b7dSRichard Lowe * true if new dependency found
3058*10d63b7dSRichard Lowe *
3059*10d63b7dSRichard Lowe * Parameters:
3060*10d63b7dSRichard Lowe * target Target we check
3061*10d63b7dSRichard Lowe * auto_count Number of old automatic vars
3062*10d63b7dSRichard Lowe * automatics Saved old automatics
3063*10d63b7dSRichard Lowe *
3064*10d63b7dSRichard Lowe * Global variables used:
3065*10d63b7dSRichard Lowe * keep_state Indicates that .KEEP_STATE is on
3066*10d63b7dSRichard Lowe */
3067*10d63b7dSRichard Lowe Boolean
check_auto_dependencies(Name target,int auto_count,Name * automatics)3068*10d63b7dSRichard Lowe check_auto_dependencies(Name target, int auto_count, Name *automatics)
3069*10d63b7dSRichard Lowe {
3070*10d63b7dSRichard Lowe Name *p;
3071*10d63b7dSRichard Lowe int n;
3072*10d63b7dSRichard Lowe Property line;
3073*10d63b7dSRichard Lowe Dependency dependency;
3074*10d63b7dSRichard Lowe
3075*10d63b7dSRichard Lowe if (keep_state) {
3076*10d63b7dSRichard Lowe if ((line = get_prop(target->prop, line_prop)) == NULL) {
3077*10d63b7dSRichard Lowe return false;
3078*10d63b7dSRichard Lowe }
3079*10d63b7dSRichard Lowe /* Go thru new list of automatic depes */
3080*10d63b7dSRichard Lowe for (dependency = line->body.line.dependencies;
3081*10d63b7dSRichard Lowe dependency != NULL;
3082*10d63b7dSRichard Lowe dependency = dependency->next) {
3083*10d63b7dSRichard Lowe /* And make sure that each one existed before we */
3084*10d63b7dSRichard Lowe /* built the target */
3085*10d63b7dSRichard Lowe if (dependency->automatic && !dependency->stale) {
3086*10d63b7dSRichard Lowe for (n = auto_count, p = automatics;
3087*10d63b7dSRichard Lowe n > 0;
3088*10d63b7dSRichard Lowe n--) {
3089*10d63b7dSRichard Lowe if (*p++ == dependency->name) {
3090*10d63b7dSRichard Lowe /* If we can find it on the */
3091*10d63b7dSRichard Lowe /* saved list of autos we */
3092*10d63b7dSRichard Lowe /* are OK */
3093*10d63b7dSRichard Lowe goto not_new;
3094*10d63b7dSRichard Lowe }
3095*10d63b7dSRichard Lowe }
3096*10d63b7dSRichard Lowe /* But if we scan over the old list */
3097*10d63b7dSRichard Lowe /* of auto. without finding it it is */
3098*10d63b7dSRichard Lowe /* new and we must check it */
3099*10d63b7dSRichard Lowe return true;
3100*10d63b7dSRichard Lowe }
3101*10d63b7dSRichard Lowe not_new:;
3102*10d63b7dSRichard Lowe }
3103*10d63b7dSRichard Lowe return false;
3104*10d63b7dSRichard Lowe } else {
3105*10d63b7dSRichard Lowe return false;
3106*10d63b7dSRichard Lowe }
3107*10d63b7dSRichard Lowe }
3108*10d63b7dSRichard Lowe
3109*10d63b7dSRichard Lowe
3110*10d63b7dSRichard Lowe // Recursively delete each of the Chain struct on the chain.
3111*10d63b7dSRichard Lowe
3112*10d63b7dSRichard Lowe static void
delete_query_chain(Chain ch)3113*10d63b7dSRichard Lowe delete_query_chain(Chain ch)
3114*10d63b7dSRichard Lowe {
3115*10d63b7dSRichard Lowe if (ch == NULL) {
3116*10d63b7dSRichard Lowe return;
3117*10d63b7dSRichard Lowe } else {
3118*10d63b7dSRichard Lowe delete_query_chain(ch->next);
3119*10d63b7dSRichard Lowe retmem_mb((char *) ch);
3120*10d63b7dSRichard Lowe }
3121*10d63b7dSRichard Lowe }
3122*10d63b7dSRichard Lowe
3123*10d63b7dSRichard Lowe Doname
target_can_be_built(register Name target)3124*10d63b7dSRichard Lowe target_can_be_built(register Name target) {
3125*10d63b7dSRichard Lowe Doname result = build_dont_know;
3126*10d63b7dSRichard Lowe Name true_target = target;
3127*10d63b7dSRichard Lowe Property line;
3128*10d63b7dSRichard Lowe
3129*10d63b7dSRichard Lowe if (target == wait_name) {
3130*10d63b7dSRichard Lowe return(build_ok);
3131*10d63b7dSRichard Lowe }
3132*10d63b7dSRichard Lowe /*
3133*10d63b7dSRichard Lowe * If the target is a constructed one for a "::" target,
3134*10d63b7dSRichard Lowe * we need to consider that.
3135*10d63b7dSRichard Lowe */
3136*10d63b7dSRichard Lowe if (target->has_target_prop) {
3137*10d63b7dSRichard Lowe true_target = get_prop(target->prop,
3138*10d63b7dSRichard Lowe target_prop)->body.target.target;
3139*10d63b7dSRichard Lowe }
3140*10d63b7dSRichard Lowe
3141*10d63b7dSRichard Lowe (void) exists(true_target);
3142*10d63b7dSRichard Lowe
3143*10d63b7dSRichard Lowe if (true_target->state == build_running) {
3144*10d63b7dSRichard Lowe return(build_running);
3145*10d63b7dSRichard Lowe }
3146*10d63b7dSRichard Lowe if (true_target->stat.time != file_doesnt_exist) {
3147*10d63b7dSRichard Lowe result = build_ok;
3148*10d63b7dSRichard Lowe }
3149*10d63b7dSRichard Lowe
3150*10d63b7dSRichard Lowe /* get line property for the target */
3151*10d63b7dSRichard Lowe line = get_prop(true_target->prop, line_prop);
3152*10d63b7dSRichard Lowe
3153*10d63b7dSRichard Lowe /* first check for explicit rule */
3154*10d63b7dSRichard Lowe if (line != NULL && line->body.line.command_template != NULL) {
3155*10d63b7dSRichard Lowe result = build_ok;
3156*10d63b7dSRichard Lowe }
3157*10d63b7dSRichard Lowe /* try to find pattern rule */
3158*10d63b7dSRichard Lowe if (result == build_dont_know) {
3159*10d63b7dSRichard Lowe result = find_percent_rule(target, NULL, false);
3160*10d63b7dSRichard Lowe }
3161*10d63b7dSRichard Lowe
3162*10d63b7dSRichard Lowe /* try to find double suffix rule */
3163*10d63b7dSRichard Lowe if (result == build_dont_know) {
3164*10d63b7dSRichard Lowe if (target->is_member) {
3165*10d63b7dSRichard Lowe Property member = get_prop(target->prop, member_prop);
3166*10d63b7dSRichard Lowe if (member != NULL && member->body.member.member != NULL) {
3167*10d63b7dSRichard Lowe result = find_ar_suffix_rule(target, member->body.member.member, NULL, false);
3168*10d63b7dSRichard Lowe } else {
3169*10d63b7dSRichard Lowe result = find_double_suffix_rule(target, NULL, false);
3170*10d63b7dSRichard Lowe }
3171*10d63b7dSRichard Lowe } else {
3172*10d63b7dSRichard Lowe result = find_double_suffix_rule(target, NULL, false);
3173*10d63b7dSRichard Lowe }
3174*10d63b7dSRichard Lowe }
3175*10d63b7dSRichard Lowe
3176*10d63b7dSRichard Lowe /* try to find suffix rule */
3177*10d63b7dSRichard Lowe if ((result == build_dont_know) && second_pass) {
3178*10d63b7dSRichard Lowe result = find_suffix_rule(target, target, empty_name, NULL, false);
3179*10d63b7dSRichard Lowe }
3180*10d63b7dSRichard Lowe
3181*10d63b7dSRichard Lowe /* check for sccs */
3182*10d63b7dSRichard Lowe if (result == build_dont_know) {
3183*10d63b7dSRichard Lowe result = sccs_get(target, NULL);
3184*10d63b7dSRichard Lowe }
3185*10d63b7dSRichard Lowe
3186*10d63b7dSRichard Lowe /* try to find dyn target */
3187*10d63b7dSRichard Lowe if (result == build_dont_know) {
3188*10d63b7dSRichard Lowe Name dtarg = find_dyntarget(target);
3189*10d63b7dSRichard Lowe if (dtarg != NULL) {
3190*10d63b7dSRichard Lowe result = target_can_be_built(dtarg);
3191*10d63b7dSRichard Lowe }
3192*10d63b7dSRichard Lowe }
3193*10d63b7dSRichard Lowe
3194*10d63b7dSRichard Lowe /* check whether target was mentioned in makefile */
3195*10d63b7dSRichard Lowe if (result == build_dont_know) {
3196*10d63b7dSRichard Lowe if (target->colons != no_colon) {
3197*10d63b7dSRichard Lowe result = build_ok;
3198*10d63b7dSRichard Lowe }
3199*10d63b7dSRichard Lowe }
3200*10d63b7dSRichard Lowe
3201*10d63b7dSRichard Lowe /* result */
3202*10d63b7dSRichard Lowe return result;
3203*10d63b7dSRichard Lowe }
3204