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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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