110d63b7dSRichard Lowe /*
210d63b7dSRichard Lowe * CDDL HEADER START
310d63b7dSRichard Lowe *
410d63b7dSRichard Lowe * The contents of this file are subject to the terms of the
510d63b7dSRichard Lowe * Common Development and Distribution License (the "License").
610d63b7dSRichard Lowe * You may not use this file except in compliance with the License.
710d63b7dSRichard Lowe *
810d63b7dSRichard Lowe * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
910d63b7dSRichard Lowe * or http://www.opensolaris.org/os/licensing.
1010d63b7dSRichard Lowe * See the License for the specific language governing permissions
1110d63b7dSRichard Lowe * and limitations under the License.
1210d63b7dSRichard Lowe *
1310d63b7dSRichard Lowe * When distributing Covered Code, include this CDDL HEADER in each
1410d63b7dSRichard Lowe * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1510d63b7dSRichard Lowe * If applicable, add the following below this CDDL HEADER, with the
1610d63b7dSRichard Lowe * fields enclosed by brackets "[]" replaced with your own identifying
1710d63b7dSRichard Lowe * information: Portions Copyright [yyyy] [name of copyright owner]
1810d63b7dSRichard Lowe *
1910d63b7dSRichard Lowe * CDDL HEADER END
2010d63b7dSRichard Lowe */
2110d63b7dSRichard Lowe /*
2210d63b7dSRichard Lowe * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
2310d63b7dSRichard Lowe * Use is subject to license terms.
2467c3092cSAndrew Stormont *
2548bbca81SDaniel Hoffman * Copyright (c) 2016 by Delphix. All rights reserved.
268e0c8248SAndrew Stormont * Copyright 2019 RackTop Systems.
2710d63b7dSRichard Lowe */
2810d63b7dSRichard Lowe
2910d63b7dSRichard Lowe /*
3010d63b7dSRichard Lowe * doname.c
3110d63b7dSRichard Lowe *
3210d63b7dSRichard Lowe * Figure out which targets are out of date and rebuild them
3310d63b7dSRichard Lowe */
3410d63b7dSRichard Lowe
3510d63b7dSRichard Lowe /*
3610d63b7dSRichard Lowe * Included files
3710d63b7dSRichard Lowe */
3810d63b7dSRichard Lowe #include <alloca.h> /* alloca() */
3910d63b7dSRichard Lowe #include <fcntl.h>
4010d63b7dSRichard Lowe #include <mk/defs.h>
4110d63b7dSRichard Lowe #include <mksh/i18n.h> /* get_char_semantics_value() */
4210d63b7dSRichard Lowe #include <mksh/macro.h> /* getvar(), expand_value() */
4310d63b7dSRichard Lowe #include <mksh/misc.h> /* getmem() */
4410d63b7dSRichard Lowe #include <poll.h>
4510d63b7dSRichard Lowe #include <libintl.h>
4610d63b7dSRichard Lowe #include <signal.h>
4710d63b7dSRichard Lowe #include <stropts.h>
4810d63b7dSRichard Lowe #include <sys/errno.h>
4910d63b7dSRichard Lowe #include <sys/stat.h>
5010d63b7dSRichard Lowe #include <sys/types.h>
5110d63b7dSRichard Lowe #include <sys/utsname.h> /* uname() */
5210d63b7dSRichard Lowe #include <sys/wait.h>
5310d63b7dSRichard Lowe #include <unistd.h> /* close() */
5410d63b7dSRichard Lowe
5510d63b7dSRichard Lowe /*
5610d63b7dSRichard Lowe * Defined macros
5710d63b7dSRichard Lowe */
5810d63b7dSRichard Lowe # define LOCALHOST "localhost"
5910d63b7dSRichard Lowe
6010d63b7dSRichard Lowe #define MAXRULES 100
6110d63b7dSRichard Lowe
6210d63b7dSRichard Lowe // Sleep for .1 seconds between stat()'s
6310d63b7dSRichard Lowe const int STAT_RETRY_SLEEP_TIME = 100000;
6410d63b7dSRichard Lowe
6510d63b7dSRichard Lowe /*
6610d63b7dSRichard Lowe * typedefs & structs
6710d63b7dSRichard Lowe */
6810d63b7dSRichard Lowe
6910d63b7dSRichard Lowe /*
7010d63b7dSRichard Lowe * Static variables
7110d63b7dSRichard Lowe */
7210d63b7dSRichard Lowe static char hostName[MAXNAMELEN] = "";
7310d63b7dSRichard Lowe static char userName[MAXNAMELEN] = "";
7410d63b7dSRichard Lowe
7510d63b7dSRichard Lowe
7610d63b7dSRichard Lowe static int second_pass = 0;
7710d63b7dSRichard Lowe
7810d63b7dSRichard Lowe /*
7910d63b7dSRichard Lowe * File table of contents
8010d63b7dSRichard Lowe */
81*e7afc443SToomas Soome extern Doname doname_check(Name target, Boolean do_get, Boolean implicit, Boolean automatic);
82*e7afc443SToomas Soome extern Doname doname(Name target, Boolean do_get, Boolean implicit, Boolean automatic);
8310d63b7dSRichard 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);
8410d63b7dSRichard Lowe void dynamic_dependencies(Name target);
85*e7afc443SToomas Soome static Doname run_command(Property line, Boolean print_machine);
8610d63b7dSRichard Lowe extern Doname execute_serial(Property line);
87*e7afc443SToomas Soome extern Name vpath_translation(Name cmd);
8810d63b7dSRichard Lowe extern void check_state(Name temp_file_name);
89*e7afc443SToomas Soome static void read_dependency_file(Name filename);
9010d63b7dSRichard Lowe static void check_read_state_file(void);
91*e7afc443SToomas Soome static void do_assign(Name line, Name target);
92*e7afc443SToomas Soome static void build_command_strings(Name target, Property line);
93*e7afc443SToomas Soome static Doname touch_command(Property line, Name target, Doname result);
9410d63b7dSRichard Lowe extern void update_target(Property line, Doname result);
95*e7afc443SToomas Soome static Doname sccs_get(Name target, Property *command);
96*e7afc443SToomas Soome extern void read_directory_of_file(Name file);
97*e7afc443SToomas Soome static void add_pattern_conditionals(Name target);
98*e7afc443SToomas Soome extern void set_locals(Name target, Property old_locals);
99*e7afc443SToomas Soome extern void reset_locals(Name target, Property old_locals, Property conditional, int index);
10010d63b7dSRichard Lowe extern Boolean check_auto_dependencies(Name target, int auto_count, Name *automatics);
10110d63b7dSRichard Lowe static void delete_query_chain(Chain ch);
10210d63b7dSRichard Lowe
10310d63b7dSRichard Lowe // From read2.cc
104*e7afc443SToomas Soome extern Name normalize_name(wchar_t *name_string, int length);
10510d63b7dSRichard Lowe
10610d63b7dSRichard Lowe
10710d63b7dSRichard Lowe
10810d63b7dSRichard Lowe /*
10910d63b7dSRichard Lowe * DONE.
11010d63b7dSRichard Lowe *
11110d63b7dSRichard Lowe * doname_check(target, do_get, implicit, automatic)
11210d63b7dSRichard Lowe *
11310d63b7dSRichard Lowe * Will call doname() and then inspect the return value
11410d63b7dSRichard Lowe *
11510d63b7dSRichard Lowe * Return value:
11610d63b7dSRichard Lowe * Indication if the build failed or not
11710d63b7dSRichard Lowe *
11810d63b7dSRichard Lowe * Parameters:
11910d63b7dSRichard Lowe * target The target to build
12010d63b7dSRichard Lowe * do_get Passed thru to doname()
12110d63b7dSRichard Lowe * implicit Passed thru to doname()
12210d63b7dSRichard Lowe * automatic Are we building a hidden dependency?
12310d63b7dSRichard Lowe *
12410d63b7dSRichard Lowe * Global variables used:
12510d63b7dSRichard Lowe * build_failed_seen Set if -k is on and error occurs
12610d63b7dSRichard Lowe * continue_after_error Indicates that -k is on
12710d63b7dSRichard Lowe * report_dependencies No error msg if -P is on
12810d63b7dSRichard Lowe */
12910d63b7dSRichard Lowe Doname
doname_check(Name target,Boolean do_get,Boolean implicit,Boolean automatic)130*e7afc443SToomas Soome doname_check(Name target, Boolean do_get, Boolean implicit, Boolean automatic)
13110d63b7dSRichard Lowe {
13210d63b7dSRichard Lowe int first_time = 1;
1332e8f3c34SToomas Soome Doname rv = build_failed;
1342e8f3c34SToomas Soome
13510d63b7dSRichard Lowe (void) fflush(stdout);
13610d63b7dSRichard Lowe try_again:
13710d63b7dSRichard Lowe switch (doname(target, do_get, implicit, automatic)) {
13810d63b7dSRichard Lowe case build_ok:
13910d63b7dSRichard Lowe second_pass = 0;
1402e8f3c34SToomas Soome rv = build_ok;
1412e8f3c34SToomas Soome break;
14210d63b7dSRichard Lowe case build_running:
14310d63b7dSRichard Lowe second_pass = 0;
1442e8f3c34SToomas Soome rv = build_running;
1452e8f3c34SToomas Soome break;
14610d63b7dSRichard Lowe case build_failed:
14710d63b7dSRichard Lowe if (!continue_after_error) {
1482e8f3c34SToomas Soome fatal(
1492e8f3c34SToomas Soome gettext("Target `%s' not remade because of errors"),
1502e8f3c34SToomas Soome target->string_mb);
15110d63b7dSRichard Lowe }
15210d63b7dSRichard Lowe build_failed_seen = true;
15310d63b7dSRichard Lowe second_pass = 0;
1542e8f3c34SToomas Soome rv = build_failed;
1552e8f3c34SToomas Soome break;
15610d63b7dSRichard Lowe case build_dont_know:
15710d63b7dSRichard Lowe /*
15810d63b7dSRichard Lowe * If we can't figure out how to build an automatic
15910d63b7dSRichard Lowe * (hidden) dependency, we just ignore it.
16010d63b7dSRichard Lowe * We later declare the target to be out of date just in
16110d63b7dSRichard Lowe * case something changed.
16210d63b7dSRichard Lowe * Also, don't complain if just reporting the dependencies
16310d63b7dSRichard Lowe * and not building anything.
16410d63b7dSRichard Lowe */
16510d63b7dSRichard Lowe if (automatic || (report_dependencies_level > 0)) {
16610d63b7dSRichard Lowe second_pass = 0;
1672e8f3c34SToomas Soome rv = build_dont_know;
1682e8f3c34SToomas Soome break;
16910d63b7dSRichard Lowe }
17010d63b7dSRichard Lowe if(first_time) {
17110d63b7dSRichard Lowe first_time = 0;
17210d63b7dSRichard Lowe second_pass = 1;
17310d63b7dSRichard Lowe goto try_again;
17410d63b7dSRichard Lowe }
17510d63b7dSRichard Lowe second_pass = 0;
17610d63b7dSRichard Lowe if (continue_after_error && !svr4) {
17710d63b7dSRichard Lowe warning(gettext("Don't know how to make target `%s'"),
17810d63b7dSRichard Lowe target->string_mb);
17910d63b7dSRichard Lowe build_failed_seen = true;
1802e8f3c34SToomas Soome rv = build_failed;
1812e8f3c34SToomas Soome break;
18210d63b7dSRichard Lowe }
1832e8f3c34SToomas Soome fatal(gettext("Don't know how to make target `%s'"),
1842e8f3c34SToomas Soome target->string_mb);
18510d63b7dSRichard Lowe break;
18610d63b7dSRichard Lowe }
1872e8f3c34SToomas Soome return (rv);
18810d63b7dSRichard Lowe }
18910d63b7dSRichard Lowe
19010d63b7dSRichard Lowe
19110d63b7dSRichard Lowe void
enter_explicit_rule_from_dynamic_rule(Name target,Name source)19210d63b7dSRichard Lowe enter_explicit_rule_from_dynamic_rule(Name target, Name source)
19310d63b7dSRichard Lowe {
19410d63b7dSRichard Lowe Property line, source_line;
19510d63b7dSRichard Lowe Dependency dependency;
19610d63b7dSRichard Lowe
19710d63b7dSRichard Lowe source_line = get_prop(source->prop, line_prop);
19810d63b7dSRichard Lowe line = maybe_append_prop(target, line_prop);
19910d63b7dSRichard Lowe line->body.line.sccs_command = false;
20010d63b7dSRichard Lowe line->body.line.target = target;
20110d63b7dSRichard Lowe if (line->body.line.command_template == NULL) {
20210d63b7dSRichard Lowe line->body.line.command_template = source_line->body.line.command_template;
20310d63b7dSRichard Lowe for (dependency = source_line->body.line.dependencies;
20410d63b7dSRichard Lowe dependency != NULL;
20510d63b7dSRichard Lowe dependency = dependency->next) {
20610d63b7dSRichard Lowe enter_dependency(line, dependency->name, false);
20710d63b7dSRichard Lowe }
20810d63b7dSRichard Lowe line->body.line.less = target;
20910d63b7dSRichard Lowe }
21010d63b7dSRichard Lowe line->body.line.percent = NULL;
21110d63b7dSRichard Lowe }
21210d63b7dSRichard Lowe
21310d63b7dSRichard Lowe
21410d63b7dSRichard Lowe
21510d63b7dSRichard Lowe Name
find_dyntarget(Name target)21610d63b7dSRichard Lowe find_dyntarget(Name target)
21710d63b7dSRichard Lowe {
21810d63b7dSRichard Lowe Dyntarget p;
21910d63b7dSRichard Lowe int i;
22010d63b7dSRichard Lowe String_rec string;
22110d63b7dSRichard Lowe wchar_t buffer[STRING_BUFFER_LENGTH];
22210d63b7dSRichard Lowe wchar_t *pp, * bufend;
22310d63b7dSRichard Lowe wchar_t tbuffer[MAXPATHLEN];
22410d63b7dSRichard Lowe Wstring wcb(target);
22510d63b7dSRichard Lowe
22610d63b7dSRichard Lowe for (p = dyntarget_list; p != NULL; p = p->next) {
22710d63b7dSRichard Lowe INIT_STRING_FROM_STACK(string, buffer);
22810d63b7dSRichard Lowe expand_value(p->name, &string, false);
22910d63b7dSRichard Lowe i = 0;
23010d63b7dSRichard Lowe pp = string.buffer.start;
23110d63b7dSRichard Lowe bufend = pp + STRING_BUFFER_LENGTH;
23210d63b7dSRichard Lowe while((*pp != nul_char) && (pp < bufend)) {
23310d63b7dSRichard Lowe if(iswspace(*pp)) {
23410d63b7dSRichard Lowe tbuffer[i] = nul_char;
23510d63b7dSRichard Lowe if(i > 0) {
23610d63b7dSRichard Lowe if (wcb.equal(tbuffer)) {
23710d63b7dSRichard Lowe enter_explicit_rule_from_dynamic_rule(target, p->name);
23810d63b7dSRichard Lowe return(target);
23910d63b7dSRichard Lowe }
24010d63b7dSRichard Lowe }
24110d63b7dSRichard Lowe pp++;
24210d63b7dSRichard Lowe i = 0;
24310d63b7dSRichard Lowe continue;
24410d63b7dSRichard Lowe }
24510d63b7dSRichard Lowe tbuffer[i] = *pp;
24610d63b7dSRichard Lowe i++;
24710d63b7dSRichard Lowe pp++;
24810d63b7dSRichard Lowe if(*pp == nul_char) {
24910d63b7dSRichard Lowe tbuffer[i] = nul_char;
25010d63b7dSRichard Lowe if(i > 0) {
25110d63b7dSRichard Lowe if (wcb.equal(tbuffer)) {
25210d63b7dSRichard Lowe enter_explicit_rule_from_dynamic_rule(target, p->name);
25310d63b7dSRichard Lowe return(target);
25410d63b7dSRichard Lowe }
25510d63b7dSRichard Lowe }
25610d63b7dSRichard Lowe break;
25710d63b7dSRichard Lowe }
25810d63b7dSRichard Lowe }
25910d63b7dSRichard Lowe }
26010d63b7dSRichard Lowe return(NULL);
26110d63b7dSRichard Lowe }
26210d63b7dSRichard Lowe
26310d63b7dSRichard Lowe /*
26410d63b7dSRichard Lowe * DONE.
26510d63b7dSRichard Lowe *
26610d63b7dSRichard Lowe * doname(target, do_get, implicit)
26710d63b7dSRichard Lowe *
26810d63b7dSRichard Lowe * Chases all files the target depends on and builds any that
26910d63b7dSRichard Lowe * are out of date. If the target is out of date it is then rebuilt.
27010d63b7dSRichard Lowe *
27110d63b7dSRichard Lowe * Return value:
27210d63b7dSRichard Lowe * Indiates if build failed or nt
27310d63b7dSRichard Lowe *
27410d63b7dSRichard Lowe * Parameters:
27510d63b7dSRichard Lowe * target Target to build
27610d63b7dSRichard Lowe * do_get Run sccs get is nessecary
27710d63b7dSRichard Lowe * implicit doname is trying to find an implicit rule
27810d63b7dSRichard Lowe *
27910d63b7dSRichard Lowe * Global variables used:
28010d63b7dSRichard Lowe * assign_done True if command line assgnment has happened
28110d63b7dSRichard Lowe * commands_done Preserved for the case that we need local value
28210d63b7dSRichard Lowe * debug_level Should we trace make's actions?
28310d63b7dSRichard Lowe * default_rule The rule for ".DEFAULT", used as last resort
28410d63b7dSRichard Lowe * empty_name The Name "", used when looking for single sfx
28510d63b7dSRichard Lowe * keep_state Indicates that .KEEP_STATE is on
28610d63b7dSRichard Lowe * parallel True if building in parallel
28710d63b7dSRichard Lowe * recursion_level Used for tracing
28810d63b7dSRichard Lowe * report_dependencies make -P is on
28910d63b7dSRichard Lowe */
29010d63b7dSRichard Lowe Doname
doname(Name target,Boolean do_get,Boolean implicit,Boolean automatic)291*e7afc443SToomas Soome doname(Name target, Boolean do_get, Boolean implicit, Boolean automatic)
29210d63b7dSRichard Lowe {
29310d63b7dSRichard Lowe Doname result = build_dont_know;
29410d63b7dSRichard Lowe Chain out_of_date_list = NULL;
29510d63b7dSRichard Lowe Chain target_group;
29610d63b7dSRichard Lowe Property old_locals = NULL;
297*e7afc443SToomas Soome Property line;
29810d63b7dSRichard Lowe Property command = NULL;
299*e7afc443SToomas Soome Dependency dependency;
30010d63b7dSRichard Lowe Name less = NULL;
30110d63b7dSRichard Lowe Name true_target = target;
30210d63b7dSRichard Lowe Name *automatics = NULL;
303*e7afc443SToomas Soome int auto_count;
30410d63b7dSRichard Lowe Boolean rechecking_target = false;
30510d63b7dSRichard Lowe Boolean saved_commands_done;
30610d63b7dSRichard Lowe Boolean restart = false;
30710d63b7dSRichard Lowe Boolean save_parallel = parallel;
30810d63b7dSRichard Lowe Boolean doing_subtree = false;
30910d63b7dSRichard Lowe
31010d63b7dSRichard Lowe Boolean recheck_conditionals = false;
31110d63b7dSRichard Lowe
31210d63b7dSRichard Lowe if (target->state == build_running) {
31310d63b7dSRichard Lowe return build_running;
31410d63b7dSRichard Lowe }
31510d63b7dSRichard Lowe line = get_prop(target->prop, line_prop);
31610d63b7dSRichard Lowe if (line != NULL) {
31710d63b7dSRichard Lowe /*
31810d63b7dSRichard Lowe * If this target is a member of target group and one of the
31910d63b7dSRichard Lowe * other members of the group is running, mark this target
32010d63b7dSRichard Lowe * as running.
32110d63b7dSRichard Lowe */
32210d63b7dSRichard Lowe for (target_group = line->body.line.target_group;
32310d63b7dSRichard Lowe target_group != NULL;
32410d63b7dSRichard Lowe target_group = target_group->next) {
32510d63b7dSRichard Lowe if (is_running(target_group->name)) {
32610d63b7dSRichard Lowe target->state = build_running;
32710d63b7dSRichard Lowe add_pending(target,
32810d63b7dSRichard Lowe recursion_level,
32910d63b7dSRichard Lowe do_get,
33010d63b7dSRichard Lowe implicit,
33110d63b7dSRichard Lowe false);
33210d63b7dSRichard Lowe return build_running;
33310d63b7dSRichard Lowe }
33410d63b7dSRichard Lowe }
33510d63b7dSRichard Lowe }
33610d63b7dSRichard Lowe /*
33710d63b7dSRichard Lowe * If the target is a constructed one for a "::" target,
33810d63b7dSRichard Lowe * we need to consider that.
33910d63b7dSRichard Lowe */
34010d63b7dSRichard Lowe if (target->has_target_prop) {
34110d63b7dSRichard Lowe true_target = get_prop(target->prop,
34210d63b7dSRichard Lowe target_prop)->body.target.target;
34310d63b7dSRichard Lowe if (true_target->colon_splits > 0) {
34410d63b7dSRichard Lowe /* Make sure we have a valid time for :: targets */
34510d63b7dSRichard Lowe Property time;
34610d63b7dSRichard Lowe
34710d63b7dSRichard Lowe time = get_prop(true_target->prop, time_prop);
34810d63b7dSRichard Lowe if (time != NULL) {
34910d63b7dSRichard Lowe true_target->stat.time = time->body.time.time;
35010d63b7dSRichard Lowe }
35110d63b7dSRichard Lowe }
35210d63b7dSRichard Lowe }
35310d63b7dSRichard Lowe (void) exists(true_target);
35410d63b7dSRichard Lowe /*
35510d63b7dSRichard Lowe * If the target has been processed, we don't need to do it again,
35610d63b7dSRichard Lowe * unless it depends on conditional macros or a delayed assignment,
35710d63b7dSRichard Lowe * or it has been done when KEEP_STATE is on.
35810d63b7dSRichard Lowe */
35910d63b7dSRichard Lowe if (target->state == build_ok) {
36010d63b7dSRichard Lowe if((!keep_state || (!target->depends_on_conditional && !assign_done))) {
36110d63b7dSRichard Lowe return build_ok;
36210d63b7dSRichard Lowe } else {
36310d63b7dSRichard Lowe recheck_conditionals = true;
36410d63b7dSRichard Lowe }
3652e8f3c34SToomas Soome }
36610d63b7dSRichard Lowe if (target->state == build_subtree) {
36710d63b7dSRichard Lowe /* A dynamic macro subtree is being built */
36810d63b7dSRichard Lowe target->state = build_dont_know;
36910d63b7dSRichard Lowe doing_subtree = true;
37010d63b7dSRichard Lowe if (!target->checking_subtree) {
37110d63b7dSRichard Lowe /*
37210d63b7dSRichard Lowe * This target has been started before and therefore
37310d63b7dSRichard Lowe * not all dependencies have to be built.
37410d63b7dSRichard Lowe */
37510d63b7dSRichard Lowe restart = true;
37610d63b7dSRichard Lowe }
37710d63b7dSRichard Lowe } else if (target->state == build_pending) {
37810d63b7dSRichard Lowe target->state = build_dont_know;
37910d63b7dSRichard Lowe restart = true;
38010d63b7dSRichard Lowe /*
38110d63b7dSRichard Lowe } else if (parallel &&
38210d63b7dSRichard Lowe keep_state &&
38310d63b7dSRichard Lowe (target->conditional_cnt > 0)) {
38410d63b7dSRichard Lowe if (!parallel_ok(target, false)) {
38510d63b7dSRichard Lowe add_subtree(target, recursion_level, do_get, implicit);
38610d63b7dSRichard Lowe target->state = build_running;
38710d63b7dSRichard Lowe return build_running;
38810d63b7dSRichard Lowe }
38910d63b7dSRichard Lowe */
39010d63b7dSRichard Lowe }
39110d63b7dSRichard Lowe /*
39210d63b7dSRichard Lowe * If KEEP_STATE is on, we have to rebuild the target if the
39310d63b7dSRichard Lowe * building of it caused new automatic dependencies to be reported.
39410d63b7dSRichard Lowe * This is where we restart the build.
39510d63b7dSRichard Lowe */
39610d63b7dSRichard Lowe if (line != NULL) {
39710d63b7dSRichard Lowe line->body.line.percent = NULL;
39810d63b7dSRichard Lowe }
39910d63b7dSRichard Lowe recheck_target:
40010d63b7dSRichard Lowe /* Init all local variables */
40110d63b7dSRichard Lowe result = build_dont_know;
40210d63b7dSRichard Lowe out_of_date_list = NULL;
40310d63b7dSRichard Lowe command = NULL;
40410d63b7dSRichard Lowe less = NULL;
40510d63b7dSRichard Lowe auto_count = 0;
40610d63b7dSRichard Lowe if (!restart && line != NULL) {
40710d63b7dSRichard Lowe /*
40810d63b7dSRichard Lowe * If this target has never been built before, mark all
40910d63b7dSRichard Lowe * of the dependencies as never built.
41010d63b7dSRichard Lowe */
41110d63b7dSRichard Lowe for (dependency = line->body.line.dependencies;
41210d63b7dSRichard Lowe dependency != NULL;
41310d63b7dSRichard Lowe dependency = dependency->next) {
41410d63b7dSRichard Lowe dependency->built = false;
41510d63b7dSRichard Lowe }
41610d63b7dSRichard Lowe }
41710d63b7dSRichard Lowe /* Save the set of automatic depes defined for this target */
41810d63b7dSRichard Lowe if (keep_state &&
41910d63b7dSRichard Lowe (line != NULL) &&
42010d63b7dSRichard Lowe (line->body.line.dependencies != NULL)) {
42110d63b7dSRichard Lowe Name *p;
42210d63b7dSRichard Lowe
42310d63b7dSRichard Lowe /*
42410d63b7dSRichard Lowe * First run thru the dependency list to see how many
42510d63b7dSRichard Lowe * autos there are.
42610d63b7dSRichard Lowe */
42710d63b7dSRichard Lowe for (dependency = line->body.line.dependencies;
42810d63b7dSRichard Lowe dependency != NULL;
42910d63b7dSRichard Lowe dependency = dependency->next) {
43010d63b7dSRichard Lowe if (dependency->automatic && !dependency->stale) {
43110d63b7dSRichard Lowe auto_count++;
43210d63b7dSRichard Lowe }
43310d63b7dSRichard Lowe }
43410d63b7dSRichard Lowe /* Create vector to hold the current autos */
43510d63b7dSRichard Lowe automatics =
43610d63b7dSRichard Lowe (Name *) alloca((int) (auto_count * sizeof (Name)));
43710d63b7dSRichard Lowe /* Copy them */
43810d63b7dSRichard Lowe for (p = automatics, dependency = line->body.line.dependencies;
43910d63b7dSRichard Lowe dependency != NULL;
44010d63b7dSRichard Lowe dependency = dependency->next) {
44110d63b7dSRichard Lowe if (dependency->automatic && !dependency->stale) {
44210d63b7dSRichard Lowe *p++ = dependency->name;
44310d63b7dSRichard Lowe }
44410d63b7dSRichard Lowe }
44510d63b7dSRichard Lowe }
44610d63b7dSRichard Lowe if (debug_level > 1) {
44710d63b7dSRichard Lowe (void) printf("%*sdoname(%s)\n",
44810d63b7dSRichard Lowe recursion_level,
44910d63b7dSRichard Lowe "",
45010d63b7dSRichard Lowe target->string_mb);
45110d63b7dSRichard Lowe }
45210d63b7dSRichard Lowe recursion_level++;
45310d63b7dSRichard Lowe /* Avoid infinite loops */
45410d63b7dSRichard Lowe if (target->state == build_in_progress) {
45510d63b7dSRichard Lowe warning(gettext("Infinite loop: Target `%s' depends on itself"),
45610d63b7dSRichard Lowe target->string_mb);
45710d63b7dSRichard Lowe return build_ok;
45810d63b7dSRichard Lowe }
45910d63b7dSRichard Lowe target->state = build_in_progress;
46010d63b7dSRichard Lowe
46110d63b7dSRichard Lowe /* Activate conditional macros for the target */
46210d63b7dSRichard Lowe if (!target->added_pattern_conditionals) {
46310d63b7dSRichard Lowe add_pattern_conditionals(target);
46410d63b7dSRichard Lowe target->added_pattern_conditionals = true;
46510d63b7dSRichard Lowe }
46610d63b7dSRichard Lowe if (target->conditional_cnt > 0) {
46710d63b7dSRichard Lowe old_locals = (Property) alloca(target->conditional_cnt *
46810d63b7dSRichard Lowe sizeof (Property_rec));
46910d63b7dSRichard Lowe set_locals(target, old_locals);
47010d63b7dSRichard Lowe }
47110d63b7dSRichard Lowe
47210d63b7dSRichard Lowe /*
47310d63b7dSRichard Lowe * after making the call to dynamic_dependecies unconditional we can handle
47448bbca81SDaniel Hoffman * target names that are same as file name. In this case $$@ in the
47510d63b7dSRichard Lowe * dependencies did not mean anything. WIth this change it expands it
47610d63b7dSRichard Lowe * as expected.
47710d63b7dSRichard Lowe */
47810d63b7dSRichard Lowe if (!target->has_depe_list_expanded)
47910d63b7dSRichard Lowe {
48010d63b7dSRichard Lowe dynamic_dependencies(target);
48110d63b7dSRichard Lowe }
48210d63b7dSRichard Lowe
48310d63b7dSRichard Lowe /*
48410d63b7dSRichard Lowe * FIRST SECTION -- GO THROUGH DEPENDENCIES AND COLLECT EXPLICIT
48510d63b7dSRichard Lowe * COMMANDS TO RUN
48610d63b7dSRichard Lowe */
48710d63b7dSRichard Lowe if ((line = get_prop(target->prop, line_prop)) != NULL) {
48810d63b7dSRichard Lowe if (check_dependencies(&result,
48910d63b7dSRichard Lowe line,
49010d63b7dSRichard Lowe do_get,
49110d63b7dSRichard Lowe target,
49210d63b7dSRichard Lowe true_target,
49310d63b7dSRichard Lowe doing_subtree,
49410d63b7dSRichard Lowe &out_of_date_list,
49510d63b7dSRichard Lowe old_locals,
49610d63b7dSRichard Lowe implicit,
49710d63b7dSRichard Lowe &command,
49810d63b7dSRichard Lowe less,
49910d63b7dSRichard Lowe rechecking_target,
50010d63b7dSRichard Lowe recheck_conditionals)) {
50110d63b7dSRichard Lowe return build_running;
50210d63b7dSRichard Lowe }
50310d63b7dSRichard Lowe if (line->body.line.query != NULL) {
50410d63b7dSRichard Lowe delete_query_chain(line->body.line.query);
50510d63b7dSRichard Lowe }
50610d63b7dSRichard Lowe line->body.line.query = out_of_date_list;
50710d63b7dSRichard Lowe }
50810d63b7dSRichard Lowe
50910d63b7dSRichard Lowe
51010d63b7dSRichard Lowe /*
51110d63b7dSRichard Lowe * If the target is a :: type, do not try to find the rule for the target,
51210d63b7dSRichard Lowe * all actions will be taken by separate branches.
51310d63b7dSRichard Lowe * Else, we try to find an implicit rule using various methods,
51410d63b7dSRichard Lowe * we quit as soon as one is found.
51510d63b7dSRichard Lowe *
51610d63b7dSRichard Lowe * [tolik, 12 Sep 2002] Do not try to find implicit rule for the target
51710d63b7dSRichard Lowe * being rechecked - the target is being rechecked means that it already
51810d63b7dSRichard Lowe * has explicit dependencies derived from an implicit rule found
51910d63b7dSRichard Lowe * in previous step.
52010d63b7dSRichard Lowe */
52110d63b7dSRichard Lowe if (target->colon_splits == 0 && !rechecking_target) {
52210d63b7dSRichard Lowe /* Look for percent matched rule */
52310d63b7dSRichard Lowe if ((result == build_dont_know) &&
52410d63b7dSRichard Lowe (command == NULL)) {
52510d63b7dSRichard Lowe switch (find_percent_rule(
52610d63b7dSRichard Lowe target,
52710d63b7dSRichard Lowe &command,
52810d63b7dSRichard Lowe recheck_conditionals)) {
52910d63b7dSRichard Lowe case build_failed:
53010d63b7dSRichard Lowe result = build_failed;
53110d63b7dSRichard Lowe break;
53210d63b7dSRichard Lowe case build_running:
53310d63b7dSRichard Lowe target->state = build_running;
53410d63b7dSRichard Lowe add_pending(target,
53510d63b7dSRichard Lowe --recursion_level,
53610d63b7dSRichard Lowe do_get,
53710d63b7dSRichard Lowe implicit,
53810d63b7dSRichard Lowe false);
53910d63b7dSRichard Lowe if (target->conditional_cnt > 0) {
54010d63b7dSRichard Lowe reset_locals(target,
54110d63b7dSRichard Lowe old_locals,
54210d63b7dSRichard Lowe get_prop(target->prop,
54310d63b7dSRichard Lowe conditional_prop),
54410d63b7dSRichard Lowe 0);
54510d63b7dSRichard Lowe }
54610d63b7dSRichard Lowe return build_running;
54710d63b7dSRichard Lowe case build_ok:
54810d63b7dSRichard Lowe result = build_ok;
54910d63b7dSRichard Lowe break;
55010d63b7dSRichard Lowe }
55110d63b7dSRichard Lowe }
55210d63b7dSRichard Lowe /* Look for double suffix rule */
55310d63b7dSRichard Lowe if (result == build_dont_know) {
55410d63b7dSRichard Lowe Property member;
55510d63b7dSRichard Lowe
55610d63b7dSRichard Lowe if (target->is_member &&
55710d63b7dSRichard Lowe ((member = get_prop(target->prop, member_prop)) !=
55810d63b7dSRichard Lowe NULL)) {
55910d63b7dSRichard Lowe switch (find_ar_suffix_rule(target,
56010d63b7dSRichard Lowe member->body.
56110d63b7dSRichard Lowe member.member,
56210d63b7dSRichard Lowe &command,
56310d63b7dSRichard Lowe recheck_conditionals)) {
56410d63b7dSRichard Lowe case build_failed:
56510d63b7dSRichard Lowe result = build_failed;
56610d63b7dSRichard Lowe break;
56710d63b7dSRichard Lowe case build_running:
56810d63b7dSRichard Lowe target->state = build_running;
56910d63b7dSRichard Lowe add_pending(target,
57010d63b7dSRichard Lowe --recursion_level,
57110d63b7dSRichard Lowe do_get,
57210d63b7dSRichard Lowe implicit,
57310d63b7dSRichard Lowe false);
57410d63b7dSRichard Lowe if (target->conditional_cnt > 0) {
57510d63b7dSRichard Lowe reset_locals(target,
57610d63b7dSRichard Lowe old_locals,
57710d63b7dSRichard Lowe get_prop(target->prop,
57810d63b7dSRichard Lowe conditional_prop),
57910d63b7dSRichard Lowe 0);
58010d63b7dSRichard Lowe }
58110d63b7dSRichard Lowe return build_running;
58210d63b7dSRichard Lowe default:
58310d63b7dSRichard Lowe /* ALWAYS bind $% for old style */
58410d63b7dSRichard Lowe /* ar rules */
58510d63b7dSRichard Lowe if (line == NULL) {
58610d63b7dSRichard Lowe line =
58710d63b7dSRichard Lowe maybe_append_prop(target,
58810d63b7dSRichard Lowe line_prop);
58910d63b7dSRichard Lowe }
59010d63b7dSRichard Lowe line->body.line.percent =
59110d63b7dSRichard Lowe member->body.member.member;
59210d63b7dSRichard Lowe break;
59310d63b7dSRichard Lowe }
59410d63b7dSRichard Lowe } else {
59510d63b7dSRichard Lowe switch (find_double_suffix_rule(target,
59610d63b7dSRichard Lowe &command,
59710d63b7dSRichard Lowe recheck_conditionals)) {
59810d63b7dSRichard Lowe case build_failed:
59910d63b7dSRichard Lowe result = build_failed;
60010d63b7dSRichard Lowe break;
60110d63b7dSRichard Lowe case build_running:
60210d63b7dSRichard Lowe target->state = build_running;
60310d63b7dSRichard Lowe add_pending(target,
60410d63b7dSRichard Lowe --recursion_level,
60510d63b7dSRichard Lowe do_get,
60610d63b7dSRichard Lowe implicit,
60710d63b7dSRichard Lowe false);
60810d63b7dSRichard Lowe if (target->conditional_cnt > 0) {
60910d63b7dSRichard Lowe reset_locals(target,
61010d63b7dSRichard Lowe old_locals,
61110d63b7dSRichard Lowe get_prop(target->
61210d63b7dSRichard Lowe prop,
61310d63b7dSRichard Lowe conditional_prop),
61410d63b7dSRichard Lowe 0);
61510d63b7dSRichard Lowe }
61610d63b7dSRichard Lowe return build_running;
61710d63b7dSRichard Lowe }
61810d63b7dSRichard Lowe }
61910d63b7dSRichard Lowe }
62010d63b7dSRichard Lowe /* Look for single suffix rule */
62110d63b7dSRichard Lowe
62210d63b7dSRichard Lowe /* /tolik/
62310d63b7dSRichard Lowe * I commented !implicit to fix bug 1247448: Suffix Rules failed when combine with Pattern Matching Rules.
62410d63b7dSRichard Lowe * This caused problem with SVR4 tilde rules (infinite recursion). So I made some changes in "implicit.cc"
62510d63b7dSRichard Lowe */
62610d63b7dSRichard Lowe /* /tolik, 06.21.96/
62710d63b7dSRichard Lowe * Regression! See BugId 1255360
62810d63b7dSRichard Lowe * If more than one percent rules are defined for the same target then
62910d63b7dSRichard Lowe * the behaviour of 'make' with my previous fix may be different from one
63048bbca81SDaniel Hoffman * of the 'old make'.
63110d63b7dSRichard Lowe * The global variable second_pass (maybe it should be an argument to doname())
63210d63b7dSRichard Lowe * is intended to avoid this regression. It is set in doname_check().
63310d63b7dSRichard Lowe * First, 'make' will work as it worked before. Only when it is
63410d63b7dSRichard Lowe * going to say "don't know how to make target" it sets second_pass to true and
63510d63b7dSRichard Lowe * run 'doname' again but now trying to use Single Suffix Rules.
63610d63b7dSRichard Lowe */
63710d63b7dSRichard Lowe if ((result == build_dont_know) && !automatic && (!implicit || second_pass) &&
63810d63b7dSRichard Lowe ((line == NULL) ||
63910d63b7dSRichard Lowe ((line->body.line.target != NULL) &&
64010d63b7dSRichard Lowe !line->body.line.target->has_regular_dependency))) {
64110d63b7dSRichard Lowe switch (find_suffix_rule(target,
64210d63b7dSRichard Lowe target,
64310d63b7dSRichard Lowe empty_name,
64410d63b7dSRichard Lowe &command,
64510d63b7dSRichard Lowe recheck_conditionals)) {
64610d63b7dSRichard Lowe case build_failed:
64710d63b7dSRichard Lowe result = build_failed;
64810d63b7dSRichard Lowe break;
64910d63b7dSRichard Lowe case build_running:
65010d63b7dSRichard Lowe target->state = build_running;
65110d63b7dSRichard Lowe add_pending(target,
65210d63b7dSRichard Lowe --recursion_level,
65310d63b7dSRichard Lowe do_get,
65410d63b7dSRichard Lowe implicit,
65510d63b7dSRichard Lowe false);
65610d63b7dSRichard Lowe if (target->conditional_cnt > 0) {
65710d63b7dSRichard Lowe reset_locals(target,
65810d63b7dSRichard Lowe old_locals,
65910d63b7dSRichard Lowe get_prop(target->prop,
66010d63b7dSRichard Lowe conditional_prop),
66110d63b7dSRichard Lowe 0);
66210d63b7dSRichard Lowe }
66310d63b7dSRichard Lowe return build_running;
66410d63b7dSRichard Lowe }
66510d63b7dSRichard Lowe }
66610d63b7dSRichard Lowe /* Try to sccs get */
66710d63b7dSRichard Lowe if ((command == NULL) &&
66810d63b7dSRichard Lowe (result == build_dont_know) &&
66910d63b7dSRichard Lowe do_get) {
67010d63b7dSRichard Lowe result = sccs_get(target, &command);
67110d63b7dSRichard Lowe }
67210d63b7dSRichard Lowe
67310d63b7dSRichard Lowe /* Use .DEFAULT rule if it is defined. */
67410d63b7dSRichard Lowe if ((command == NULL) &&
67510d63b7dSRichard Lowe (result == build_dont_know) &&
67610d63b7dSRichard Lowe (true_target->colons == no_colon) &&
67710d63b7dSRichard Lowe default_rule &&
67810d63b7dSRichard Lowe !implicit) {
67910d63b7dSRichard Lowe /* Make sure we have a line prop */
68010d63b7dSRichard Lowe line = maybe_append_prop(target, line_prop);
68110d63b7dSRichard Lowe command = line;
68210d63b7dSRichard Lowe Boolean out_of_date;
68310d63b7dSRichard Lowe if (true_target->is_member) {
68410d63b7dSRichard Lowe out_of_date = (Boolean) OUT_OF_DATE_SEC(true_target->stat.time,
68510d63b7dSRichard Lowe line->body.line.dependency_time);
68610d63b7dSRichard Lowe } else {
68710d63b7dSRichard Lowe out_of_date = (Boolean) OUT_OF_DATE(true_target->stat.time,
68810d63b7dSRichard Lowe line->body.line.dependency_time);
68910d63b7dSRichard Lowe }
69010d63b7dSRichard Lowe if (build_unconditional || out_of_date) {
69110d63b7dSRichard Lowe line->body.line.is_out_of_date = true;
69210d63b7dSRichard Lowe if (debug_level > 0) {
69310d63b7dSRichard Lowe (void) printf(gettext("%*sBuilding %s using .DEFAULT because it is out of date\n"),
69410d63b7dSRichard Lowe recursion_level,
69510d63b7dSRichard Lowe "",
69610d63b7dSRichard Lowe true_target->string_mb);
69710d63b7dSRichard Lowe }
69810d63b7dSRichard Lowe }
69910d63b7dSRichard Lowe line->body.line.sccs_command = false;
70010d63b7dSRichard Lowe line->body.line.command_template = default_rule;
70110d63b7dSRichard Lowe line->body.line.target = true_target;
70210d63b7dSRichard Lowe line->body.line.star = NULL;
70310d63b7dSRichard Lowe line->body.line.less = true_target;
70410d63b7dSRichard Lowe line->body.line.percent = NULL;
70510d63b7dSRichard Lowe }
70610d63b7dSRichard Lowe }
70710d63b7dSRichard Lowe
70810d63b7dSRichard Lowe /* We say "target up to date" if no cmd were executed for the target */
70910d63b7dSRichard Lowe if (!target->is_double_colon_parent) {
71010d63b7dSRichard Lowe commands_done = false;
71110d63b7dSRichard Lowe }
71210d63b7dSRichard Lowe
71310d63b7dSRichard Lowe silent = silent_all;
71410d63b7dSRichard Lowe ignore_errors = ignore_errors_all;
71510d63b7dSRichard Lowe if (posix)
71610d63b7dSRichard Lowe {
71710d63b7dSRichard Lowe if (!silent)
71810d63b7dSRichard Lowe {
71910d63b7dSRichard Lowe silent = (Boolean) target->silent_mode;
72010d63b7dSRichard Lowe }
72110d63b7dSRichard Lowe if (!ignore_errors)
72210d63b7dSRichard Lowe {
72310d63b7dSRichard Lowe ignore_errors = (Boolean) target->ignore_error_mode;
72410d63b7dSRichard Lowe }
72510d63b7dSRichard Lowe }
72610d63b7dSRichard Lowe
72710d63b7dSRichard Lowe int doname_dyntarget = 0;
72810d63b7dSRichard Lowe r_command:
72910d63b7dSRichard Lowe /* Run commands if any. */
73010d63b7dSRichard Lowe if ((command != NULL) &&
73110d63b7dSRichard Lowe (command->body.line.command_template != NULL)) {
73210d63b7dSRichard Lowe if (result != build_failed) {
73348bbca81SDaniel Hoffman result = run_command(command,
73410d63b7dSRichard Lowe (Boolean) ((parallel || save_parallel) && !silent));
73510d63b7dSRichard Lowe }
73610d63b7dSRichard Lowe switch (result) {
73710d63b7dSRichard Lowe case build_running:
73810d63b7dSRichard Lowe add_running(target,
73910d63b7dSRichard Lowe true_target,
74010d63b7dSRichard Lowe command,
74110d63b7dSRichard Lowe --recursion_level,
74210d63b7dSRichard Lowe auto_count,
74310d63b7dSRichard Lowe automatics,
74410d63b7dSRichard Lowe do_get,
74510d63b7dSRichard Lowe implicit);
74610d63b7dSRichard Lowe target->state = build_running;
74710d63b7dSRichard Lowe if ((line = get_prop(target->prop,
74810d63b7dSRichard Lowe line_prop)) != NULL) {
74910d63b7dSRichard Lowe if (line->body.line.query != NULL) {
75010d63b7dSRichard Lowe delete_query_chain(line->body.line.query);
75110d63b7dSRichard Lowe }
75210d63b7dSRichard Lowe line->body.line.query = NULL;
75310d63b7dSRichard Lowe }
75410d63b7dSRichard Lowe if (target->conditional_cnt > 0) {
75510d63b7dSRichard Lowe reset_locals(target,
75610d63b7dSRichard Lowe old_locals,
75710d63b7dSRichard Lowe get_prop(target->prop,
75810d63b7dSRichard Lowe conditional_prop),
75910d63b7dSRichard Lowe 0);
76010d63b7dSRichard Lowe }
76110d63b7dSRichard Lowe return build_running;
76210d63b7dSRichard Lowe case build_serial:
76310d63b7dSRichard Lowe add_serial(target,
76410d63b7dSRichard Lowe --recursion_level,
76510d63b7dSRichard Lowe do_get,
76610d63b7dSRichard Lowe implicit);
76710d63b7dSRichard Lowe target->state = build_running;
76810d63b7dSRichard Lowe line = get_prop(target->prop, line_prop);
76910d63b7dSRichard Lowe if (line != NULL) {
77010d63b7dSRichard Lowe if (line->body.line.query != NULL) {
77110d63b7dSRichard Lowe delete_query_chain(line->body.line.query);
77210d63b7dSRichard Lowe }
77310d63b7dSRichard Lowe line->body.line.query = NULL;
77410d63b7dSRichard Lowe }
77510d63b7dSRichard Lowe if (target->conditional_cnt > 0) {
77610d63b7dSRichard Lowe reset_locals(target,
77710d63b7dSRichard Lowe old_locals,
77810d63b7dSRichard Lowe get_prop(target->prop,
77910d63b7dSRichard Lowe conditional_prop),
78010d63b7dSRichard Lowe 0);
78110d63b7dSRichard Lowe }
78210d63b7dSRichard Lowe return build_running;
78310d63b7dSRichard Lowe case build_ok:
78410d63b7dSRichard Lowe /* If all went OK set a nice timestamp */
78510d63b7dSRichard Lowe if (true_target->stat.time == file_doesnt_exist) {
78610d63b7dSRichard Lowe true_target->stat.time = file_max_time;
78710d63b7dSRichard Lowe }
78810d63b7dSRichard Lowe break;
78910d63b7dSRichard Lowe }
79010d63b7dSRichard Lowe } else {
79110d63b7dSRichard Lowe /*
79210d63b7dSRichard Lowe * If no command was found for the target, and it doesn't
79310d63b7dSRichard Lowe * exist, and it is mentioned as a target in the makefile,
79410d63b7dSRichard Lowe * we say it is extremely new and that it is OK.
79510d63b7dSRichard Lowe */
79610d63b7dSRichard Lowe if (target->colons != no_colon) {
79710d63b7dSRichard Lowe if (true_target->stat.time == file_doesnt_exist){
79810d63b7dSRichard Lowe true_target->stat.time = file_max_time;
79910d63b7dSRichard Lowe }
80010d63b7dSRichard Lowe result = build_ok;
80110d63b7dSRichard Lowe }
80210d63b7dSRichard Lowe /*
80310d63b7dSRichard Lowe * Trying dynamic targets.
80410d63b7dSRichard Lowe */
80510d63b7dSRichard Lowe if(!doname_dyntarget) {
80610d63b7dSRichard Lowe doname_dyntarget = 1;
80710d63b7dSRichard Lowe Name dtarg = find_dyntarget(target);
80810d63b7dSRichard Lowe if(dtarg!=NULL) {
80910d63b7dSRichard Lowe if (!target->has_depe_list_expanded) {
81010d63b7dSRichard Lowe dynamic_dependencies(target);
81110d63b7dSRichard Lowe }
81210d63b7dSRichard Lowe if ((line = get_prop(target->prop, line_prop)) != NULL) {
81310d63b7dSRichard Lowe if (check_dependencies(&result,
81410d63b7dSRichard Lowe line,
81510d63b7dSRichard Lowe do_get,
81610d63b7dSRichard Lowe target,
81710d63b7dSRichard Lowe true_target,
81810d63b7dSRichard Lowe doing_subtree,
81910d63b7dSRichard Lowe &out_of_date_list,
82010d63b7dSRichard Lowe old_locals,
82110d63b7dSRichard Lowe implicit,
82210d63b7dSRichard Lowe &command,
82310d63b7dSRichard Lowe less,
82410d63b7dSRichard Lowe rechecking_target,
82510d63b7dSRichard Lowe recheck_conditionals))
82610d63b7dSRichard Lowe {
82710d63b7dSRichard Lowe return build_running;
82810d63b7dSRichard Lowe }
82910d63b7dSRichard Lowe if (line->body.line.query != NULL) {
83010d63b7dSRichard Lowe delete_query_chain(line->body.line.query);
83110d63b7dSRichard Lowe }
83210d63b7dSRichard Lowe line->body.line.query = out_of_date_list;
83310d63b7dSRichard Lowe }
83410d63b7dSRichard Lowe goto r_command;
83510d63b7dSRichard Lowe }
83610d63b7dSRichard Lowe }
83710d63b7dSRichard Lowe /*
83810d63b7dSRichard Lowe * If the file exists, it is OK that we couldnt figure
83910d63b7dSRichard Lowe * out how to build it.
84010d63b7dSRichard Lowe */
84110d63b7dSRichard Lowe (void) exists(target);
84210d63b7dSRichard Lowe if ((target->stat.time != file_doesnt_exist) &&
84310d63b7dSRichard Lowe (result == build_dont_know)) {
84410d63b7dSRichard Lowe result = build_ok;
84510d63b7dSRichard Lowe }
84610d63b7dSRichard Lowe }
84710d63b7dSRichard Lowe
84810d63b7dSRichard Lowe /*
84910d63b7dSRichard Lowe * Some of the following is duplicated in the function finish_doname.
85010d63b7dSRichard Lowe * If anything is changed here, check to see if it needs to be
85110d63b7dSRichard Lowe * changed there.
85210d63b7dSRichard Lowe */
85310d63b7dSRichard Lowe if ((line = get_prop(target->prop, line_prop)) != NULL) {
85410d63b7dSRichard Lowe if (line->body.line.query != NULL) {
85510d63b7dSRichard Lowe delete_query_chain(line->body.line.query);
85610d63b7dSRichard Lowe }
85710d63b7dSRichard Lowe line->body.line.query = NULL;
85810d63b7dSRichard Lowe }
85910d63b7dSRichard Lowe target->state = result;
86010d63b7dSRichard Lowe parallel = save_parallel;
86110d63b7dSRichard Lowe if (target->conditional_cnt > 0) {
86210d63b7dSRichard Lowe reset_locals(target,
86310d63b7dSRichard Lowe old_locals,
86410d63b7dSRichard Lowe get_prop(target->prop, conditional_prop),
86510d63b7dSRichard Lowe 0);
86610d63b7dSRichard Lowe }
86710d63b7dSRichard Lowe recursion_level--;
86810d63b7dSRichard Lowe if (target->is_member) {
86910d63b7dSRichard Lowe Property member;
87010d63b7dSRichard Lowe
87110d63b7dSRichard Lowe /* Propagate the timestamp from the member file to the member*/
87210d63b7dSRichard Lowe if ((target->stat.time != file_max_time) &&
87310d63b7dSRichard Lowe ((member = get_prop(target->prop, member_prop)) != NULL) &&
87410d63b7dSRichard Lowe (exists(member->body.member.member) > file_doesnt_exist)) {
87510d63b7dSRichard Lowe target->stat.time =
87610d63b7dSRichard Lowe member->body.member.member->stat.time;
87710d63b7dSRichard Lowe }
87810d63b7dSRichard Lowe }
87910d63b7dSRichard Lowe /*
88010d63b7dSRichard Lowe * Check if we found any new auto dependencies when we
88110d63b7dSRichard Lowe * built the target.
88210d63b7dSRichard Lowe */
88310d63b7dSRichard Lowe if ((result == build_ok) && check_auto_dependencies(target,
88410d63b7dSRichard Lowe auto_count,
88510d63b7dSRichard Lowe automatics)) {
88610d63b7dSRichard Lowe if (debug_level > 0) {
88710d63b7dSRichard Lowe (void) printf(gettext("%*sTarget `%s' acquired new dependencies from build, rechecking all dependencies\n"),
88810d63b7dSRichard Lowe recursion_level,
88910d63b7dSRichard Lowe "",
89010d63b7dSRichard Lowe true_target->string_mb);
89110d63b7dSRichard Lowe }
89210d63b7dSRichard Lowe rechecking_target = true;
89310d63b7dSRichard Lowe saved_commands_done = commands_done;
89410d63b7dSRichard Lowe goto recheck_target;
89510d63b7dSRichard Lowe }
89610d63b7dSRichard Lowe
89710d63b7dSRichard Lowe if (rechecking_target && !commands_done) {
89810d63b7dSRichard Lowe commands_done = saved_commands_done;
89910d63b7dSRichard Lowe }
90010d63b7dSRichard Lowe
90110d63b7dSRichard Lowe return result;
90210d63b7dSRichard Lowe }
90310d63b7dSRichard Lowe
90410d63b7dSRichard Lowe /*
90510d63b7dSRichard Lowe * DONE.
90610d63b7dSRichard Lowe *
90710d63b7dSRichard Lowe * check_dependencies(result, line, do_get,
90810d63b7dSRichard Lowe * target, true_target, doing_subtree, out_of_date_tail,
90910d63b7dSRichard Lowe * old_locals, implicit, command, less, rechecking_target)
91010d63b7dSRichard Lowe *
91110d63b7dSRichard Lowe * Return value:
91210d63b7dSRichard Lowe * True returned if some dependencies left running
91348bbca81SDaniel Hoffman *
91410d63b7dSRichard Lowe * Parameters:
91510d63b7dSRichard Lowe * result Pointer to cell we update if build failed
91610d63b7dSRichard Lowe * line We get the dependencies from here
91710d63b7dSRichard Lowe * do_get Allow use of sccs get in recursive doname()
91810d63b7dSRichard Lowe * target The target to chase dependencies for
91910d63b7dSRichard Lowe * true_target The real one for :: and lib(member)
92010d63b7dSRichard Lowe * doing_subtree True if building a conditional macro subtree
92110d63b7dSRichard Lowe * out_of_date_tail Used to set the $? list
92210d63b7dSRichard Lowe * old_locals Used for resetting the local macros
92310d63b7dSRichard Lowe * implicit Called when scanning for implicit rules?
92410d63b7dSRichard Lowe * command Place to stuff command
92510d63b7dSRichard Lowe * less Set to $< value
92610d63b7dSRichard Lowe *
92710d63b7dSRichard Lowe * Global variables used:
92810d63b7dSRichard Lowe * command_changed Set if we suspect .make.state needs rewrite
92910d63b7dSRichard Lowe * debug_level Should we trace actions?
93010d63b7dSRichard Lowe * force The Name " FORCE", compared against
93110d63b7dSRichard Lowe * recursion_level Used for tracing
93210d63b7dSRichard Lowe * rewrite_statefile Set if .make.state needs rewriting
93310d63b7dSRichard Lowe * wait_name The Name ".WAIT", compared against
93410d63b7dSRichard Lowe */
93510d63b7dSRichard 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)93610d63b7dSRichard 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)
93710d63b7dSRichard Lowe {
93810d63b7dSRichard Lowe Boolean dependencies_running;
939*e7afc443SToomas Soome Dependency dependency;
94010d63b7dSRichard Lowe Doname dep_result;
94110d63b7dSRichard Lowe Boolean dependency_changed = false;
94210d63b7dSRichard Lowe
94310d63b7dSRichard Lowe line->body.line.dependency_time = file_doesnt_exist;
94410d63b7dSRichard Lowe if (line->body.line.query != NULL) {
94510d63b7dSRichard Lowe delete_query_chain(line->body.line.query);
94610d63b7dSRichard Lowe }
94710d63b7dSRichard Lowe line->body.line.query = NULL;
94810d63b7dSRichard Lowe line->body.line.is_out_of_date = false;
94910d63b7dSRichard Lowe dependencies_running = false;
95010d63b7dSRichard Lowe /*
95110d63b7dSRichard Lowe * Run thru all the dependencies and call doname() recursively
95210d63b7dSRichard Lowe * on each of them.
95310d63b7dSRichard Lowe */
95410d63b7dSRichard Lowe for (dependency = line->body.line.dependencies;
95510d63b7dSRichard Lowe dependency != NULL;
95610d63b7dSRichard Lowe dependency = dependency->next) {
95710d63b7dSRichard Lowe Boolean this_dependency_changed = false;
95810d63b7dSRichard Lowe
95910d63b7dSRichard Lowe if (!dependency->automatic &&
96010d63b7dSRichard Lowe (rechecking_target || target->rechecking_target)) {
96110d63b7dSRichard Lowe /*
96210d63b7dSRichard Lowe * We only bother with the autos when rechecking
96310d63b7dSRichard Lowe */
96410d63b7dSRichard Lowe continue;
96510d63b7dSRichard Lowe }
96610d63b7dSRichard Lowe
96710d63b7dSRichard Lowe if (dependency->name == wait_name) {
96810d63b7dSRichard Lowe /*
96910d63b7dSRichard Lowe * The special target .WAIT means finish all of
97010d63b7dSRichard Lowe * the prior dependencies before continuing.
97110d63b7dSRichard Lowe */
97210d63b7dSRichard Lowe if (dependencies_running) {
97310d63b7dSRichard Lowe break;
97410d63b7dSRichard Lowe }
97510d63b7dSRichard Lowe } else if ((!parallel_ok(dependency->name, false)) &&
97610d63b7dSRichard Lowe (dependencies_running)) {
97710d63b7dSRichard Lowe /*
97810d63b7dSRichard Lowe * If we can't execute the current dependency in
97910d63b7dSRichard Lowe * parallel, hold off the dependency processing
98010d63b7dSRichard Lowe * to preserve the order of the dependencies.
98110d63b7dSRichard Lowe */
98210d63b7dSRichard Lowe break;
98310d63b7dSRichard Lowe } else {
98410d63b7dSRichard Lowe timestruc_t depe_time = file_doesnt_exist;
98510d63b7dSRichard Lowe
98610d63b7dSRichard Lowe
98710d63b7dSRichard Lowe if (true_target->is_member) {
98810d63b7dSRichard Lowe depe_time = exists(dependency->name);
98910d63b7dSRichard Lowe }
99010d63b7dSRichard Lowe if (dependency->built ||
99110d63b7dSRichard Lowe (dependency->name->state == build_failed)) {
99210d63b7dSRichard Lowe dep_result = (Doname) dependency->name->state;
99310d63b7dSRichard Lowe } else {
99410d63b7dSRichard Lowe dep_result = doname_check(dependency->name,
99510d63b7dSRichard Lowe do_get,
99610d63b7dSRichard Lowe false,
99710d63b7dSRichard Lowe (Boolean) dependency->automatic);
99810d63b7dSRichard Lowe }
99910d63b7dSRichard Lowe if (true_target->is_member || dependency->name->is_member) {
100010d63b7dSRichard Lowe /* should compare only secs, cause lib members does not have nsec time resolution */
100110d63b7dSRichard Lowe if (depe_time.tv_sec != dependency->name->stat.time.tv_sec) {
100210d63b7dSRichard Lowe this_dependency_changed =
100310d63b7dSRichard Lowe dependency_changed =
100410d63b7dSRichard Lowe true;
100510d63b7dSRichard Lowe }
100610d63b7dSRichard Lowe } else {
100710d63b7dSRichard Lowe if (depe_time != dependency->name->stat.time) {
100810d63b7dSRichard Lowe this_dependency_changed =
100910d63b7dSRichard Lowe dependency_changed =
101010d63b7dSRichard Lowe true;
101110d63b7dSRichard Lowe }
101210d63b7dSRichard Lowe }
101310d63b7dSRichard Lowe dependency->built = true;
101410d63b7dSRichard Lowe switch (dep_result) {
101510d63b7dSRichard Lowe case build_running:
101610d63b7dSRichard Lowe dependencies_running = true;
101710d63b7dSRichard Lowe continue;
101810d63b7dSRichard Lowe case build_failed:
101910d63b7dSRichard Lowe *result = build_failed;
102010d63b7dSRichard Lowe break;
102110d63b7dSRichard Lowe case build_dont_know:
102210d63b7dSRichard Lowe /*
102310d63b7dSRichard Lowe * If make can't figure out how to make a dependency, maybe the dependency
102410d63b7dSRichard Lowe * is out of date. In this case, we just declare the target out of date
102510d63b7dSRichard Lowe * and go on. If we really need the dependency, the make'ing of the target
102610d63b7dSRichard Lowe * will fail. This will only happen for automatic (hidden) dependencies.
102710d63b7dSRichard Lowe */
102810d63b7dSRichard Lowe if(!recheck_conditionals) {
102910d63b7dSRichard Lowe line->body.line.is_out_of_date = true;
103010d63b7dSRichard Lowe }
103110d63b7dSRichard Lowe /*
103210d63b7dSRichard Lowe * Make sure the dependency is not saved
103310d63b7dSRichard Lowe * in the state file.
103410d63b7dSRichard Lowe */
103510d63b7dSRichard Lowe dependency->stale = true;
103610d63b7dSRichard Lowe rewrite_statefile =
103710d63b7dSRichard Lowe command_changed =
103810d63b7dSRichard Lowe true;
103910d63b7dSRichard Lowe if (debug_level > 0) {
104010d63b7dSRichard Lowe (void) printf(gettext("Target %s rebuilt because dependency %s does not exist\n"),
104110d63b7dSRichard Lowe true_target->string_mb,
104210d63b7dSRichard Lowe dependency->name->string_mb);
104310d63b7dSRichard Lowe }
104410d63b7dSRichard Lowe break;
104510d63b7dSRichard Lowe }
104610d63b7dSRichard Lowe if (dependency->name->depends_on_conditional) {
104710d63b7dSRichard Lowe target->depends_on_conditional = true;
104810d63b7dSRichard Lowe }
104910d63b7dSRichard Lowe if (dependency->name == force) {
105010d63b7dSRichard Lowe target->stat.time =
105110d63b7dSRichard Lowe dependency->name->stat.time;
105210d63b7dSRichard Lowe }
105310d63b7dSRichard Lowe /*
105410d63b7dSRichard Lowe * Propagate new timestamp from "member" to
105510d63b7dSRichard Lowe * "lib.a(member)".
105610d63b7dSRichard Lowe */
105710d63b7dSRichard Lowe (void) exists(dependency->name);
105810d63b7dSRichard Lowe
105910d63b7dSRichard Lowe /* Collect the timestamp of the youngest dependency */
106010d63b7dSRichard Lowe line->body.line.dependency_time =
106110d63b7dSRichard Lowe MAX(dependency->name->stat.time,
106210d63b7dSRichard Lowe line->body.line.dependency_time);
106310d63b7dSRichard Lowe
106410d63b7dSRichard Lowe /* Correction: do not consider nanosecs for members */
106510d63b7dSRichard Lowe if(true_target->is_member || dependency->name->is_member) {
106610d63b7dSRichard Lowe line->body.line.dependency_time.tv_nsec = 0;
106710d63b7dSRichard Lowe }
106810d63b7dSRichard Lowe
106910d63b7dSRichard Lowe if (debug_level > 1) {
107010d63b7dSRichard Lowe (void) printf(gettext("%*sDate(%s)=%s \n"),
107110d63b7dSRichard Lowe recursion_level,
107210d63b7dSRichard Lowe "",
107310d63b7dSRichard Lowe dependency->name->string_mb,
107410d63b7dSRichard Lowe time_to_string(dependency->name->
107510d63b7dSRichard Lowe stat.time));
107610d63b7dSRichard Lowe if (dependency->name->stat.time > line->body.line.dependency_time) {
107710d63b7dSRichard Lowe (void) printf(gettext("%*sDate-dependencies(%s) set to %s\n"),
107810d63b7dSRichard Lowe recursion_level,
107910d63b7dSRichard Lowe "",
108010d63b7dSRichard Lowe true_target->string_mb,
108110d63b7dSRichard Lowe time_to_string(line->body.line.
108210d63b7dSRichard Lowe dependency_time));
108310d63b7dSRichard Lowe }
108410d63b7dSRichard Lowe }
108510d63b7dSRichard Lowe
108610d63b7dSRichard Lowe /* Build the $? list */
108710d63b7dSRichard Lowe if (true_target->is_member) {
108810d63b7dSRichard Lowe if (this_dependency_changed == true) {
108910d63b7dSRichard Lowe true_target->stat.time = dependency->name->stat.time;
109010d63b7dSRichard Lowe true_target->stat.time.tv_sec--;
109110d63b7dSRichard Lowe } else {
109248bbca81SDaniel Hoffman /* Dina:
109310d63b7dSRichard Lowe * The next statement is commented
109410d63b7dSRichard Lowe * out as a fix for bug #1051032.
109510d63b7dSRichard Lowe * if dependency hasn't changed
109610d63b7dSRichard Lowe * then there's no need to invalidate
109710d63b7dSRichard Lowe * true_target. This statemnt causes
109810d63b7dSRichard Lowe * make to take much longer to process
109910d63b7dSRichard Lowe * an already-built archive. Soren
110010d63b7dSRichard Lowe * said it was a quick fix for some
110110d63b7dSRichard Lowe * problem he doesn't remember.
110210d63b7dSRichard Lowe true_target->stat.time = file_no_time;
110310d63b7dSRichard Lowe */
110410d63b7dSRichard Lowe (void) exists(true_target);
110510d63b7dSRichard Lowe }
110610d63b7dSRichard Lowe } else {
110710d63b7dSRichard Lowe (void) exists(true_target);
110810d63b7dSRichard Lowe }
110910d63b7dSRichard Lowe Boolean out_of_date;
111010d63b7dSRichard Lowe if (true_target->is_member || dependency->name->is_member) {
111110d63b7dSRichard Lowe out_of_date = (Boolean) OUT_OF_DATE_SEC(true_target->stat.time,
111210d63b7dSRichard Lowe dependency->name->stat.time);
111310d63b7dSRichard Lowe } else {
111410d63b7dSRichard Lowe out_of_date = (Boolean) OUT_OF_DATE(true_target->stat.time,
111510d63b7dSRichard Lowe dependency->name->stat.time);
111610d63b7dSRichard Lowe }
111710d63b7dSRichard Lowe if ((build_unconditional || out_of_date) &&
111810d63b7dSRichard Lowe (dependency->name != force) &&
111910d63b7dSRichard Lowe (dependency->stale == false)) {
112010d63b7dSRichard Lowe *out_of_date_tail = ALLOC(Chain);
112110d63b7dSRichard Lowe if (dependency->name->is_member &&
112210d63b7dSRichard Lowe (get_prop(dependency->name->prop,
112310d63b7dSRichard Lowe member_prop) != NULL)) {
112410d63b7dSRichard Lowe (*out_of_date_tail)->name =
112510d63b7dSRichard Lowe get_prop(dependency->name->prop,
112610d63b7dSRichard Lowe member_prop)->
112710d63b7dSRichard Lowe body.member.member;
112810d63b7dSRichard Lowe } else {
112910d63b7dSRichard Lowe (*out_of_date_tail)->name =
113010d63b7dSRichard Lowe dependency->name;
113110d63b7dSRichard Lowe }
113210d63b7dSRichard Lowe (*out_of_date_tail)->next = NULL;
113310d63b7dSRichard Lowe out_of_date_tail = &(*out_of_date_tail)->next;
113410d63b7dSRichard Lowe if (debug_level > 0) {
113510d63b7dSRichard Lowe if (dependency->name->stat.time == file_max_time) {
113610d63b7dSRichard Lowe (void) printf(gettext("%*sBuilding %s because %s does not exist\n"),
113710d63b7dSRichard Lowe recursion_level,
113810d63b7dSRichard Lowe "",
113910d63b7dSRichard Lowe true_target->string_mb,
114010d63b7dSRichard Lowe dependency->name->string_mb);
114110d63b7dSRichard Lowe } else {
114210d63b7dSRichard Lowe (void) printf(gettext("%*sBuilding %s because it is out of date relative to %s\n"),
114310d63b7dSRichard Lowe recursion_level,
114410d63b7dSRichard Lowe "",
114510d63b7dSRichard Lowe true_target->string_mb,
114610d63b7dSRichard Lowe dependency->name->string_mb);
114710d63b7dSRichard Lowe }
114810d63b7dSRichard Lowe }
114910d63b7dSRichard Lowe }
115010d63b7dSRichard Lowe if (dependency->name == force) {
115110d63b7dSRichard Lowe force->stat.time =
115210d63b7dSRichard Lowe file_max_time;
115310d63b7dSRichard Lowe force->state = build_dont_know;
115410d63b7dSRichard Lowe }
115510d63b7dSRichard Lowe }
115610d63b7dSRichard Lowe }
115710d63b7dSRichard Lowe if (dependencies_running) {
115810d63b7dSRichard Lowe if (doing_subtree) {
115910d63b7dSRichard Lowe if (target->conditional_cnt > 0) {
116010d63b7dSRichard Lowe reset_locals(target,
116110d63b7dSRichard Lowe old_locals,
116210d63b7dSRichard Lowe get_prop(target->prop,
116310d63b7dSRichard Lowe conditional_prop),
116410d63b7dSRichard Lowe 0);
116510d63b7dSRichard Lowe }
116610d63b7dSRichard Lowe return true;
116710d63b7dSRichard Lowe } else {
116810d63b7dSRichard Lowe target->state = build_running;
116910d63b7dSRichard Lowe add_pending(target,
117010d63b7dSRichard Lowe --recursion_level,
117110d63b7dSRichard Lowe do_get,
117210d63b7dSRichard Lowe implicit,
117310d63b7dSRichard Lowe false);
117410d63b7dSRichard Lowe if (target->conditional_cnt > 0) {
117510d63b7dSRichard Lowe reset_locals(target,
117610d63b7dSRichard Lowe old_locals,
117710d63b7dSRichard Lowe get_prop(target->prop,
117810d63b7dSRichard Lowe conditional_prop),
117910d63b7dSRichard Lowe 0);
118010d63b7dSRichard Lowe }
118110d63b7dSRichard Lowe return true;
118210d63b7dSRichard Lowe }
118310d63b7dSRichard Lowe }
118410d63b7dSRichard Lowe /*
118510d63b7dSRichard Lowe * Collect the timestamp of the youngest double colon target
118610d63b7dSRichard Lowe * dependency.
118710d63b7dSRichard Lowe */
118810d63b7dSRichard Lowe if (target->is_double_colon_parent) {
118910d63b7dSRichard Lowe for (dependency = line->body.line.dependencies;
119010d63b7dSRichard Lowe dependency != NULL;
119110d63b7dSRichard Lowe dependency = dependency->next) {
119210d63b7dSRichard Lowe Property tmp_line;
119310d63b7dSRichard Lowe
119410d63b7dSRichard Lowe if ((tmp_line = get_prop(dependency->name->prop, line_prop)) != NULL) {
119510d63b7dSRichard Lowe if(tmp_line->body.line.dependency_time != file_max_time) {
119610d63b7dSRichard Lowe target->stat.time =
119710d63b7dSRichard Lowe MAX(tmp_line->body.line.dependency_time,
119810d63b7dSRichard Lowe target->stat.time);
119910d63b7dSRichard Lowe }
120010d63b7dSRichard Lowe }
120110d63b7dSRichard Lowe }
120210d63b7dSRichard Lowe }
120310d63b7dSRichard Lowe if ((true_target->is_member) && (dependency_changed == true)) {
120410d63b7dSRichard Lowe true_target->stat.time = file_no_time;
120510d63b7dSRichard Lowe }
120610d63b7dSRichard Lowe /*
120710d63b7dSRichard Lowe * After scanning all the dependencies, we check the rule
120810d63b7dSRichard Lowe * if we found one.
120910d63b7dSRichard Lowe */
121010d63b7dSRichard Lowe if (line->body.line.command_template != NULL) {
121110d63b7dSRichard Lowe if (line->body.line.command_template_redefined) {
121210d63b7dSRichard Lowe warning(gettext("Too many rules defined for target %s"),
121310d63b7dSRichard Lowe target->string_mb);
121410d63b7dSRichard Lowe }
121510d63b7dSRichard Lowe *command = line;
121610d63b7dSRichard Lowe /* Check if the target is out of date */
121710d63b7dSRichard Lowe Boolean out_of_date;
121810d63b7dSRichard Lowe if (true_target->is_member) {
121910d63b7dSRichard Lowe out_of_date = (Boolean) OUT_OF_DATE_SEC(true_target->stat.time,
122010d63b7dSRichard Lowe line->body.line.dependency_time);
122110d63b7dSRichard Lowe } else {
122210d63b7dSRichard Lowe out_of_date = (Boolean) OUT_OF_DATE(true_target->stat.time,
122310d63b7dSRichard Lowe line->body.line.dependency_time);
122410d63b7dSRichard Lowe }
122510d63b7dSRichard Lowe if (build_unconditional || out_of_date){
122610d63b7dSRichard Lowe if(!recheck_conditionals) {
122710d63b7dSRichard Lowe line->body.line.is_out_of_date = true;
122810d63b7dSRichard Lowe }
122910d63b7dSRichard Lowe }
123010d63b7dSRichard Lowe line->body.line.sccs_command = false;
123110d63b7dSRichard Lowe line->body.line.target = true_target;
123210d63b7dSRichard Lowe if(gnu_style) {
123310d63b7dSRichard Lowe
123410d63b7dSRichard Lowe // set $< for explicit rule
123510d63b7dSRichard Lowe if(line->body.line.dependencies != NULL) {
123610d63b7dSRichard Lowe less = line->body.line.dependencies->name;
123710d63b7dSRichard Lowe }
123810d63b7dSRichard Lowe
123910d63b7dSRichard Lowe // set $* for explicit rule
124010d63b7dSRichard Lowe Name target_body;
124110d63b7dSRichard Lowe Name tt = true_target;
124210d63b7dSRichard Lowe Property member;
1243*e7afc443SToomas Soome wchar_t *target_end;
1244*e7afc443SToomas Soome Dependency suffix;
1245*e7afc443SToomas Soome int suffix_length;
124610d63b7dSRichard Lowe Wstring targ_string;
124710d63b7dSRichard Lowe Wstring suf_string;
124810d63b7dSRichard Lowe
124910d63b7dSRichard Lowe if (true_target->is_member &&
125010d63b7dSRichard Lowe ((member = get_prop(target->prop, member_prop)) !=
125110d63b7dSRichard Lowe NULL)) {
125210d63b7dSRichard Lowe tt = member->body.member.member;
125310d63b7dSRichard Lowe }
125410d63b7dSRichard Lowe targ_string.init(tt);
125510d63b7dSRichard Lowe target_end = targ_string.get_string() + tt->hash.length;
125610d63b7dSRichard Lowe for (suffix = suffixes; suffix != NULL; suffix = suffix->next) {
125710d63b7dSRichard Lowe suffix_length = suffix->name->hash.length;
125810d63b7dSRichard Lowe suf_string.init(suffix->name);
125910d63b7dSRichard Lowe if (tt->hash.length < suffix_length) {
126010d63b7dSRichard Lowe continue;
126110d63b7dSRichard Lowe } else if (!IS_WEQUALN(suf_string.get_string(),
126210d63b7dSRichard Lowe (target_end - suffix_length),
126310d63b7dSRichard Lowe suffix_length)) {
126410d63b7dSRichard Lowe continue;
126510d63b7dSRichard Lowe }
126610d63b7dSRichard Lowe target_body = GETNAME(
126710d63b7dSRichard Lowe targ_string.get_string(),
126810d63b7dSRichard Lowe (int)(tt->hash.length - suffix_length)
126910d63b7dSRichard Lowe );
127010d63b7dSRichard Lowe line->body.line.star = target_body;
127110d63b7dSRichard Lowe }
127210d63b7dSRichard Lowe
127310d63b7dSRichard Lowe // set result = build_ok so that implicit rules are not used.
127410d63b7dSRichard Lowe if(*result == build_dont_know) {
127510d63b7dSRichard Lowe *result = build_ok;
127610d63b7dSRichard Lowe }
127710d63b7dSRichard Lowe }
127810d63b7dSRichard Lowe if (less != NULL) {
127910d63b7dSRichard Lowe line->body.line.less = less;
128010d63b7dSRichard Lowe }
128110d63b7dSRichard Lowe }
128210d63b7dSRichard Lowe
128310d63b7dSRichard Lowe return false;
128410d63b7dSRichard Lowe }
128510d63b7dSRichard Lowe
128610d63b7dSRichard Lowe /*
128710d63b7dSRichard Lowe * dynamic_dependencies(target)
128810d63b7dSRichard Lowe *
128910d63b7dSRichard Lowe * Checks if any dependency contains a macro ref
129010d63b7dSRichard Lowe * If so, it replaces the dependency with the expanded version.
129110d63b7dSRichard Lowe * Here, "$@" gets translated to target->string. That is
129210d63b7dSRichard Lowe * the current name on the left of the colon in the
129310d63b7dSRichard Lowe * makefile. Thus,
129410d63b7dSRichard Lowe * xyz: s.$@.c
129510d63b7dSRichard Lowe * translates into
129610d63b7dSRichard Lowe * xyz: s.xyz.c
129710d63b7dSRichard Lowe *
129810d63b7dSRichard Lowe * Also, "$(@F)" translates to the same thing without a preceeding
129910d63b7dSRichard Lowe * directory path (if one exists).
130010d63b7dSRichard Lowe * Note, to enter "$@" on a dependency line in a makefile
130110d63b7dSRichard Lowe * "$$@" must be typed. This is because make expands
130210d63b7dSRichard Lowe * macros in dependency lists upon reading them.
130310d63b7dSRichard Lowe * dynamic_dependencies() also expands file wildcards.
130410d63b7dSRichard Lowe * If there are any Shell meta characters in the name,
130510d63b7dSRichard Lowe * search the directory, and replace the dependency
130610d63b7dSRichard Lowe * with the set of files the pattern matches
130710d63b7dSRichard Lowe *
130810d63b7dSRichard Lowe * Parameters:
130910d63b7dSRichard Lowe * target Target to sanitize dependencies for
131010d63b7dSRichard Lowe *
131110d63b7dSRichard Lowe * Global variables used:
131210d63b7dSRichard Lowe * c_at The Name "@", used to set macro value
131310d63b7dSRichard Lowe * debug_level Should we trace actions?
131410d63b7dSRichard Lowe * dot The Name ".", used to read directory
131510d63b7dSRichard Lowe * recursion_level Used for tracing
131610d63b7dSRichard Lowe */
131710d63b7dSRichard Lowe void
dynamic_dependencies(Name target)131810d63b7dSRichard Lowe dynamic_dependencies(Name target)
131910d63b7dSRichard Lowe {
132010d63b7dSRichard Lowe wchar_t pattern[MAXPATHLEN];
1321*e7afc443SToomas Soome wchar_t *p;
132210d63b7dSRichard Lowe Property line;
1323*e7afc443SToomas Soome Dependency dependency;
1324*e7afc443SToomas Soome Dependency *remove;
132510d63b7dSRichard Lowe String_rec string;
132610d63b7dSRichard Lowe wchar_t buffer[MAXPATHLEN];
1327*e7afc443SToomas Soome Boolean set_at = false;
1328*e7afc443SToomas Soome wchar_t *start;
132910d63b7dSRichard Lowe Dependency new_depe;
1330*e7afc443SToomas Soome Boolean reuse_cell;
133110d63b7dSRichard Lowe Dependency first_member;
133210d63b7dSRichard Lowe Name directory;
133310d63b7dSRichard Lowe Name lib;
133410d63b7dSRichard Lowe Name member;
133510d63b7dSRichard Lowe Property prop;
133610d63b7dSRichard Lowe Name true_target = target;
133710d63b7dSRichard Lowe wchar_t *library;
133810d63b7dSRichard Lowe
133910d63b7dSRichard Lowe if ((line = get_prop(target->prop, line_prop)) == NULL) {
134010d63b7dSRichard Lowe return;
134110d63b7dSRichard Lowe }
134210d63b7dSRichard Lowe /* If the target is constructed from a "::" target we consider that */
134310d63b7dSRichard Lowe if (target->has_target_prop) {
134410d63b7dSRichard Lowe true_target = get_prop(target->prop,
134510d63b7dSRichard Lowe target_prop)->body.target.target;
134610d63b7dSRichard Lowe }
134710d63b7dSRichard Lowe /* Scan all dependencies and process the ones that contain "$" chars */
134810d63b7dSRichard Lowe for (dependency = line->body.line.dependencies;
134910d63b7dSRichard Lowe dependency != NULL;
135010d63b7dSRichard Lowe dependency = dependency->next) {
135110d63b7dSRichard Lowe if (!dependency->name->dollar) {
135210d63b7dSRichard Lowe continue;
135310d63b7dSRichard Lowe }
135410d63b7dSRichard Lowe target->has_depe_list_expanded = true;
135510d63b7dSRichard Lowe
135610d63b7dSRichard Lowe /* The make macro $@ is bound to the target name once per */
135710d63b7dSRichard Lowe /* invocation of dynamic_dependencies() */
135810d63b7dSRichard Lowe if (!set_at) {
135910d63b7dSRichard Lowe (void) SETVAR(c_at, true_target, false);
136010d63b7dSRichard Lowe set_at = true;
136110d63b7dSRichard Lowe }
136210d63b7dSRichard Lowe /* Expand this dependency string */
136310d63b7dSRichard Lowe INIT_STRING_FROM_STACK(string, buffer);
136410d63b7dSRichard Lowe expand_value(dependency->name, &string, false);
136510d63b7dSRichard Lowe /* Scan the expanded string. It could contain whitespace */
136610d63b7dSRichard Lowe /* which mean it expands to several dependencies */
136710d63b7dSRichard Lowe start = string.buffer.start;
136810d63b7dSRichard Lowe while (iswspace(*start)) {
136910d63b7dSRichard Lowe start++;
137010d63b7dSRichard Lowe }
137110d63b7dSRichard Lowe /* Remove the cell (later) if the macro was empty */
137210d63b7dSRichard Lowe if (start[0] == (int) nul_char) {
137310d63b7dSRichard Lowe dependency->name = NULL;
137410d63b7dSRichard Lowe }
137510d63b7dSRichard Lowe
137610d63b7dSRichard Lowe /* azv 10/26/95 to fix bug BID_1170218 */
137710d63b7dSRichard Lowe if ((start[0] == (int) period_char) &&
137810d63b7dSRichard Lowe (start[1] == (int) slash_char)) {
137910d63b7dSRichard Lowe start += 2;
138010d63b7dSRichard Lowe }
138110d63b7dSRichard Lowe /* azv */
138210d63b7dSRichard Lowe
138310d63b7dSRichard Lowe first_member = NULL;
138410d63b7dSRichard Lowe /* We use the original dependency cell for the first */
138510d63b7dSRichard Lowe /* dependency from the expansion */
138610d63b7dSRichard Lowe reuse_cell = true;
138710d63b7dSRichard Lowe /* We also have to deal with dependencies that expand to */
138810d63b7dSRichard Lowe /* lib.a(members) notation */
138910d63b7dSRichard Lowe for (p = start; *p != (int) nul_char; p++) {
139010d63b7dSRichard Lowe if ((*p == (int) parenleft_char)) {
139110d63b7dSRichard Lowe lib = GETNAME(start, p - start);
139210d63b7dSRichard Lowe lib->is_member = true;
139310d63b7dSRichard Lowe first_member = dependency;
139410d63b7dSRichard Lowe start = p + 1;
139510d63b7dSRichard Lowe while (iswspace(*start)) {
139610d63b7dSRichard Lowe start++;
139710d63b7dSRichard Lowe }
139810d63b7dSRichard Lowe break;
139910d63b7dSRichard Lowe }
140010d63b7dSRichard Lowe }
140110d63b7dSRichard Lowe do {
140210d63b7dSRichard Lowe /* First skip whitespace */
140310d63b7dSRichard Lowe for (p = start; *p != (int) nul_char; p++) {
140410d63b7dSRichard Lowe if ((*p == (int) nul_char) ||
140510d63b7dSRichard Lowe iswspace(*p) ||
140610d63b7dSRichard Lowe (*p == (int) parenright_char)) {
140710d63b7dSRichard Lowe break;
140810d63b7dSRichard Lowe }
140910d63b7dSRichard Lowe }
141010d63b7dSRichard Lowe /* Enter dependency from expansion */
141110d63b7dSRichard Lowe if (p != start) {
141210d63b7dSRichard Lowe /* Create new dependency cell if */
141310d63b7dSRichard Lowe /* this is not the first dependency */
141410d63b7dSRichard Lowe /* picked from the expansion */
141510d63b7dSRichard Lowe if (!reuse_cell) {
141610d63b7dSRichard Lowe new_depe = ALLOC(Dependency);
141710d63b7dSRichard Lowe new_depe->next = dependency->next;
141810d63b7dSRichard Lowe new_depe->automatic = false;
141910d63b7dSRichard Lowe new_depe->stale = false;
142010d63b7dSRichard Lowe new_depe->built = false;
142110d63b7dSRichard Lowe dependency->next = new_depe;
142210d63b7dSRichard Lowe dependency = new_depe;
142310d63b7dSRichard Lowe }
142410d63b7dSRichard Lowe reuse_cell = false;
142510d63b7dSRichard Lowe /* Internalize the dependency name */
142610d63b7dSRichard Lowe // tolik. Fix for bug 4110429: inconsistent expansion for macros that
142710d63b7dSRichard Lowe // include "//" and "/./"
142810d63b7dSRichard Lowe //dependency->name = GETNAME(start, p - start);
142910d63b7dSRichard Lowe dependency->name = normalize_name(start, p - start);
143010d63b7dSRichard Lowe if ((debug_level > 0) &&
143110d63b7dSRichard Lowe (first_member == NULL)) {
143210d63b7dSRichard Lowe (void) printf(gettext("%*sDynamic dependency `%s' for target `%s'\n"),
143310d63b7dSRichard Lowe recursion_level,
143410d63b7dSRichard Lowe "",
143510d63b7dSRichard Lowe dependency->name->string_mb,
143610d63b7dSRichard Lowe true_target->string_mb);
143710d63b7dSRichard Lowe }
143810d63b7dSRichard Lowe for (start = p; iswspace(*start); start++);
143910d63b7dSRichard Lowe p = start;
144010d63b7dSRichard Lowe }
144110d63b7dSRichard Lowe } while ((*p != (int) nul_char) &&
144210d63b7dSRichard Lowe (*p != (int) parenright_char));
144310d63b7dSRichard Lowe /* If the expansion was of lib.a(members) format we now */
144410d63b7dSRichard Lowe /* enter the proper member cells */
144510d63b7dSRichard Lowe if (first_member != NULL) {
144610d63b7dSRichard Lowe /* Scan the new dependencies and transform them from */
144710d63b7dSRichard Lowe /* "foo" to "lib.a(foo)" */
144810d63b7dSRichard Lowe for (; 1; first_member = first_member->next) {
144910d63b7dSRichard Lowe /* Build "lib.a(foo)" name */
145010d63b7dSRichard Lowe INIT_STRING_FROM_STACK(string, buffer);
145110d63b7dSRichard Lowe APPEND_NAME(lib,
145210d63b7dSRichard Lowe &string,
145310d63b7dSRichard Lowe (int) lib->hash.length);
145410d63b7dSRichard Lowe append_char((int) parenleft_char, &string);
145510d63b7dSRichard Lowe APPEND_NAME(first_member->name,
145610d63b7dSRichard Lowe &string,
145710d63b7dSRichard Lowe FIND_LENGTH);
145810d63b7dSRichard Lowe append_char((int) parenright_char, &string);
145910d63b7dSRichard Lowe member = first_member->name;
146010d63b7dSRichard Lowe /* Replace "foo" with "lib.a(foo)" */
146110d63b7dSRichard Lowe first_member->name =
146210d63b7dSRichard Lowe GETNAME(string.buffer.start, FIND_LENGTH);
146310d63b7dSRichard Lowe if (string.free_after_use) {
146410d63b7dSRichard Lowe retmem(string.buffer.start);
146510d63b7dSRichard Lowe }
146610d63b7dSRichard Lowe if (debug_level > 0) {
146710d63b7dSRichard Lowe (void) printf(gettext("%*sDynamic dependency `%s' for target `%s'\n"),
146810d63b7dSRichard Lowe recursion_level,
146910d63b7dSRichard Lowe "",
147010d63b7dSRichard Lowe first_member->name->
147110d63b7dSRichard Lowe string_mb,
147210d63b7dSRichard Lowe true_target->string_mb);
147310d63b7dSRichard Lowe }
147410d63b7dSRichard Lowe first_member->name->is_member = lib->is_member;
147510d63b7dSRichard Lowe /* Add member property to member */
147610d63b7dSRichard Lowe prop = maybe_append_prop(first_member->name,
147710d63b7dSRichard Lowe member_prop);
147810d63b7dSRichard Lowe prop->body.member.library = lib;
147910d63b7dSRichard Lowe prop->body.member.entry = NULL;
148010d63b7dSRichard Lowe prop->body.member.member = member;
148110d63b7dSRichard Lowe if (first_member == dependency) {
148210d63b7dSRichard Lowe break;
148310d63b7dSRichard Lowe }
148410d63b7dSRichard Lowe }
148510d63b7dSRichard Lowe }
148610d63b7dSRichard Lowe }
148710d63b7dSRichard Lowe Wstring wcb;
148810d63b7dSRichard Lowe /* Then scan all the dependencies again. This time we want to expand */
148910d63b7dSRichard Lowe /* shell file wildcards */
149010d63b7dSRichard Lowe for (remove = &line->body.line.dependencies, dependency = *remove;
149110d63b7dSRichard Lowe dependency != NULL;
149210d63b7dSRichard Lowe dependency = *remove) {
149310d63b7dSRichard Lowe if (dependency->name == NULL) {
149410d63b7dSRichard Lowe dependency = *remove = (*remove)->next;
149510d63b7dSRichard Lowe continue;
149610d63b7dSRichard Lowe }
149710d63b7dSRichard Lowe /* If dependency name string contains shell wildcards */
149810d63b7dSRichard Lowe /* replace the name with the expansion */
149910d63b7dSRichard Lowe if (dependency->name->wildcard) {
150010d63b7dSRichard Lowe wcb.init(dependency->name);
150110d63b7dSRichard Lowe if ((start = (wchar_t *) wcschr(wcb.get_string(),
150210d63b7dSRichard Lowe (int) parenleft_char)) != NULL) {
150310d63b7dSRichard Lowe /* lib(*) type pattern */
150410d63b7dSRichard Lowe library = buffer;
150510d63b7dSRichard Lowe (void) wcsncpy(buffer,
150610d63b7dSRichard Lowe wcb.get_string(),
150710d63b7dSRichard Lowe start - wcb.get_string());
150810d63b7dSRichard Lowe buffer[start-wcb.get_string()] =
150910d63b7dSRichard Lowe (int) nul_char;
151010d63b7dSRichard Lowe (void) wcsncpy(pattern,
151110d63b7dSRichard Lowe start + 1,
151210d63b7dSRichard Lowe (int) (dependency->name->hash.length-(start-wcb.get_string())-2));
151310d63b7dSRichard Lowe pattern[dependency->name->hash.length -
151410d63b7dSRichard Lowe (start-wcb.get_string()) - 2] =
151510d63b7dSRichard Lowe (int) nul_char;
151610d63b7dSRichard Lowe } else {
151710d63b7dSRichard Lowe library = NULL;
151810d63b7dSRichard Lowe (void) wcsncpy(pattern,
151910d63b7dSRichard Lowe wcb.get_string(),
152010d63b7dSRichard Lowe (int) dependency->name->hash.length);
152110d63b7dSRichard Lowe pattern[dependency->name->hash.length] =
152210d63b7dSRichard Lowe (int) nul_char;
152310d63b7dSRichard Lowe }
152410d63b7dSRichard Lowe start = (wchar_t *) wcsrchr(pattern, (int) slash_char);
152510d63b7dSRichard Lowe if (start == NULL) {
152610d63b7dSRichard Lowe directory = dot;
152710d63b7dSRichard Lowe p = pattern;
152810d63b7dSRichard Lowe } else {
152910d63b7dSRichard Lowe directory = GETNAME(pattern, start-pattern);
153010d63b7dSRichard Lowe p = start+1;
153110d63b7dSRichard Lowe }
153210d63b7dSRichard Lowe /* The expansion is handled by the read_dir() routine*/
153310d63b7dSRichard Lowe if (read_dir(directory, p, line, library)) {
153410d63b7dSRichard Lowe *remove = (*remove)->next;
153510d63b7dSRichard Lowe } else {
153610d63b7dSRichard Lowe remove = &dependency->next;
153710d63b7dSRichard Lowe }
153810d63b7dSRichard Lowe } else {
153910d63b7dSRichard Lowe remove = &dependency->next;
154010d63b7dSRichard Lowe }
154110d63b7dSRichard Lowe }
154210d63b7dSRichard Lowe
154310d63b7dSRichard Lowe /* Then unbind $@ */
154410d63b7dSRichard Lowe (void) SETVAR(c_at, (Name) NULL, false);
154510d63b7dSRichard Lowe }
154610d63b7dSRichard Lowe
154710d63b7dSRichard Lowe /*
154810d63b7dSRichard Lowe * DONE.
154910d63b7dSRichard Lowe *
155010d63b7dSRichard Lowe * run_command(line)
155110d63b7dSRichard Lowe *
155210d63b7dSRichard Lowe * Takes one Cmd_line and runs the commands from it.
155310d63b7dSRichard Lowe *
155410d63b7dSRichard Lowe * Return value:
155510d63b7dSRichard Lowe * Indicates if the command failed or not
155610d63b7dSRichard Lowe *
155710d63b7dSRichard Lowe * Parameters:
155810d63b7dSRichard Lowe * line The command line to run
155910d63b7dSRichard Lowe *
156010d63b7dSRichard Lowe * Global variables used:
156110d63b7dSRichard Lowe * commands_done Set if we do run command
156210d63b7dSRichard Lowe * current_line Set to the line we run a command from
156310d63b7dSRichard Lowe * current_target Set to the target we run a command for
156410d63b7dSRichard Lowe * file_number Used to form temp file name
156510d63b7dSRichard Lowe * keep_state Indicates that .KEEP_STATE is on
156610d63b7dSRichard Lowe * make_state The Name ".make.state", used to check timestamp
156710d63b7dSRichard Lowe * parallel True if currently building in parallel
156810d63b7dSRichard Lowe * parallel_process_cnt Count of parallel processes running
156910d63b7dSRichard Lowe * quest Indicates that make -q is on
157010d63b7dSRichard Lowe * rewrite_statefile Set if we do run a command
157110d63b7dSRichard Lowe * sunpro_dependencies The Name "SUNPRO_DEPENDENCIES", set value
157210d63b7dSRichard Lowe * temp_file_directory Used to form temp fie name
157310d63b7dSRichard Lowe * temp_file_name Set to the name of the temp file
157410d63b7dSRichard Lowe * touch Indicates that make -t is on
157510d63b7dSRichard Lowe */
157610d63b7dSRichard Lowe static Doname
run_command(Property line,Boolean)1577*e7afc443SToomas Soome run_command(Property line, Boolean)
157810d63b7dSRichard Lowe {
1579*e7afc443SToomas Soome Doname result = build_ok;
1580*e7afc443SToomas Soome Boolean remember_only = false;
1581*e7afc443SToomas Soome Name target = line->body.line.target;
158210d63b7dSRichard Lowe wchar_t *string;
158310d63b7dSRichard Lowe char tmp_file_path[MAXPATHLEN];
158410d63b7dSRichard Lowe
158510d63b7dSRichard Lowe if (!line->body.line.is_out_of_date && target->rechecking_target) {
158610d63b7dSRichard Lowe target->rechecking_target = false;
158710d63b7dSRichard Lowe return build_ok;
158810d63b7dSRichard Lowe }
158910d63b7dSRichard Lowe
159010d63b7dSRichard Lowe /*
159110d63b7dSRichard Lowe * Build the command if we know the target is out of date,
159210d63b7dSRichard Lowe * or if we want to check cmd consistency.
159310d63b7dSRichard Lowe */
159410d63b7dSRichard Lowe if (line->body.line.is_out_of_date || keep_state) {
159510d63b7dSRichard Lowe /* Hack for handling conditional macros in DMake. */
159610d63b7dSRichard Lowe if (!line->body.line.dont_rebuild_command_used) {
159710d63b7dSRichard Lowe build_command_strings(target, line);
159810d63b7dSRichard Lowe }
159910d63b7dSRichard Lowe }
160010d63b7dSRichard Lowe /* Never mind */
160110d63b7dSRichard Lowe if (!line->body.line.is_out_of_date) {
160210d63b7dSRichard Lowe return build_ok;
160310d63b7dSRichard Lowe }
160410d63b7dSRichard Lowe /* If quest, then exit(1) because the target is out of date */
160510d63b7dSRichard Lowe if (quest) {
160610d63b7dSRichard Lowe if (posix) {
160710d63b7dSRichard Lowe result = execute_parallel(line, true);
160810d63b7dSRichard Lowe }
160910d63b7dSRichard Lowe exit_status = 1;
161010d63b7dSRichard Lowe exit(1);
161110d63b7dSRichard Lowe }
161210d63b7dSRichard Lowe /* We actually had to do something this time */
161310d63b7dSRichard Lowe rewrite_statefile = commands_done = true;
161410d63b7dSRichard Lowe /*
161510d63b7dSRichard Lowe * If this is an sccs command, we have to do some extra checking
161610d63b7dSRichard Lowe * and possibly complain. If the file can't be gotten because it's
161710d63b7dSRichard Lowe * checked out, we complain and behave as if the command was
161810d63b7dSRichard Lowe * executed eventhough we ignored the command.
161910d63b7dSRichard Lowe */
162010d63b7dSRichard Lowe if (!touch &&
162110d63b7dSRichard Lowe line->body.line.sccs_command &&
162210d63b7dSRichard Lowe (target->stat.time != file_doesnt_exist) &&
162310d63b7dSRichard Lowe ((target->stat.mode & 0222) != 0)) {
162410d63b7dSRichard Lowe fatal(gettext("%s is writable so it cannot be sccs gotten"),
162510d63b7dSRichard Lowe target->string_mb);
162610d63b7dSRichard Lowe target->has_complained = remember_only = true;
162710d63b7dSRichard Lowe }
162810d63b7dSRichard Lowe /*
162910d63b7dSRichard Lowe * If KEEP_STATE is on, we make sure we have the timestamp for
163010d63b7dSRichard Lowe * .make.state. If .make.state changes during the command run,
163110d63b7dSRichard Lowe * we reread .make.state after the command. We also setup the
163210d63b7dSRichard Lowe * environment variable that asks utilities to report dependencies.
163310d63b7dSRichard Lowe */
163410d63b7dSRichard Lowe if (!touch &&
163510d63b7dSRichard Lowe keep_state &&
163610d63b7dSRichard Lowe !remember_only) {
163710d63b7dSRichard Lowe (void) exists(make_state);
163848bbca81SDaniel Hoffman if((strlen(temp_file_directory) == 1) &&
163910d63b7dSRichard Lowe (temp_file_directory[0] == '/')) {
164010d63b7dSRichard Lowe tmp_file_path[0] = '\0';
164110d63b7dSRichard Lowe } else {
164210d63b7dSRichard Lowe strcpy(tmp_file_path, temp_file_directory);
164310d63b7dSRichard Lowe }
164410d63b7dSRichard Lowe sprintf(mbs_buffer,
164510d63b7dSRichard Lowe "%s/.make.dependency.%08x.%d.%d",
164610d63b7dSRichard Lowe tmp_file_path,
164710d63b7dSRichard Lowe hostid,
164810d63b7dSRichard Lowe getpid(),
164910d63b7dSRichard Lowe file_number++);
165010d63b7dSRichard Lowe MBSTOWCS(wcs_buffer, mbs_buffer);
165110d63b7dSRichard Lowe Boolean fnd;
165210d63b7dSRichard Lowe temp_file_name = getname_fn(wcs_buffer, FIND_LENGTH, false, &fnd);
165310d63b7dSRichard Lowe temp_file_name->stat.is_file = true;
165410d63b7dSRichard Lowe int len = 2*MAXPATHLEN + strlen(target->string_mb) + 2;
165510d63b7dSRichard Lowe wchar_t *to = string = ALLOC_WC(len);
165610d63b7dSRichard Lowe for (wchar_t *from = wcs_buffer; *from != (int) nul_char; ) {
165710d63b7dSRichard Lowe if (*from == (int) space_char) {
165810d63b7dSRichard Lowe *to++ = (int) backslash_char;
165910d63b7dSRichard Lowe }
166010d63b7dSRichard Lowe *to++ = *from++;
166110d63b7dSRichard Lowe }
166210d63b7dSRichard Lowe *to++ = (int) space_char;
166310d63b7dSRichard Lowe MBSTOWCS(to, target->string_mb);
166410d63b7dSRichard Lowe Name sprodep_name = getname_fn(string, FIND_LENGTH, false, &fnd);
166510d63b7dSRichard Lowe (void) SETVAR(sunpro_dependencies,
166610d63b7dSRichard Lowe sprodep_name,
166710d63b7dSRichard Lowe false);
166810d63b7dSRichard Lowe retmem(string);
166910d63b7dSRichard Lowe } else {
167010d63b7dSRichard Lowe temp_file_name = NULL;
167110d63b7dSRichard Lowe }
167210d63b7dSRichard Lowe
167310d63b7dSRichard Lowe /*
167410d63b7dSRichard Lowe * In case we are interrupted, we need to know what was going on.
167510d63b7dSRichard Lowe */
167610d63b7dSRichard Lowe current_target = target;
167710d63b7dSRichard Lowe /*
167810d63b7dSRichard Lowe * We also need to be able to save an empty command instead of the
167910d63b7dSRichard Lowe * interrupted one in .make.state.
168010d63b7dSRichard Lowe */
168110d63b7dSRichard Lowe current_line = line;
168210d63b7dSRichard Lowe if (remember_only) {
168310d63b7dSRichard Lowe /* Empty block!!! */
168410d63b7dSRichard Lowe } else if (touch) {
168510d63b7dSRichard Lowe result = touch_command(line, target, result);
168610d63b7dSRichard Lowe if (posix) {
168710d63b7dSRichard Lowe result = execute_parallel(line, true);
168810d63b7dSRichard Lowe }
168910d63b7dSRichard Lowe } else {
169010d63b7dSRichard Lowe /*
169110d63b7dSRichard Lowe * If this is not a touch run, we need to execute the
169210d63b7dSRichard Lowe * proper command(s) for the target.
169310d63b7dSRichard Lowe */
169410d63b7dSRichard Lowe if (parallel) {
169510d63b7dSRichard Lowe if (!parallel_ok(target, true)) {
169610d63b7dSRichard Lowe /*
169710d63b7dSRichard Lowe * We are building in parallel, but
169810d63b7dSRichard Lowe * this target must be built in serial.
169910d63b7dSRichard Lowe */
170010d63b7dSRichard Lowe /*
170110d63b7dSRichard Lowe * If nothing else is building,
170210d63b7dSRichard Lowe * do this one, else wait.
170310d63b7dSRichard Lowe */
170410d63b7dSRichard Lowe if (parallel_process_cnt == 0) {
170510d63b7dSRichard Lowe result = execute_parallel(line, true, target->localhost);
170610d63b7dSRichard Lowe } else {
170710d63b7dSRichard Lowe current_target = NULL;
170810d63b7dSRichard Lowe current_line = NULL;
170910d63b7dSRichard Lowe /*
171010d63b7dSRichard Lowe line->body.line.command_used = NULL;
171110d63b7dSRichard Lowe */
171210d63b7dSRichard Lowe line->body.line.dont_rebuild_command_used = true;
171310d63b7dSRichard Lowe return build_serial;
171410d63b7dSRichard Lowe }
171510d63b7dSRichard Lowe } else {
171610d63b7dSRichard Lowe result = execute_parallel(line, false);
171710d63b7dSRichard Lowe switch (result) {
171810d63b7dSRichard Lowe case build_running:
171910d63b7dSRichard Lowe return build_running;
172010d63b7dSRichard Lowe case build_serial:
172110d63b7dSRichard Lowe if (parallel_process_cnt == 0) {
172210d63b7dSRichard Lowe result = execute_parallel(line, true, target->localhost);
172310d63b7dSRichard Lowe } else {
172410d63b7dSRichard Lowe current_target = NULL;
172510d63b7dSRichard Lowe current_line = NULL;
172610d63b7dSRichard Lowe target->parallel = false;
172710d63b7dSRichard Lowe line->body.line.command_used =
17282e8f3c34SToomas Soome NULL;
172910d63b7dSRichard Lowe return build_serial;
173010d63b7dSRichard Lowe }
173110d63b7dSRichard Lowe }
173210d63b7dSRichard Lowe }
173310d63b7dSRichard Lowe } else {
173410d63b7dSRichard Lowe result = execute_parallel(line, true, target->localhost);
173510d63b7dSRichard Lowe }
173610d63b7dSRichard Lowe }
173710d63b7dSRichard Lowe temp_file_name = NULL;
173810d63b7dSRichard Lowe if (report_dependencies_level == 0){
173910d63b7dSRichard Lowe update_target(line, result);
174010d63b7dSRichard Lowe }
174110d63b7dSRichard Lowe current_target = NULL;
174210d63b7dSRichard Lowe current_line = NULL;
174310d63b7dSRichard Lowe return result;
174410d63b7dSRichard Lowe }
174510d63b7dSRichard Lowe
174610d63b7dSRichard Lowe /*
174710d63b7dSRichard Lowe * execute_serial(line)
174810d63b7dSRichard Lowe *
174910d63b7dSRichard Lowe * Runs thru the command line for the target and
175010d63b7dSRichard Lowe * executes the rules one by one.
175110d63b7dSRichard Lowe *
175210d63b7dSRichard Lowe * Return value:
175310d63b7dSRichard Lowe * The result of the command build
175410d63b7dSRichard Lowe *
175548bbca81SDaniel Hoffman * Parameters:
175610d63b7dSRichard Lowe * line The command to execute
175710d63b7dSRichard Lowe *
175810d63b7dSRichard Lowe * Static variables used:
175910d63b7dSRichard Lowe *
176010d63b7dSRichard Lowe * Global variables used:
176110d63b7dSRichard Lowe * continue_after_error -k flag
176210d63b7dSRichard Lowe * do_not_exec_rule -n flag
176310d63b7dSRichard Lowe * report_dependencies -P flag
176410d63b7dSRichard Lowe * silent Don't echo commands before executing
176510d63b7dSRichard Lowe * temp_file_name Temp file for auto dependencies
176610d63b7dSRichard Lowe * vpath_defined If true, translate path for command
176710d63b7dSRichard Lowe */
176810d63b7dSRichard Lowe Doname
execute_serial(Property line)176910d63b7dSRichard Lowe execute_serial(Property line)
177010d63b7dSRichard Lowe {
177110d63b7dSRichard Lowe int child_pid = 0;
177210d63b7dSRichard Lowe Boolean printed_serial;
177310d63b7dSRichard Lowe Doname result = build_ok;
177410d63b7dSRichard Lowe Cmd_line rule, cmd_tail, command = NULL;
177510d63b7dSRichard Lowe char mbstring[MAXPATHLEN];
177610d63b7dSRichard Lowe int filed;
177710d63b7dSRichard Lowe Name target = line->body.line.target;
177810d63b7dSRichard Lowe
177910d63b7dSRichard Lowe target->has_recursive_dependency = false;
178010d63b7dSRichard Lowe // We have to create a copy of the rules chain for processing because
178110d63b7dSRichard Lowe // the original one can be destroyed during .make.state file rereading.
178210d63b7dSRichard Lowe for (rule = line->body.line.command_used;
178310d63b7dSRichard Lowe rule != NULL;
178410d63b7dSRichard Lowe rule = rule->next) {
178510d63b7dSRichard Lowe if (command == NULL) {
178610d63b7dSRichard Lowe command = cmd_tail = ALLOC(Cmd_line);
178710d63b7dSRichard Lowe } else {
178810d63b7dSRichard Lowe cmd_tail->next = ALLOC(Cmd_line);
178910d63b7dSRichard Lowe cmd_tail = cmd_tail->next;
179010d63b7dSRichard Lowe }
179110d63b7dSRichard Lowe *cmd_tail = *rule;
179210d63b7dSRichard Lowe }
179310d63b7dSRichard Lowe if (command) {
179410d63b7dSRichard Lowe cmd_tail->next = NULL;
179510d63b7dSRichard Lowe }
179610d63b7dSRichard Lowe for (rule = command; rule != NULL; rule = rule->next) {
179710d63b7dSRichard Lowe if (posix && (touch || quest) && !rule->always_exec) {
179810d63b7dSRichard Lowe continue;
179910d63b7dSRichard Lowe }
180010d63b7dSRichard Lowe if (vpath_defined) {
180110d63b7dSRichard Lowe rule->command_line =
180210d63b7dSRichard Lowe vpath_translation(rule->command_line);
180310d63b7dSRichard Lowe }
180410d63b7dSRichard Lowe /* Echo command line, maybe. */
180510d63b7dSRichard Lowe if ((rule->command_line->hash.length > 0) &&
180610d63b7dSRichard Lowe !silent &&
180710d63b7dSRichard Lowe (!rule->silent || do_not_exec_rule) &&
180810d63b7dSRichard Lowe (report_dependencies_level == 0)) {
180910d63b7dSRichard Lowe (void) printf("%s\n", rule->command_line->string_mb);
181010d63b7dSRichard Lowe }
181110d63b7dSRichard Lowe if (rule->command_line->hash.length > 0) {
181210d63b7dSRichard Lowe /* Do assignment if command line prefixed with "=" */
181310d63b7dSRichard Lowe if (rule->assign) {
181410d63b7dSRichard Lowe result = build_ok;
181510d63b7dSRichard Lowe do_assign(rule->command_line, target);
181610d63b7dSRichard Lowe } else if (report_dependencies_level == 0) {
181710d63b7dSRichard Lowe /* Execute command line. */
181810d63b7dSRichard Lowe setvar_envvar();
181910d63b7dSRichard Lowe result = dosys(rule->command_line,
182010d63b7dSRichard Lowe (Boolean) rule->ignore_error,
182110d63b7dSRichard Lowe (Boolean) rule->make_refd,
182210d63b7dSRichard Lowe /* ds 98.04.23 bug #4085164. make should always show error messages */
182310d63b7dSRichard Lowe false,
182410d63b7dSRichard Lowe /* BOOLEAN(rule->silent &&
182510d63b7dSRichard Lowe rule->ignore_error), */
182610d63b7dSRichard Lowe (Boolean) rule->always_exec,
182710d63b7dSRichard Lowe target);
182810d63b7dSRichard Lowe check_state(temp_file_name);
182910d63b7dSRichard Lowe }
183010d63b7dSRichard Lowe } else {
183110d63b7dSRichard Lowe result = build_ok;
183210d63b7dSRichard Lowe }
183310d63b7dSRichard Lowe if (result == build_failed) {
183410d63b7dSRichard Lowe if (silent || rule->silent) {
183510d63b7dSRichard Lowe (void) printf(gettext("The following command caused the error:\n%s\n"),
183610d63b7dSRichard Lowe rule->command_line->string_mb);
183710d63b7dSRichard Lowe }
183810d63b7dSRichard Lowe if (!rule->ignore_error && !ignore_errors) {
183910d63b7dSRichard Lowe if (!continue_after_error) {
184010d63b7dSRichard Lowe fatal(gettext("Command failed for target `%s'"),
184110d63b7dSRichard Lowe target->string_mb);
184210d63b7dSRichard Lowe }
184310d63b7dSRichard Lowe /*
184410d63b7dSRichard Lowe * Make sure a failing command is not
184510d63b7dSRichard Lowe * saved in .make.state.
184610d63b7dSRichard Lowe */
184710d63b7dSRichard Lowe line->body.line.command_used = NULL;
184810d63b7dSRichard Lowe break;
184910d63b7dSRichard Lowe } else {
185010d63b7dSRichard Lowe result = build_ok;
185110d63b7dSRichard Lowe }
185210d63b7dSRichard Lowe }
185310d63b7dSRichard Lowe }
185410d63b7dSRichard Lowe for (rule = command; rule != NULL; rule = cmd_tail) {
185510d63b7dSRichard Lowe cmd_tail = rule->next;
185610d63b7dSRichard Lowe free(rule);
185710d63b7dSRichard Lowe }
185810d63b7dSRichard Lowe command = NULL;
185910d63b7dSRichard Lowe if (temp_file_name != NULL) {
186010d63b7dSRichard Lowe free_name(temp_file_name);
186110d63b7dSRichard Lowe }
186210d63b7dSRichard Lowe temp_file_name = NULL;
186310d63b7dSRichard Lowe
186410d63b7dSRichard Lowe Property spro = get_prop(sunpro_dependencies->prop, macro_prop);
186510d63b7dSRichard Lowe if(spro != NULL) {
186610d63b7dSRichard Lowe Name val = spro->body.macro.value;
186710d63b7dSRichard Lowe if(val != NULL) {
186810d63b7dSRichard Lowe free_name(val);
186910d63b7dSRichard Lowe spro->body.macro.value = NULL;
187010d63b7dSRichard Lowe }
187110d63b7dSRichard Lowe }
187210d63b7dSRichard Lowe spro = get_prop(sunpro_dependencies->prop, env_mem_prop);
187310d63b7dSRichard Lowe if(spro) {
187410d63b7dSRichard Lowe char *val = spro->body.env_mem.value;
187510d63b7dSRichard Lowe if(val != NULL) {
187648bbca81SDaniel Hoffman /*
187710d63b7dSRichard Lowe * Do not return memory allocated for SUNPRO_DEPENDENCIES
187848bbca81SDaniel Hoffman * It will be returned in setvar_daemon() in macro.cc
187910d63b7dSRichard Lowe */
188010d63b7dSRichard Lowe // retmem_mb(val);
188110d63b7dSRichard Lowe spro->body.env_mem.value = NULL;
188210d63b7dSRichard Lowe }
188310d63b7dSRichard Lowe }
188448bbca81SDaniel Hoffman
188510d63b7dSRichard Lowe return result;
188610d63b7dSRichard Lowe }
188710d63b7dSRichard Lowe
188810d63b7dSRichard Lowe
188910d63b7dSRichard Lowe
189010d63b7dSRichard Lowe /*
189110d63b7dSRichard Lowe * vpath_translation(cmd)
189210d63b7dSRichard Lowe *
189310d63b7dSRichard Lowe * Translates one command line by
189410d63b7dSRichard Lowe * checking each word. If the word has an alias it is translated.
189510d63b7dSRichard Lowe *
189610d63b7dSRichard Lowe * Return value:
189710d63b7dSRichard Lowe * The translated command
189810d63b7dSRichard Lowe *
189910d63b7dSRichard Lowe * Parameters:
190010d63b7dSRichard Lowe * cmd Command to translate
190110d63b7dSRichard Lowe *
190210d63b7dSRichard Lowe * Global variables used:
190310d63b7dSRichard Lowe */
190410d63b7dSRichard Lowe Name
vpath_translation(Name cmd)1905*e7afc443SToomas Soome vpath_translation(Name cmd)
190610d63b7dSRichard Lowe {
190710d63b7dSRichard Lowe wchar_t buffer[STRING_BUFFER_LENGTH];
190810d63b7dSRichard Lowe String_rec new_cmd;
190910d63b7dSRichard Lowe wchar_t *p;
191010d63b7dSRichard Lowe wchar_t *start;
191110d63b7dSRichard Lowe
191210d63b7dSRichard Lowe if (!vpath_defined || (cmd == NULL) || (cmd->hash.length == 0)) {
191310d63b7dSRichard Lowe return cmd;
191410d63b7dSRichard Lowe }
191510d63b7dSRichard Lowe INIT_STRING_FROM_STACK(new_cmd, buffer);
191610d63b7dSRichard Lowe
191710d63b7dSRichard Lowe Wstring wcb(cmd);
191810d63b7dSRichard Lowe p = wcb.get_string();
191910d63b7dSRichard Lowe
192010d63b7dSRichard Lowe while (*p != (int) nul_char) {
192110d63b7dSRichard Lowe while (iswspace(*p) && (*p != (int) nul_char)) {
192210d63b7dSRichard Lowe append_char(*p++, &new_cmd);
192310d63b7dSRichard Lowe }
192410d63b7dSRichard Lowe start = p;
192510d63b7dSRichard Lowe while (!iswspace(*p) && (*p != (int) nul_char)) {
192610d63b7dSRichard Lowe p++;
192710d63b7dSRichard Lowe }
192810d63b7dSRichard Lowe cmd = GETNAME(start, p - start);
192910d63b7dSRichard Lowe if (cmd->has_vpath_alias_prop) {
193010d63b7dSRichard Lowe cmd = get_prop(cmd->prop, vpath_alias_prop)->
193110d63b7dSRichard Lowe body.vpath_alias.alias;
193210d63b7dSRichard Lowe APPEND_NAME(cmd,
193310d63b7dSRichard Lowe &new_cmd,
193410d63b7dSRichard Lowe (int) cmd->hash.length);
193510d63b7dSRichard Lowe } else {
193610d63b7dSRichard Lowe append_string(start, &new_cmd, p - start);
193710d63b7dSRichard Lowe }
193810d63b7dSRichard Lowe }
193910d63b7dSRichard Lowe cmd = GETNAME(new_cmd.buffer.start, FIND_LENGTH);
194010d63b7dSRichard Lowe if (new_cmd.free_after_use) {
194110d63b7dSRichard Lowe retmem(new_cmd.buffer.start);
194210d63b7dSRichard Lowe }
194310d63b7dSRichard Lowe return cmd;
194410d63b7dSRichard Lowe }
194510d63b7dSRichard Lowe
194610d63b7dSRichard Lowe /*
194710d63b7dSRichard Lowe * check_state(temp_file_name)
194810d63b7dSRichard Lowe *
194910d63b7dSRichard Lowe * Reads and checks the state changed by the previously executed command.
195010d63b7dSRichard Lowe *
195110d63b7dSRichard Lowe * Parameters:
195210d63b7dSRichard Lowe * temp_file_name The auto dependency temp file
195310d63b7dSRichard Lowe *
195410d63b7dSRichard Lowe * Global variables used:
195510d63b7dSRichard Lowe */
195610d63b7dSRichard Lowe void
check_state(Name temp_file_name)195710d63b7dSRichard Lowe check_state(Name temp_file_name)
195810d63b7dSRichard Lowe {
195910d63b7dSRichard Lowe if (!keep_state) {
196010d63b7dSRichard Lowe return;
196110d63b7dSRichard Lowe }
196210d63b7dSRichard Lowe
196310d63b7dSRichard Lowe /*
196448bbca81SDaniel Hoffman * Then read the temp file that now might
196548bbca81SDaniel Hoffman * contain dependency reports from utilities
196610d63b7dSRichard Lowe */
196710d63b7dSRichard Lowe read_dependency_file(temp_file_name);
196810d63b7dSRichard Lowe
196910d63b7dSRichard Lowe /*
197010d63b7dSRichard Lowe * And reread .make.state if it
197148bbca81SDaniel Hoffman * changed (the command ran recursive makes)
197210d63b7dSRichard Lowe */
197310d63b7dSRichard Lowe check_read_state_file();
197410d63b7dSRichard Lowe if (temp_file_name != NULL) {
197510d63b7dSRichard Lowe (void) unlink(temp_file_name->string_mb);
197610d63b7dSRichard Lowe }
197710d63b7dSRichard Lowe }
197810d63b7dSRichard Lowe
197910d63b7dSRichard Lowe /*
198010d63b7dSRichard Lowe * read_dependency_file(filename)
198110d63b7dSRichard Lowe *
198210d63b7dSRichard Lowe * Read the temp file used for reporting dependencies to make
198310d63b7dSRichard Lowe *
198410d63b7dSRichard Lowe * Parameters:
198510d63b7dSRichard Lowe * filename The name of the file with the state info
198610d63b7dSRichard Lowe *
198710d63b7dSRichard Lowe * Global variables used:
198810d63b7dSRichard Lowe * makefile_type The type of makefile being read
198910d63b7dSRichard Lowe * read_trace_level Debug flag
199010d63b7dSRichard Lowe * temp_file_number The always increasing number for unique files
199110d63b7dSRichard Lowe * trace_reader Debug flag
199210d63b7dSRichard Lowe */
199310d63b7dSRichard Lowe static void
read_dependency_file(Name filename)1994*e7afc443SToomas Soome read_dependency_file(Name filename)
199510d63b7dSRichard Lowe {
1996*e7afc443SToomas Soome Makefile_type save_makefile_type;
199710d63b7dSRichard Lowe
199810d63b7dSRichard Lowe if (filename == NULL) {
199910d63b7dSRichard Lowe return;
200010d63b7dSRichard Lowe }
200110d63b7dSRichard Lowe filename->stat.time = file_no_time;
200210d63b7dSRichard Lowe if (exists(filename) > file_doesnt_exist) {
200310d63b7dSRichard Lowe save_makefile_type = makefile_type;
200410d63b7dSRichard Lowe makefile_type = reading_cpp_file;
200510d63b7dSRichard Lowe if (read_trace_level > 1) {
200610d63b7dSRichard Lowe trace_reader = true;
200710d63b7dSRichard Lowe }
200810d63b7dSRichard Lowe temp_file_number++;
200910d63b7dSRichard Lowe (void) read_simple_file(filename,
201010d63b7dSRichard Lowe false,
201110d63b7dSRichard Lowe false,
201210d63b7dSRichard Lowe false,
201310d63b7dSRichard Lowe false,
201410d63b7dSRichard Lowe false,
201510d63b7dSRichard Lowe false);
201610d63b7dSRichard Lowe trace_reader = false;
201710d63b7dSRichard Lowe makefile_type = save_makefile_type;
201810d63b7dSRichard Lowe }
201910d63b7dSRichard Lowe }
202010d63b7dSRichard Lowe
202110d63b7dSRichard Lowe /*
202210d63b7dSRichard Lowe * check_read_state_file()
202310d63b7dSRichard Lowe *
202410d63b7dSRichard Lowe * Check if .make.state has changed
202510d63b7dSRichard Lowe * If it has we reread it
202610d63b7dSRichard Lowe *
202710d63b7dSRichard Lowe * Parameters:
202810d63b7dSRichard Lowe *
202910d63b7dSRichard Lowe * Global variables used:
203010d63b7dSRichard Lowe * make_state Make state file name
203110d63b7dSRichard Lowe * makefile_type Type of makefile being read
203210d63b7dSRichard Lowe * read_trace_level Debug flag
203310d63b7dSRichard Lowe * trace_reader Debug flag
203410d63b7dSRichard Lowe */
203510d63b7dSRichard Lowe static void
check_read_state_file(void)203610d63b7dSRichard Lowe check_read_state_file(void)
203710d63b7dSRichard Lowe {
203810d63b7dSRichard Lowe timestruc_t previous = make_state->stat.time;
2039*e7afc443SToomas Soome Makefile_type save_makefile_type;
2040*e7afc443SToomas Soome Property makefile;
204110d63b7dSRichard Lowe
204210d63b7dSRichard Lowe make_state->stat.time = file_no_time;
204310d63b7dSRichard Lowe if ((exists(make_state) == file_doesnt_exist) ||
204410d63b7dSRichard Lowe (make_state->stat.time == previous)) {
204510d63b7dSRichard Lowe return;
204610d63b7dSRichard Lowe }
204710d63b7dSRichard Lowe save_makefile_type = makefile_type;
204810d63b7dSRichard Lowe makefile_type = rereading_statefile;
204910d63b7dSRichard Lowe /* Make sure we clear the old cached contents of .make.state */
205010d63b7dSRichard Lowe makefile = maybe_append_prop(make_state, makefile_prop);
205110d63b7dSRichard Lowe if (makefile->body.makefile.contents != NULL) {
205210d63b7dSRichard Lowe retmem(makefile->body.makefile.contents);
205310d63b7dSRichard Lowe makefile->body.makefile.contents = NULL;
205410d63b7dSRichard Lowe }
205510d63b7dSRichard Lowe if (read_trace_level > 1) {
205610d63b7dSRichard Lowe trace_reader = true;
205710d63b7dSRichard Lowe }
205810d63b7dSRichard Lowe temp_file_number++;
205910d63b7dSRichard Lowe (void) read_simple_file(make_state,
206010d63b7dSRichard Lowe false,
206110d63b7dSRichard Lowe false,
206210d63b7dSRichard Lowe false,
206310d63b7dSRichard Lowe false,
206410d63b7dSRichard Lowe false,
206510d63b7dSRichard Lowe true);
206610d63b7dSRichard Lowe trace_reader = false;
206710d63b7dSRichard Lowe makefile_type = save_makefile_type;
206810d63b7dSRichard Lowe }
206910d63b7dSRichard Lowe
207010d63b7dSRichard Lowe /*
207110d63b7dSRichard Lowe * do_assign(line, target)
207210d63b7dSRichard Lowe *
207310d63b7dSRichard Lowe * Handles runtime assignments for command lines prefixed with "=".
207410d63b7dSRichard Lowe *
207510d63b7dSRichard Lowe * Parameters:
207610d63b7dSRichard Lowe * line The command that contains an assignment
207710d63b7dSRichard Lowe * target The Name of the target, used for error reports
207810d63b7dSRichard Lowe *
207910d63b7dSRichard Lowe * Global variables used:
208010d63b7dSRichard Lowe * assign_done Set to indicate doname needs to reprocess
208110d63b7dSRichard Lowe */
208210d63b7dSRichard Lowe static void
do_assign(Name line,Name target)2083*e7afc443SToomas Soome do_assign(Name line, Name target)
208410d63b7dSRichard Lowe {
208510d63b7dSRichard Lowe Wstring wcb(line);
2086*e7afc443SToomas Soome wchar_t *string = wcb.get_string();
2087*e7afc443SToomas Soome wchar_t *equal;
2088*e7afc443SToomas Soome Name name;
2089*e7afc443SToomas Soome Boolean append = false;
209010d63b7dSRichard Lowe
209110d63b7dSRichard Lowe /*
209210d63b7dSRichard Lowe * If any runtime assignments are done, doname() must reprocess all
209310d63b7dSRichard Lowe * targets in the future since the macro values used to build the
209410d63b7dSRichard Lowe * command lines for the targets might have changed.
209510d63b7dSRichard Lowe */
209610d63b7dSRichard Lowe assign_done = true;
209710d63b7dSRichard Lowe /* Skip white space. */
209810d63b7dSRichard Lowe while (iswspace(*string)) {
209910d63b7dSRichard Lowe string++;
210010d63b7dSRichard Lowe }
210110d63b7dSRichard Lowe equal = string;
210210d63b7dSRichard Lowe /* Find "+=" or "=". */
210310d63b7dSRichard Lowe while (!iswspace(*equal) &&
210410d63b7dSRichard Lowe (*equal != (int) plus_char) &&
210510d63b7dSRichard Lowe (*equal != (int) equal_char)) {
210610d63b7dSRichard Lowe equal++;
210710d63b7dSRichard Lowe }
210810d63b7dSRichard Lowe /* Internalize macro name. */
210910d63b7dSRichard Lowe name = GETNAME(string, equal - string);
211010d63b7dSRichard Lowe /* Skip over "+=" "=". */
211110d63b7dSRichard Lowe while (!((*equal == (int) nul_char) ||
211210d63b7dSRichard Lowe (*equal == (int) equal_char) ||
211310d63b7dSRichard Lowe (*equal == (int) plus_char))) {
211410d63b7dSRichard Lowe equal++;
211510d63b7dSRichard Lowe }
211610d63b7dSRichard Lowe switch (*equal) {
211710d63b7dSRichard Lowe case nul_char:
211810d63b7dSRichard Lowe fatal(gettext("= expected in rule `%s' for target `%s'"),
211910d63b7dSRichard Lowe line->string_mb,
212010d63b7dSRichard Lowe target->string_mb);
212110d63b7dSRichard Lowe case plus_char:
212210d63b7dSRichard Lowe append = true;
212310d63b7dSRichard Lowe equal++;
212410d63b7dSRichard Lowe break;
212510d63b7dSRichard Lowe }
212610d63b7dSRichard Lowe equal++;
212710d63b7dSRichard Lowe /* Skip over whitespace in front of value. */
212810d63b7dSRichard Lowe while (iswspace(*equal)) {
212910d63b7dSRichard Lowe equal++;
213010d63b7dSRichard Lowe }
213110d63b7dSRichard Lowe /* Enter new macro value. */
213210d63b7dSRichard Lowe enter_equal(name,
213310d63b7dSRichard Lowe GETNAME(equal, wcb.get_string() + line->hash.length - equal),
213410d63b7dSRichard Lowe append);
213510d63b7dSRichard Lowe }
213610d63b7dSRichard Lowe
213710d63b7dSRichard Lowe /*
213810d63b7dSRichard Lowe * build_command_strings(target, line)
213910d63b7dSRichard Lowe *
214010d63b7dSRichard Lowe * Builds the command string to used when
214110d63b7dSRichard Lowe * building a target. If the string is different from the previous one
214210d63b7dSRichard Lowe * is_out_of_date is set.
214310d63b7dSRichard Lowe *
214410d63b7dSRichard Lowe * Parameters:
214510d63b7dSRichard Lowe * target Target to build commands for
214610d63b7dSRichard Lowe * line Where to stuff result
214710d63b7dSRichard Lowe *
214810d63b7dSRichard Lowe * Global variables used:
214910d63b7dSRichard Lowe * c_at The Name "@", used to set macro value
215010d63b7dSRichard Lowe * command_changed Set if command is different from old
215110d63b7dSRichard Lowe * debug_level Should we trace activities?
215210d63b7dSRichard Lowe * do_not_exec_rule Always echo when running -n
215310d63b7dSRichard Lowe * empty_name The Name "", used for empty rule
215410d63b7dSRichard Lowe * funny Semantics of characters
215510d63b7dSRichard Lowe * ignore_errors Used to init field for line
215610d63b7dSRichard Lowe * is_conditional Set to false befor evaling macro, checked
215710d63b7dSRichard Lowe * after expanding macros
215810d63b7dSRichard Lowe * keep_state Indicates that .KEEP_STATE is on
215910d63b7dSRichard Lowe * make_word_mentioned Set by macro eval, inits field for cmd
216010d63b7dSRichard Lowe * query The Name "?", used to set macro value
216110d63b7dSRichard Lowe * query_mentioned Set by macro eval, inits field for cmd
216210d63b7dSRichard Lowe * recursion_level Used for tracing
216310d63b7dSRichard Lowe * silent Used to init field for line
216410d63b7dSRichard Lowe */
216510d63b7dSRichard Lowe static void
build_command_strings(Name target,Property line)2166*e7afc443SToomas Soome build_command_strings(Name target, Property line)
216710d63b7dSRichard Lowe {
216810d63b7dSRichard Lowe String_rec command_line;
2169*e7afc443SToomas Soome Cmd_line command_template = line->body.line.command_template;
2170*e7afc443SToomas Soome Cmd_line *insert = &line->body.line.command_used;
2171*e7afc443SToomas Soome Cmd_line used = *insert;
217210d63b7dSRichard Lowe wchar_t buffer[STRING_BUFFER_LENGTH];
217310d63b7dSRichard Lowe wchar_t *start;
217410d63b7dSRichard Lowe Name new_command_line;
2175*e7afc443SToomas Soome Boolean new_command_longer = false;
2176*e7afc443SToomas Soome Boolean ignore_all_command_dependency = true;
217710d63b7dSRichard Lowe Property member;
217810d63b7dSRichard Lowe static Name less_name;
217910d63b7dSRichard Lowe static Name percent_name;
218010d63b7dSRichard Lowe static Name star;
218110d63b7dSRichard Lowe Name tmp_name;
218210d63b7dSRichard Lowe
218310d63b7dSRichard Lowe if (less_name == NULL) {
218410d63b7dSRichard Lowe MBSTOWCS(wcs_buffer, "<");
218510d63b7dSRichard Lowe less_name = GETNAME(wcs_buffer, FIND_LENGTH);
218610d63b7dSRichard Lowe MBSTOWCS(wcs_buffer, "%");
218710d63b7dSRichard Lowe percent_name = GETNAME(wcs_buffer, FIND_LENGTH);
218810d63b7dSRichard Lowe MBSTOWCS(wcs_buffer, "*");
218910d63b7dSRichard Lowe star = GETNAME(wcs_buffer, FIND_LENGTH);
219010d63b7dSRichard Lowe }
219110d63b7dSRichard Lowe
219210d63b7dSRichard Lowe /* We have to check if a target depends on conditional macros */
219310d63b7dSRichard Lowe /* Targets that do must be reprocessed by doname() each time around */
219410d63b7dSRichard Lowe /* since the macro values used when building the target might have */
219510d63b7dSRichard Lowe /* changed */
219610d63b7dSRichard Lowe conditional_macro_used = false;
219710d63b7dSRichard Lowe /* If we are building a lib.a(member) target $@ should be bound */
219810d63b7dSRichard Lowe /* to lib.a */
219910d63b7dSRichard Lowe if (target->is_member &&
220010d63b7dSRichard Lowe ((member = get_prop(target->prop, member_prop)) != NULL)) {
220110d63b7dSRichard Lowe target = member->body.member.library;
220210d63b7dSRichard Lowe }
220310d63b7dSRichard Lowe /* If we are building a "::" help target $@ should be bound to */
220410d63b7dSRichard Lowe /* the real target name */
220510d63b7dSRichard Lowe /* A lib.a(member) target is never :: */
220610d63b7dSRichard Lowe if (target->has_target_prop) {
220710d63b7dSRichard Lowe target = get_prop(target->prop, target_prop)->
220810d63b7dSRichard Lowe body.target.target;
220910d63b7dSRichard Lowe }
221010d63b7dSRichard Lowe /* Bind the magic macros that make supplies */
221110d63b7dSRichard Lowe tmp_name = target;
221210d63b7dSRichard Lowe if(tmp_name != NULL) {
221310d63b7dSRichard Lowe if (tmp_name->has_vpath_alias_prop) {
221410d63b7dSRichard Lowe tmp_name = get_prop(tmp_name->prop, vpath_alias_prop)->
221510d63b7dSRichard Lowe body.vpath_alias.alias;
221610d63b7dSRichard Lowe }
221710d63b7dSRichard Lowe }
221810d63b7dSRichard Lowe (void) SETVAR(c_at, tmp_name, false);
221910d63b7dSRichard Lowe
222010d63b7dSRichard Lowe tmp_name = line->body.line.star;
222110d63b7dSRichard Lowe if(tmp_name != NULL) {
222210d63b7dSRichard Lowe if (tmp_name->has_vpath_alias_prop) {
222310d63b7dSRichard Lowe tmp_name = get_prop(tmp_name->prop, vpath_alias_prop)->
222410d63b7dSRichard Lowe body.vpath_alias.alias;
222510d63b7dSRichard Lowe }
222610d63b7dSRichard Lowe }
222710d63b7dSRichard Lowe (void) SETVAR(star, tmp_name, false);
222810d63b7dSRichard Lowe
222910d63b7dSRichard Lowe tmp_name = line->body.line.less;
223010d63b7dSRichard Lowe if(tmp_name != NULL) {
223110d63b7dSRichard Lowe if (tmp_name->has_vpath_alias_prop) {
223210d63b7dSRichard Lowe tmp_name = get_prop(tmp_name->prop, vpath_alias_prop)->
223310d63b7dSRichard Lowe body.vpath_alias.alias;
223410d63b7dSRichard Lowe }
223510d63b7dSRichard Lowe }
223610d63b7dSRichard Lowe (void) SETVAR(less_name, tmp_name, false);
223710d63b7dSRichard Lowe
223810d63b7dSRichard Lowe tmp_name = line->body.line.percent;
223910d63b7dSRichard Lowe if(tmp_name != NULL) {
224010d63b7dSRichard Lowe if (tmp_name->has_vpath_alias_prop) {
224110d63b7dSRichard Lowe tmp_name = get_prop(tmp_name->prop, vpath_alias_prop)->
224210d63b7dSRichard Lowe body.vpath_alias.alias;
224310d63b7dSRichard Lowe }
224410d63b7dSRichard Lowe }
224510d63b7dSRichard Lowe (void) SETVAR(percent_name, tmp_name, false);
224610d63b7dSRichard Lowe
224710d63b7dSRichard Lowe /* $? is seldom used and it is expensive to build */
224810d63b7dSRichard Lowe /* so we store the list form and build the string on demand */
224910d63b7dSRichard Lowe Chain query_list = NULL;
225010d63b7dSRichard Lowe Chain *query_list_tail = &query_list;
225110d63b7dSRichard Lowe
225210d63b7dSRichard Lowe for (Chain ch = line->body.line.query; ch != NULL; ch = ch->next) {
225310d63b7dSRichard Lowe *query_list_tail = ALLOC(Chain);
225410d63b7dSRichard Lowe (*query_list_tail)->name = ch->name;
225510d63b7dSRichard Lowe if ((*query_list_tail)->name->has_vpath_alias_prop) {
225610d63b7dSRichard Lowe (*query_list_tail)->name =
225710d63b7dSRichard Lowe get_prop((*query_list_tail)->name->prop,
225810d63b7dSRichard Lowe vpath_alias_prop)->body.vpath_alias.alias;
225910d63b7dSRichard Lowe }
226010d63b7dSRichard Lowe (*query_list_tail)->next = NULL;
226110d63b7dSRichard Lowe query_list_tail = &(*query_list_tail)->next;
226210d63b7dSRichard Lowe }
226310d63b7dSRichard Lowe (void) setvar_daemon(query,
226410d63b7dSRichard Lowe (Name) query_list,
226510d63b7dSRichard Lowe false,
226610d63b7dSRichard Lowe chain_daemon,
226710d63b7dSRichard Lowe false,
226810d63b7dSRichard Lowe debug_level);
226910d63b7dSRichard Lowe
227010d63b7dSRichard Lowe /* build $^ */
227110d63b7dSRichard Lowe Chain hat_list = NULL;
227210d63b7dSRichard Lowe Chain *hat_list_tail = &hat_list;
227310d63b7dSRichard Lowe
227448bbca81SDaniel Hoffman for (Dependency dependency = line->body.line.dependencies;
227510d63b7dSRichard Lowe dependency != NULL;
227610d63b7dSRichard Lowe dependency = dependency->next) {
227710d63b7dSRichard Lowe /* skip automatic dependencies */
227810d63b7dSRichard Lowe if (!dependency->automatic) {
227910d63b7dSRichard Lowe if ((dependency->name != force) &&
228010d63b7dSRichard Lowe (dependency->stale == false)) {
228110d63b7dSRichard Lowe *hat_list_tail = ALLOC(Chain);
228248bbca81SDaniel Hoffman
228310d63b7dSRichard Lowe if (dependency->name->is_member &&
228410d63b7dSRichard Lowe (get_prop(dependency->name->prop, member_prop) != NULL)) {
228548bbca81SDaniel Hoffman (*hat_list_tail)->name =
228610d63b7dSRichard Lowe get_prop(dependency->name->prop,
228710d63b7dSRichard Lowe member_prop)->body.member.member;
228810d63b7dSRichard Lowe } else {
228910d63b7dSRichard Lowe (*hat_list_tail)->name = dependency->name;
229010d63b7dSRichard Lowe }
229110d63b7dSRichard Lowe
229210d63b7dSRichard Lowe if((*hat_list_tail)->name != NULL) {
229310d63b7dSRichard Lowe if ((*hat_list_tail)->name->has_vpath_alias_prop) {
229410d63b7dSRichard Lowe (*hat_list_tail)->name =
229510d63b7dSRichard Lowe get_prop((*hat_list_tail)->name->prop,
229610d63b7dSRichard Lowe vpath_alias_prop)->body.vpath_alias.alias;
229710d63b7dSRichard Lowe }
229810d63b7dSRichard Lowe }
229910d63b7dSRichard Lowe
230010d63b7dSRichard Lowe (*hat_list_tail)->next = NULL;
230110d63b7dSRichard Lowe hat_list_tail = &(*hat_list_tail)->next;
230210d63b7dSRichard Lowe }
230310d63b7dSRichard Lowe }
230410d63b7dSRichard Lowe }
230510d63b7dSRichard Lowe (void) setvar_daemon(hat,
230610d63b7dSRichard Lowe (Name) hat_list,
230710d63b7dSRichard Lowe false,
230810d63b7dSRichard Lowe chain_daemon,
230910d63b7dSRichard Lowe false,
231010d63b7dSRichard Lowe debug_level);
231110d63b7dSRichard Lowe
231210d63b7dSRichard Lowe /* We have two command sequences we need to handle */
231310d63b7dSRichard Lowe /* The old one that we probably read from .make.state */
231410d63b7dSRichard Lowe /* and the new one we are building that will replace the old one */
231510d63b7dSRichard Lowe /* Even when KEEP_STATE is not on we build a new command sequence and store */
231610d63b7dSRichard Lowe /* it in the line prop. This command sequence is then executed by */
231710d63b7dSRichard Lowe /* run_command(). If KEEP_STATE is on it is also later written to */
231810d63b7dSRichard Lowe /* .make.state. The routine replaces the old command line by line with the */
231910d63b7dSRichard Lowe /* new one trying to reuse Cmd_lines */
232010d63b7dSRichard Lowe
232110d63b7dSRichard Lowe /* If there is no old command_used we have to start creating */
232210d63b7dSRichard Lowe /* Cmd_lines to keep the new cmd in */
232310d63b7dSRichard Lowe if (used == NULL) {
232410d63b7dSRichard Lowe new_command_longer = true;
232510d63b7dSRichard Lowe *insert = used = ALLOC(Cmd_line);
232610d63b7dSRichard Lowe used->next = NULL;
232710d63b7dSRichard Lowe used->command_line = NULL;
232810d63b7dSRichard Lowe insert = &used->next;
232910d63b7dSRichard Lowe }
233010d63b7dSRichard Lowe /* Run thru the template for the new command and build the expanded */
233110d63b7dSRichard Lowe /* new command lines */
233210d63b7dSRichard Lowe for (;
233310d63b7dSRichard Lowe command_template != NULL;
233410d63b7dSRichard Lowe command_template = command_template->next, insert = &used->next, used = *insert) {
233510d63b7dSRichard Lowe /* If there is no old command_used Cmd_line we need to */
233610d63b7dSRichard Lowe /* create one and say that cmd consistency failed */
233710d63b7dSRichard Lowe if (used == NULL) {
233810d63b7dSRichard Lowe new_command_longer = true;
233910d63b7dSRichard Lowe *insert = used = ALLOC(Cmd_line);
234010d63b7dSRichard Lowe used->next = NULL;
234110d63b7dSRichard Lowe used->command_line = empty_name;
234210d63b7dSRichard Lowe }
234310d63b7dSRichard Lowe /* Prepare the Cmd_line for the processing */
234410d63b7dSRichard Lowe /* The command line prefixes "@-=?" are stripped and that */
234510d63b7dSRichard Lowe /* information is saved in the Cmd_line */
234610d63b7dSRichard Lowe used->assign = false;
234710d63b7dSRichard Lowe used->ignore_error = ignore_errors;
234810d63b7dSRichard Lowe used->silent = silent;
234910d63b7dSRichard Lowe used->always_exec = false;
235010d63b7dSRichard Lowe /* Expand the macros in the command line */
235110d63b7dSRichard Lowe INIT_STRING_FROM_STACK(command_line, buffer);
235210d63b7dSRichard Lowe make_word_mentioned =
235310d63b7dSRichard Lowe query_mentioned =
235410d63b7dSRichard Lowe false;
235510d63b7dSRichard Lowe expand_value(command_template->command_line, &command_line, true);
235610d63b7dSRichard Lowe /* If the macro $(MAKE) is mentioned in the command */
235710d63b7dSRichard Lowe /* "make -n" runs actually execute the command */
235810d63b7dSRichard Lowe used->make_refd = make_word_mentioned;
235910d63b7dSRichard Lowe used->ignore_command_dependency = query_mentioned;
236010d63b7dSRichard Lowe /* Strip the prefixes */
236110d63b7dSRichard Lowe start = command_line.buffer.start;
236210d63b7dSRichard Lowe for (;
236310d63b7dSRichard Lowe iswspace(*start) ||
236410d63b7dSRichard Lowe (get_char_semantics_value(*start) & (int) command_prefix_sem);
236510d63b7dSRichard Lowe start++) {
236610d63b7dSRichard Lowe switch (*start) {
236710d63b7dSRichard Lowe case question_char:
236810d63b7dSRichard Lowe used->ignore_command_dependency = true;
236910d63b7dSRichard Lowe break;
237010d63b7dSRichard Lowe case exclam_char:
237110d63b7dSRichard Lowe used->ignore_command_dependency = false;
237210d63b7dSRichard Lowe break;
237310d63b7dSRichard Lowe case equal_char:
237410d63b7dSRichard Lowe used->assign = true;
237510d63b7dSRichard Lowe break;
237610d63b7dSRichard Lowe case hyphen_char:
237710d63b7dSRichard Lowe used->ignore_error = true;
237810d63b7dSRichard Lowe break;
237910d63b7dSRichard Lowe case at_char:
238010d63b7dSRichard Lowe if (!do_not_exec_rule) {
238110d63b7dSRichard Lowe used->silent = true;
238210d63b7dSRichard Lowe }
238310d63b7dSRichard Lowe break;
238410d63b7dSRichard Lowe case plus_char:
238510d63b7dSRichard Lowe if(posix) {
238610d63b7dSRichard Lowe used->always_exec = true;
238710d63b7dSRichard Lowe }
238810d63b7dSRichard Lowe break;
238910d63b7dSRichard Lowe }
239010d63b7dSRichard Lowe }
239110d63b7dSRichard Lowe /* If all command lines of the template are prefixed with "?"*/
239210d63b7dSRichard Lowe /* the VIRTUAL_ROOT is not used for cmd consistency checks */
239310d63b7dSRichard Lowe if (!used->ignore_command_dependency) {
239410d63b7dSRichard Lowe ignore_all_command_dependency = false;
239510d63b7dSRichard Lowe }
239610d63b7dSRichard Lowe /* Internalize the expanded and stripped command line */
239710d63b7dSRichard Lowe new_command_line = GETNAME(start, FIND_LENGTH);
239810d63b7dSRichard Lowe if ((used->command_line == NULL) &&
239910d63b7dSRichard Lowe (line->body.line.sccs_command)) {
240010d63b7dSRichard Lowe used->command_line = new_command_line;
240110d63b7dSRichard Lowe new_command_longer = false;
240210d63b7dSRichard Lowe }
240310d63b7dSRichard Lowe /* Compare it with the old one for command consistency */
240410d63b7dSRichard Lowe if (used->command_line != new_command_line) {
240510d63b7dSRichard Lowe Name vpath_translated = vpath_translation(new_command_line);
240610d63b7dSRichard Lowe if (keep_state &&
240710d63b7dSRichard Lowe !used->ignore_command_dependency && (vpath_translated != used->command_line)) {
240810d63b7dSRichard Lowe if (debug_level > 0) {
240910d63b7dSRichard Lowe if (used->command_line != NULL
241010d63b7dSRichard Lowe && *used->command_line->string_mb !=
241110d63b7dSRichard Lowe '\0') {
241210d63b7dSRichard Lowe (void) printf(gettext("%*sBuilding %s because new command \n\t%s\n%*sdifferent from old\n\t%s\n"),
241310d63b7dSRichard Lowe recursion_level,
241410d63b7dSRichard Lowe "",
241510d63b7dSRichard Lowe target->string_mb,
241610d63b7dSRichard Lowe vpath_translated->string_mb,
241710d63b7dSRichard Lowe recursion_level,
241810d63b7dSRichard Lowe "",
241910d63b7dSRichard Lowe used->
242010d63b7dSRichard Lowe command_line->
242110d63b7dSRichard Lowe string_mb);
242210d63b7dSRichard Lowe } else {
242310d63b7dSRichard Lowe (void) printf(gettext("%*sBuilding %s because new command \n\t%s\n%*sdifferent from empty old command\n"),
242410d63b7dSRichard Lowe recursion_level,
242510d63b7dSRichard Lowe "",
242610d63b7dSRichard Lowe target->string_mb,
242710d63b7dSRichard Lowe vpath_translated->string_mb,
242810d63b7dSRichard Lowe recursion_level,
242910d63b7dSRichard Lowe "");
243010d63b7dSRichard Lowe }
243110d63b7dSRichard Lowe }
243210d63b7dSRichard Lowe command_changed = true;
243310d63b7dSRichard Lowe line->body.line.is_out_of_date = true;
243410d63b7dSRichard Lowe }
243510d63b7dSRichard Lowe used->command_line = new_command_line;
243610d63b7dSRichard Lowe }
243710d63b7dSRichard Lowe if (command_line.free_after_use) {
243810d63b7dSRichard Lowe retmem(command_line.buffer.start);
243910d63b7dSRichard Lowe }
244010d63b7dSRichard Lowe }
244110d63b7dSRichard Lowe /* Check if the old command is longer than the new for */
244210d63b7dSRichard Lowe /* command consistency */
244310d63b7dSRichard Lowe if (used != NULL) {
244410d63b7dSRichard Lowe *insert = NULL;
244510d63b7dSRichard Lowe if (keep_state &&
244610d63b7dSRichard Lowe !ignore_all_command_dependency) {
244710d63b7dSRichard Lowe if (debug_level > 0) {
244810d63b7dSRichard Lowe (void) printf(gettext("%*sBuilding %s because new command shorter than old\n"),
244910d63b7dSRichard Lowe recursion_level,
245010d63b7dSRichard Lowe "",
245110d63b7dSRichard Lowe target->string_mb);
245210d63b7dSRichard Lowe }
245310d63b7dSRichard Lowe command_changed = true;
245410d63b7dSRichard Lowe line->body.line.is_out_of_date = true;
245510d63b7dSRichard Lowe }
245610d63b7dSRichard Lowe }
245710d63b7dSRichard Lowe /* Check if the new command is longer than the old command for */
245810d63b7dSRichard Lowe /* command consistency */
245910d63b7dSRichard Lowe if (new_command_longer &&
246010d63b7dSRichard Lowe !ignore_all_command_dependency &&
246110d63b7dSRichard Lowe keep_state) {
246210d63b7dSRichard Lowe if (debug_level > 0) {
246310d63b7dSRichard Lowe (void) printf(gettext("%*sBuilding %s because new command longer than old\n"),
246410d63b7dSRichard Lowe recursion_level,
246510d63b7dSRichard Lowe "",
246610d63b7dSRichard Lowe target->string_mb);
246710d63b7dSRichard Lowe }
246810d63b7dSRichard Lowe command_changed = true;
246910d63b7dSRichard Lowe line->body.line.is_out_of_date = true;
247010d63b7dSRichard Lowe }
247110d63b7dSRichard Lowe /* Unbind the magic macros */
247210d63b7dSRichard Lowe (void) SETVAR(c_at, (Name) NULL, false);
247310d63b7dSRichard Lowe (void) SETVAR(star, (Name) NULL, false);
247410d63b7dSRichard Lowe (void) SETVAR(less_name, (Name) NULL, false);
247510d63b7dSRichard Lowe (void) SETVAR(percent_name, (Name) NULL, false);
247610d63b7dSRichard Lowe (void) SETVAR(query, (Name) NULL, false);
247710d63b7dSRichard Lowe if (query_list != NULL) {
24782e8f3c34SToomas Soome delete_query_chain(query_list);
247910d63b7dSRichard Lowe }
248010d63b7dSRichard Lowe (void) SETVAR(hat, (Name) NULL, false);
248110d63b7dSRichard Lowe if (hat_list != NULL) {
24822e8f3c34SToomas Soome delete_query_chain(hat_list);
248310d63b7dSRichard Lowe }
248410d63b7dSRichard Lowe
248510d63b7dSRichard Lowe if (conditional_macro_used) {
248610d63b7dSRichard Lowe target->conditional_macro_list = cond_macro_list;
248710d63b7dSRichard Lowe cond_macro_list = NULL;
248810d63b7dSRichard Lowe target->depends_on_conditional = true;
248910d63b7dSRichard Lowe }
249010d63b7dSRichard Lowe }
249110d63b7dSRichard Lowe
249210d63b7dSRichard Lowe /*
249310d63b7dSRichard Lowe * touch_command(line, target, result)
249410d63b7dSRichard Lowe *
249510d63b7dSRichard Lowe * If this is an "make -t" run we do this.
249610d63b7dSRichard Lowe * We touch all targets in the target group ("foo + fie:") if any.
249710d63b7dSRichard Lowe *
249810d63b7dSRichard Lowe * Return value:
249910d63b7dSRichard Lowe * Indicates if the command failed or not
250010d63b7dSRichard Lowe *
250110d63b7dSRichard Lowe * Parameters:
250210d63b7dSRichard Lowe * line The command line to update
250310d63b7dSRichard Lowe * target The target we are touching
250410d63b7dSRichard Lowe * result Initial value for the result we return
250510d63b7dSRichard Lowe *
250610d63b7dSRichard Lowe * Global variables used:
250710d63b7dSRichard Lowe * do_not_exec_rule Indicates that -n is on
250810d63b7dSRichard Lowe * silent Do not echo commands
250910d63b7dSRichard Lowe */
251010d63b7dSRichard Lowe static Doname
touch_command(Property line,Name target,Doname result)2511*e7afc443SToomas Soome touch_command(Property line, Name target, Doname result)
251210d63b7dSRichard Lowe {
251310d63b7dSRichard Lowe Name name;
2514*e7afc443SToomas Soome Chain target_group;
251510d63b7dSRichard Lowe String_rec touch_string;
251610d63b7dSRichard Lowe wchar_t buffer[MAXPATHLEN];
251710d63b7dSRichard Lowe Name touch_cmd;
251810d63b7dSRichard Lowe Cmd_line rule;
251910d63b7dSRichard Lowe
252010d63b7dSRichard Lowe for (name = target, target_group = NULL; name != NULL;) {
252110d63b7dSRichard Lowe if (!name->is_member) {
252210d63b7dSRichard Lowe /*
252310d63b7dSRichard Lowe * Build a touch command that can be passed
252410d63b7dSRichard Lowe * to dosys(). If KEEP_STATE is on, "make -t"
252510d63b7dSRichard Lowe * will save the proper command, not the
252610d63b7dSRichard Lowe * "touch" in .make.state.
252710d63b7dSRichard Lowe */
252810d63b7dSRichard Lowe INIT_STRING_FROM_STACK(touch_string, buffer);
252910d63b7dSRichard Lowe MBSTOWCS(wcs_buffer, "touch ");
253010d63b7dSRichard Lowe append_string(wcs_buffer, &touch_string, FIND_LENGTH);
253110d63b7dSRichard Lowe touch_cmd = name;
253210d63b7dSRichard Lowe if (name->has_vpath_alias_prop) {
253310d63b7dSRichard Lowe touch_cmd = get_prop(name->prop,
253410d63b7dSRichard Lowe vpath_alias_prop)->
253510d63b7dSRichard Lowe body.vpath_alias.alias;
253610d63b7dSRichard Lowe }
253710d63b7dSRichard Lowe APPEND_NAME(touch_cmd,
253810d63b7dSRichard Lowe &touch_string,
253910d63b7dSRichard Lowe FIND_LENGTH);
254010d63b7dSRichard Lowe touch_cmd = GETNAME(touch_string.buffer.start,
254110d63b7dSRichard Lowe FIND_LENGTH);
254210d63b7dSRichard Lowe if (touch_string.free_after_use) {
254310d63b7dSRichard Lowe retmem(touch_string.buffer.start);
254410d63b7dSRichard Lowe }
254510d63b7dSRichard Lowe if (!silent ||
254610d63b7dSRichard Lowe do_not_exec_rule &&
254710d63b7dSRichard Lowe (target_group == NULL)) {
254810d63b7dSRichard Lowe (void) printf("%s\n", touch_cmd->string_mb);
254910d63b7dSRichard Lowe }
255010d63b7dSRichard Lowe /* Run the touch command, or simulate it */
255110d63b7dSRichard Lowe if (!do_not_exec_rule) {
255210d63b7dSRichard Lowe result = dosys(touch_cmd,
255310d63b7dSRichard Lowe false,
255410d63b7dSRichard Lowe false,
255510d63b7dSRichard Lowe false,
255610d63b7dSRichard Lowe false,
255710d63b7dSRichard Lowe name);
255810d63b7dSRichard Lowe } else {
255910d63b7dSRichard Lowe result = build_ok;
256010d63b7dSRichard Lowe }
256110d63b7dSRichard Lowe } else {
256210d63b7dSRichard Lowe result = build_ok;
256310d63b7dSRichard Lowe }
256410d63b7dSRichard Lowe if (target_group == NULL) {
256510d63b7dSRichard Lowe target_group = line->body.line.target_group;
256610d63b7dSRichard Lowe } else {
256710d63b7dSRichard Lowe target_group = target_group->next;
256810d63b7dSRichard Lowe }
256910d63b7dSRichard Lowe if (target_group != NULL) {
257010d63b7dSRichard Lowe name = target_group->name;
257110d63b7dSRichard Lowe } else {
257210d63b7dSRichard Lowe name = NULL;
257310d63b7dSRichard Lowe }
257410d63b7dSRichard Lowe }
257510d63b7dSRichard Lowe return result;
257610d63b7dSRichard Lowe }
257710d63b7dSRichard Lowe
257810d63b7dSRichard Lowe /*
257910d63b7dSRichard Lowe * update_target(line, result)
258010d63b7dSRichard Lowe *
258110d63b7dSRichard Lowe * updates the status of a target after executing its commands.
258210d63b7dSRichard Lowe *
258310d63b7dSRichard Lowe * Parameters:
258410d63b7dSRichard Lowe * line The command line block to update
258510d63b7dSRichard Lowe * result Indicates that build is OK so can update
258610d63b7dSRichard Lowe *
258710d63b7dSRichard Lowe * Global variables used:
258810d63b7dSRichard Lowe * do_not_exec_rule Indicates that -n is on
258910d63b7dSRichard Lowe * touch Fake the new timestamp if we are just touching
259010d63b7dSRichard Lowe */
259110d63b7dSRichard Lowe void
update_target(Property line,Doname result)259210d63b7dSRichard Lowe update_target(Property line, Doname result)
259310d63b7dSRichard Lowe {
259410d63b7dSRichard Lowe Name target;
259510d63b7dSRichard Lowe Chain target_group;
259610d63b7dSRichard Lowe Property line2;
259710d63b7dSRichard Lowe timestruc_t old_stat_time;
259810d63b7dSRichard Lowe Property member;
259910d63b7dSRichard Lowe
260010d63b7dSRichard Lowe /*
260110d63b7dSRichard Lowe * [tolik] Additional fix for bug 1063790. It was fixed
260210d63b7dSRichard Lowe * for serial make long ago, but DMake dumps core when
260348bbca81SDaniel Hoffman * target is a symlink and sccs file is newer then target.
260410d63b7dSRichard Lowe * In this case, finish_children() calls update_target()
260510d63b7dSRichard Lowe * with line==NULL.
260610d63b7dSRichard Lowe */
260710d63b7dSRichard Lowe if(line == NULL) {
260810d63b7dSRichard Lowe /* XXX. Should we do anything here? */
260910d63b7dSRichard Lowe return;
261048bbca81SDaniel Hoffman }
261110d63b7dSRichard Lowe
261210d63b7dSRichard Lowe target = line->body.line.target;
261310d63b7dSRichard Lowe
261410d63b7dSRichard Lowe if ((result == build_ok) && (line->body.line.command_used != NULL)) {
261510d63b7dSRichard Lowe if (do_not_exec_rule ||
261610d63b7dSRichard Lowe touch ||
261710d63b7dSRichard Lowe (target->is_member &&
261810d63b7dSRichard Lowe (line->body.line.command_template != NULL) &&
261910d63b7dSRichard Lowe (line->body.line.command_template->command_line->string_mb[0] == 0) &&
262010d63b7dSRichard Lowe (line->body.line.command_template->next == NULL))) {
262110d63b7dSRichard Lowe /* If we are simulating execution we need to fake a */
262210d63b7dSRichard Lowe /* new timestamp for the target we didnt build */
262310d63b7dSRichard Lowe target->stat.time = file_max_time;
262410d63b7dSRichard Lowe } else {
262510d63b7dSRichard Lowe /*
262610d63b7dSRichard Lowe * If we really built the target we read the new
262710d63b7dSRichard Lowe * timestamp.
262810d63b7dSRichard Lowe * Fix for bug #1110906: if .c file is newer than
262910d63b7dSRichard Lowe * the corresponding .o file which is in an archive
263010d63b7dSRichard Lowe * file, make will compile the .c file but it won't
263110d63b7dSRichard Lowe * update the object in the .a file.
263210d63b7dSRichard Lowe */
263310d63b7dSRichard Lowe old_stat_time = target->stat.time;
263410d63b7dSRichard Lowe target->stat.time = file_no_time;
263510d63b7dSRichard Lowe (void) exists(target);
263610d63b7dSRichard Lowe if ((target->is_member) &&
263710d63b7dSRichard Lowe (target->stat.time == old_stat_time)) {
263810d63b7dSRichard Lowe member = get_prop(target->prop, member_prop);
263910d63b7dSRichard Lowe if (member != NULL) {
264010d63b7dSRichard Lowe target->stat.time = member->body.member.library->stat.time;
264110d63b7dSRichard Lowe target->stat.time.tv_sec++;
264210d63b7dSRichard Lowe }
264310d63b7dSRichard Lowe }
264410d63b7dSRichard Lowe }
264510d63b7dSRichard Lowe /* If the target is part of a group we need to propagate the */
264610d63b7dSRichard Lowe /* result of the run to all members */
264710d63b7dSRichard Lowe for (target_group = line->body.line.target_group;
264810d63b7dSRichard Lowe target_group != NULL;
264910d63b7dSRichard Lowe target_group = target_group->next) {
265010d63b7dSRichard Lowe target_group->name->stat.time = target->stat.time;
265110d63b7dSRichard Lowe line2 = maybe_append_prop(target_group->name,
265210d63b7dSRichard Lowe line_prop);
265310d63b7dSRichard Lowe line2->body.line.command_used =
265410d63b7dSRichard Lowe line->body.line.command_used;
265510d63b7dSRichard Lowe line2->body.line.target = target_group->name;
265610d63b7dSRichard Lowe }
265710d63b7dSRichard Lowe }
265810d63b7dSRichard Lowe target->has_built = true;
265910d63b7dSRichard Lowe }
266010d63b7dSRichard Lowe
266110d63b7dSRichard Lowe /*
266210d63b7dSRichard Lowe * sccs_get(target, command)
266310d63b7dSRichard Lowe *
266410d63b7dSRichard Lowe * Figures out if it possible to sccs get a file
266510d63b7dSRichard Lowe * and builds the command to do it if it is.
266610d63b7dSRichard Lowe *
266710d63b7dSRichard Lowe * Return value:
266810d63b7dSRichard Lowe * Indicates if sccs get failed or not
266910d63b7dSRichard Lowe *
267010d63b7dSRichard Lowe * Parameters:
267110d63b7dSRichard Lowe * target Target to get
267210d63b7dSRichard Lowe * command Where to deposit command to use
267310d63b7dSRichard Lowe *
267410d63b7dSRichard Lowe * Global variables used:
267510d63b7dSRichard Lowe * debug_level Should we trace activities?
267610d63b7dSRichard Lowe * recursion_level Used for tracing
267710d63b7dSRichard Lowe * sccs_get_rule The rule to used for sccs getting
267810d63b7dSRichard Lowe */
267910d63b7dSRichard Lowe static Doname
sccs_get(Name target,Property * command)2680*e7afc443SToomas Soome sccs_get(Name target, Property *command)
268110d63b7dSRichard Lowe {
2682*e7afc443SToomas Soome int result;
268310d63b7dSRichard Lowe char link[MAXPATHLEN];
268410d63b7dSRichard Lowe String_rec string;
268510d63b7dSRichard Lowe wchar_t name[MAXPATHLEN];
2686*e7afc443SToomas Soome wchar_t *p;
268710d63b7dSRichard Lowe timestruc_t sccs_time;
2688*e7afc443SToomas Soome Property line;
268910d63b7dSRichard Lowe int sym_link_depth = 0;
269010d63b7dSRichard Lowe
269110d63b7dSRichard Lowe /* For sccs, we need to chase symlinks. */
269210d63b7dSRichard Lowe while (target->stat.is_sym_link) {
269310d63b7dSRichard Lowe if (sym_link_depth++ > 90) {
269410d63b7dSRichard Lowe fatal(gettext("Can't read symbolic link `%s': Number of symbolic links encountered during path name traversal exceeds 90."),
269510d63b7dSRichard Lowe target->string_mb);
269610d63b7dSRichard Lowe }
269710d63b7dSRichard Lowe /* Read the value of the link. */
269810d63b7dSRichard Lowe result = readlink_vroot(target->string_mb,
269910d63b7dSRichard Lowe link,
270010d63b7dSRichard Lowe sizeof(link),
270110d63b7dSRichard Lowe NULL,
270210d63b7dSRichard Lowe VROOT_DEFAULT);
270310d63b7dSRichard Lowe if (result == -1) {
270410d63b7dSRichard Lowe fatal(gettext("Can't read symbolic link `%s': %s"),
270510d63b7dSRichard Lowe target->string_mb, errmsg(errno));
270610d63b7dSRichard Lowe }
270710d63b7dSRichard Lowe link[result] = 0;
270810d63b7dSRichard Lowe /* Use the value to build the proper filename. */
270910d63b7dSRichard Lowe INIT_STRING_FROM_STACK(string, name);
271010d63b7dSRichard Lowe
271110d63b7dSRichard Lowe Wstring wcb(target);
271210d63b7dSRichard Lowe if ((link[0] != slash_char) &&
271310d63b7dSRichard Lowe ((p = (wchar_t *) wcsrchr(wcb.get_string(), slash_char)) != NULL)) {
271410d63b7dSRichard Lowe append_string(wcb.get_string(), &string, p - wcb.get_string() + 1);
271510d63b7dSRichard Lowe }
271610d63b7dSRichard Lowe append_string(link, &string, result);
271710d63b7dSRichard Lowe /* Replace the old name with the translated name. */
271810d63b7dSRichard Lowe target = normalize_name(string.buffer.start, string.text.p - string.buffer.start);
271910d63b7dSRichard Lowe (void) exists(target);
272010d63b7dSRichard Lowe if (string.free_after_use) {
272110d63b7dSRichard Lowe retmem(string.buffer.start);
272210d63b7dSRichard Lowe }
272310d63b7dSRichard Lowe }
272410d63b7dSRichard Lowe
272510d63b7dSRichard Lowe /*
272610d63b7dSRichard Lowe * read_dir() also reads the ?/SCCS dir and saves information
272710d63b7dSRichard Lowe * about which files have SCSC/s. files.
272810d63b7dSRichard Lowe */
272910d63b7dSRichard Lowe if (target->stat.has_sccs == DONT_KNOW_SCCS) {
273010d63b7dSRichard Lowe read_directory_of_file(target);
273110d63b7dSRichard Lowe }
273210d63b7dSRichard Lowe switch (target->stat.has_sccs) {
273310d63b7dSRichard Lowe case DONT_KNOW_SCCS:
273410d63b7dSRichard Lowe /* We dont know by now there is no SCCS/s.* */
273510d63b7dSRichard Lowe target->stat.has_sccs = NO_SCCS;
27368e0c8248SAndrew Stormont /* FALLTHROUGH */
273710d63b7dSRichard Lowe case NO_SCCS:
273810d63b7dSRichard Lowe /*
273910d63b7dSRichard Lowe * If there is no SCCS/s.* but the plain file exists,
274010d63b7dSRichard Lowe * we say things are OK.
274110d63b7dSRichard Lowe */
274210d63b7dSRichard Lowe if (target->stat.time > file_doesnt_exist) {
274310d63b7dSRichard Lowe return build_ok;
274410d63b7dSRichard Lowe }
274510d63b7dSRichard Lowe /* If we cant find the plain file, we give up. */
274610d63b7dSRichard Lowe return build_dont_know;
274710d63b7dSRichard Lowe case HAS_SCCS:
274810d63b7dSRichard Lowe /*
274910d63b7dSRichard Lowe * Pay dirt. We now need to figure out if the plain file
275010d63b7dSRichard Lowe * is out of date relative to the SCCS/s.* file.
275110d63b7dSRichard Lowe */
275210d63b7dSRichard Lowe sccs_time = exists(get_prop(target->prop,
275310d63b7dSRichard Lowe sccs_prop)->body.sccs.file);
275410d63b7dSRichard Lowe break;
275510d63b7dSRichard Lowe }
275610d63b7dSRichard Lowe
275710d63b7dSRichard Lowe if ((!target->has_complained &&
275810d63b7dSRichard Lowe (sccs_time != file_doesnt_exist) &&
275910d63b7dSRichard Lowe (sccs_get_rule != NULL))) {
276010d63b7dSRichard Lowe /* only checking */
276110d63b7dSRichard Lowe if (command == NULL) {
276210d63b7dSRichard Lowe return build_ok;
276310d63b7dSRichard Lowe }
276410d63b7dSRichard Lowe /*
276510d63b7dSRichard Lowe * We provide a command line for the target. The line is a
276610d63b7dSRichard Lowe * "sccs get" command from default.mk.
276710d63b7dSRichard Lowe */
276810d63b7dSRichard Lowe line = maybe_append_prop(target, line_prop);
276910d63b7dSRichard Lowe *command = line;
277010d63b7dSRichard Lowe if (sccs_time > target->stat.time) {
277110d63b7dSRichard Lowe /*
277210d63b7dSRichard Lowe * And only if the plain file is out of date do we
277310d63b7dSRichard Lowe * request execution of the command.
277410d63b7dSRichard Lowe */
277510d63b7dSRichard Lowe line->body.line.is_out_of_date = true;
277610d63b7dSRichard Lowe if (debug_level > 0) {
277710d63b7dSRichard Lowe (void) printf(gettext("%*sSccs getting %s because s. file is younger than source file\n"),
277810d63b7dSRichard Lowe recursion_level,
277910d63b7dSRichard Lowe "",
278010d63b7dSRichard Lowe target->string_mb);
278110d63b7dSRichard Lowe }
278210d63b7dSRichard Lowe }
278310d63b7dSRichard Lowe line->body.line.sccs_command = true;
278410d63b7dSRichard Lowe line->body.line.command_template = sccs_get_rule;
278510d63b7dSRichard Lowe if(!svr4 && (!allrules_read || posix)) {
278610d63b7dSRichard Lowe if((target->prop) &&
278710d63b7dSRichard Lowe (target->prop->body.sccs.file) &&
278810d63b7dSRichard Lowe (target->prop->body.sccs.file->string_mb)) {
278910d63b7dSRichard Lowe if((strlen(target->prop->body.sccs.file->string_mb) ==
279048bbca81SDaniel Hoffman strlen(target->string_mb) + 2) &&
279110d63b7dSRichard Lowe (target->prop->body.sccs.file->string_mb[0] == 's') &&
279210d63b7dSRichard Lowe (target->prop->body.sccs.file->string_mb[1] == '.')) {
279310d63b7dSRichard Lowe
279410d63b7dSRichard Lowe line->body.line.command_template = get_posix_rule;
279510d63b7dSRichard Lowe }
279610d63b7dSRichard Lowe }
279710d63b7dSRichard Lowe }
279810d63b7dSRichard Lowe line->body.line.target = target;
279910d63b7dSRichard Lowe /*
280010d63b7dSRichard Lowe * Also make sure the rule is build with $* and $<
280110d63b7dSRichard Lowe * bound properly.
280210d63b7dSRichard Lowe */
280310d63b7dSRichard Lowe line->body.line.star = NULL;
280410d63b7dSRichard Lowe line->body.line.less = NULL;
280510d63b7dSRichard Lowe line->body.line.percent = NULL;
280610d63b7dSRichard Lowe return build_ok;
280710d63b7dSRichard Lowe }
280810d63b7dSRichard Lowe return build_dont_know;
280910d63b7dSRichard Lowe }
281010d63b7dSRichard Lowe
281110d63b7dSRichard Lowe /*
281210d63b7dSRichard Lowe * read_directory_of_file(file)
281310d63b7dSRichard Lowe *
281410d63b7dSRichard Lowe * Reads the directory the specified file lives in.
281510d63b7dSRichard Lowe *
281610d63b7dSRichard Lowe * Parameters:
281710d63b7dSRichard Lowe * file The file we need to read dir for
281810d63b7dSRichard Lowe *
281910d63b7dSRichard Lowe * Global variables used:
282010d63b7dSRichard Lowe * dot The Name ".", used as the default dir
282110d63b7dSRichard Lowe */
282210d63b7dSRichard Lowe void
read_directory_of_file(Name file)2823*e7afc443SToomas Soome read_directory_of_file(Name file)
282410d63b7dSRichard Lowe {
282510d63b7dSRichard Lowe
282610d63b7dSRichard Lowe Wstring file_string(file);
282710d63b7dSRichard Lowe wchar_t * wcb = file_string.get_string();
282810d63b7dSRichard Lowe wchar_t usr_include_buf[MAXPATHLEN];
282910d63b7dSRichard Lowe wchar_t usr_include_sys_buf[MAXPATHLEN];
283010d63b7dSRichard Lowe
2831*e7afc443SToomas Soome Name directory = dot;
2832*e7afc443SToomas Soome wchar_t *p = (wchar_t *) wcsrchr(wcb,
283310d63b7dSRichard Lowe (int) slash_char);
2834*e7afc443SToomas Soome int length = p - wcb;
283510d63b7dSRichard Lowe static Name usr_include;
283610d63b7dSRichard Lowe static Name usr_include_sys;
283710d63b7dSRichard Lowe
283810d63b7dSRichard Lowe if (usr_include == NULL) {
283910d63b7dSRichard Lowe MBSTOWCS(usr_include_buf, "/usr/include");
284010d63b7dSRichard Lowe usr_include = GETNAME(usr_include_buf, FIND_LENGTH);
284110d63b7dSRichard Lowe MBSTOWCS(usr_include_sys_buf, "/usr/include/sys");
284210d63b7dSRichard Lowe usr_include_sys = GETNAME(usr_include_sys_buf, FIND_LENGTH);
284310d63b7dSRichard Lowe }
284410d63b7dSRichard Lowe
284510d63b7dSRichard Lowe /*
284610d63b7dSRichard Lowe * If the filename contains a "/" we have to extract the path
284710d63b7dSRichard Lowe * Else the path defaults to ".".
284810d63b7dSRichard Lowe */
284910d63b7dSRichard Lowe if (p != NULL) {
285010d63b7dSRichard Lowe /*
285110d63b7dSRichard Lowe * Check some popular directories first to possibly
285210d63b7dSRichard Lowe * save time. Compare string length first to gain speed.
285310d63b7dSRichard Lowe */
285410d63b7dSRichard Lowe if ((usr_include->hash.length == length) &&
285510d63b7dSRichard Lowe IS_WEQUALN(usr_include_buf,
285610d63b7dSRichard Lowe wcb,
285710d63b7dSRichard Lowe length)) {
285810d63b7dSRichard Lowe directory = usr_include;
285910d63b7dSRichard Lowe } else if ((usr_include_sys->hash.length == length) &&
286010d63b7dSRichard Lowe IS_WEQUALN(usr_include_sys_buf,
286110d63b7dSRichard Lowe wcb,
286210d63b7dSRichard Lowe length)) {
286310d63b7dSRichard Lowe directory = usr_include_sys;
286410d63b7dSRichard Lowe } else {
286510d63b7dSRichard Lowe directory = GETNAME(wcb, length);
286610d63b7dSRichard Lowe }
286710d63b7dSRichard Lowe }
286810d63b7dSRichard Lowe (void) read_dir(directory,
286910d63b7dSRichard Lowe (wchar_t *) NULL,
287010d63b7dSRichard Lowe (Property) NULL,
287110d63b7dSRichard Lowe (wchar_t *) NULL);
287210d63b7dSRichard Lowe }
287310d63b7dSRichard Lowe
287410d63b7dSRichard Lowe /*
287510d63b7dSRichard Lowe * add_pattern_conditionals(target)
287610d63b7dSRichard Lowe *
287710d63b7dSRichard Lowe * Scan the list of conditionals defined for pattern targets and add any
287810d63b7dSRichard Lowe * that match this target to its list of conditionals.
287910d63b7dSRichard Lowe *
288010d63b7dSRichard Lowe * Parameters:
288110d63b7dSRichard Lowe * target The target we should add conditionals for
288210d63b7dSRichard Lowe *
288310d63b7dSRichard Lowe * Global variables used:
288410d63b7dSRichard Lowe * conditionals The list of pattern conditionals
288510d63b7dSRichard Lowe */
288610d63b7dSRichard Lowe static void
add_pattern_conditionals(Name target)2887*e7afc443SToomas Soome add_pattern_conditionals(Name target)
288810d63b7dSRichard Lowe {
2889*e7afc443SToomas Soome Property conditional;
289010d63b7dSRichard Lowe Property new_prop;
289110d63b7dSRichard Lowe Property *previous;
289210d63b7dSRichard Lowe Name_rec dummy;
289310d63b7dSRichard Lowe wchar_t *pattern;
289410d63b7dSRichard Lowe wchar_t *percent;
289510d63b7dSRichard Lowe int length;
289610d63b7dSRichard Lowe
289710d63b7dSRichard Lowe Wstring wcb(target);
289810d63b7dSRichard Lowe Wstring wcb1;
289910d63b7dSRichard Lowe
290010d63b7dSRichard Lowe for (conditional = get_prop(conditionals->prop, conditional_prop);
290110d63b7dSRichard Lowe conditional != NULL;
290210d63b7dSRichard Lowe conditional = get_prop(conditional->next, conditional_prop)) {
290310d63b7dSRichard Lowe wcb1.init(conditional->body.conditional.target);
290410d63b7dSRichard Lowe pattern = wcb1.get_string();
290510d63b7dSRichard Lowe if (pattern[1] != 0) {
290610d63b7dSRichard Lowe percent = (wchar_t *) wcschr(pattern, (int) percent_char);
290767c3092cSAndrew Stormont /* Check for possible buffer under-read */
290867c3092cSAndrew Stormont if ((length = wcb.length()-wcslen(percent+1)) <= 0) {
290967c3092cSAndrew Stormont continue;
291067c3092cSAndrew Stormont }
291110d63b7dSRichard Lowe if (!wcb.equaln(pattern, percent-pattern) ||
291267c3092cSAndrew Stormont !IS_WEQUAL(wcb.get_string(length), percent+1)) {
291310d63b7dSRichard Lowe continue;
291410d63b7dSRichard Lowe }
291510d63b7dSRichard Lowe }
291610d63b7dSRichard Lowe for (previous = &target->prop;
291710d63b7dSRichard Lowe *previous != NULL;
291810d63b7dSRichard Lowe previous = &(*previous)->next) {
291910d63b7dSRichard Lowe if (((*previous)->type == conditional_prop) &&
292010d63b7dSRichard Lowe ((*previous)->body.conditional.sequence >
292110d63b7dSRichard Lowe conditional->body.conditional.sequence)) {
292210d63b7dSRichard Lowe break;
292310d63b7dSRichard Lowe }
292410d63b7dSRichard Lowe }
292510d63b7dSRichard Lowe if (*previous == NULL) {
292610d63b7dSRichard Lowe new_prop = append_prop(target, conditional_prop);
292710d63b7dSRichard Lowe } else {
292810d63b7dSRichard Lowe dummy.prop = NULL;
292910d63b7dSRichard Lowe new_prop = append_prop(&dummy, conditional_prop);
293010d63b7dSRichard Lowe new_prop->next = *previous;
293110d63b7dSRichard Lowe *previous = new_prop;
293210d63b7dSRichard Lowe }
293310d63b7dSRichard Lowe target->conditional_cnt++;
293410d63b7dSRichard Lowe new_prop->body.conditional = conditional->body.conditional;
293510d63b7dSRichard Lowe }
293610d63b7dSRichard Lowe }
293710d63b7dSRichard Lowe
293810d63b7dSRichard Lowe /*
293910d63b7dSRichard Lowe * set_locals(target, old_locals)
294010d63b7dSRichard Lowe *
294110d63b7dSRichard Lowe * Sets any conditional macros for the target.
294210d63b7dSRichard Lowe * Each target carries a possibly empty set of conditional properties.
294310d63b7dSRichard Lowe *
294410d63b7dSRichard Lowe * Parameters:
294510d63b7dSRichard Lowe * target The target to set conditional macros for
294610d63b7dSRichard Lowe * old_locals Space to store old values in
294710d63b7dSRichard Lowe *
294810d63b7dSRichard Lowe * Global variables used:
294910d63b7dSRichard Lowe * debug_level Should we trace activity?
295010d63b7dSRichard Lowe * is_conditional We need to preserve this value
295110d63b7dSRichard Lowe * recursion_level Used for tracing
295210d63b7dSRichard Lowe */
295310d63b7dSRichard Lowe void
set_locals(Name target,Property old_locals)2954*e7afc443SToomas Soome set_locals(Name target, Property old_locals)
295510d63b7dSRichard Lowe {
2956*e7afc443SToomas Soome Property conditional;
2957*e7afc443SToomas Soome int i;
2958*e7afc443SToomas Soome Boolean saved_conditional_macro_used;
295910d63b7dSRichard Lowe Chain cond_name;
296010d63b7dSRichard Lowe Chain cond_chain;
296110d63b7dSRichard Lowe
296210d63b7dSRichard Lowe if (target->dont_activate_cond_values) {
296310d63b7dSRichard Lowe return;
296410d63b7dSRichard Lowe }
296510d63b7dSRichard Lowe
296610d63b7dSRichard Lowe saved_conditional_macro_used = conditional_macro_used;
296710d63b7dSRichard Lowe
296810d63b7dSRichard Lowe /* Scan the list of conditional properties and apply each one */
296910d63b7dSRichard Lowe for (conditional = get_prop(target->prop, conditional_prop), i = 0;
297010d63b7dSRichard Lowe conditional != NULL;
297110d63b7dSRichard Lowe conditional = get_prop(conditional->next, conditional_prop),
297210d63b7dSRichard Lowe i++) {
297310d63b7dSRichard Lowe /* Save the old value */
297410d63b7dSRichard Lowe old_locals[i].body.macro =
297510d63b7dSRichard Lowe maybe_append_prop(conditional->body.conditional.name,
297610d63b7dSRichard Lowe macro_prop)->body.macro;
297710d63b7dSRichard Lowe if (debug_level > 1) {
297810d63b7dSRichard Lowe (void) printf(gettext("%*sActivating conditional value: "),
297910d63b7dSRichard Lowe recursion_level,
298010d63b7dSRichard Lowe "");
298110d63b7dSRichard Lowe }
298210d63b7dSRichard Lowe /* Set the conditional value. Macros are expanded when the */
298310d63b7dSRichard Lowe /* macro is refd as usual */
298410d63b7dSRichard Lowe if ((conditional->body.conditional.name != virtual_root) ||
298510d63b7dSRichard Lowe (conditional->body.conditional.value != virtual_root)) {
298610d63b7dSRichard Lowe (void) SETVAR(conditional->body.conditional.name,
298710d63b7dSRichard Lowe conditional->body.conditional.value,
298810d63b7dSRichard Lowe (Boolean) conditional->body.conditional.append);
298910d63b7dSRichard Lowe }
299010d63b7dSRichard Lowe cond_name = ALLOC(Chain);
299110d63b7dSRichard Lowe cond_name->name = conditional->body.conditional.name;
299210d63b7dSRichard Lowe }
299310d63b7dSRichard Lowe /* Put this target on the front of the chain of conditional targets */
299410d63b7dSRichard Lowe cond_chain = ALLOC(Chain);
299510d63b7dSRichard Lowe cond_chain->name = target;
299610d63b7dSRichard Lowe cond_chain->next = conditional_targets;
299710d63b7dSRichard Lowe conditional_targets = cond_chain;
299810d63b7dSRichard Lowe conditional_macro_used = saved_conditional_macro_used;
299910d63b7dSRichard Lowe }
300010d63b7dSRichard Lowe
300110d63b7dSRichard Lowe /*
300210d63b7dSRichard Lowe * reset_locals(target, old_locals, conditional, index)
300310d63b7dSRichard Lowe *
300410d63b7dSRichard Lowe * Removes any conditional macros for the target.
300510d63b7dSRichard Lowe *
300610d63b7dSRichard Lowe * Parameters:
300710d63b7dSRichard Lowe * target The target we are retoring values for
300810d63b7dSRichard Lowe * old_locals The values to restore
300910d63b7dSRichard Lowe * conditional The first conditional block for the target
301010d63b7dSRichard Lowe * index into the old_locals vector
301110d63b7dSRichard Lowe * Global variables used:
301210d63b7dSRichard Lowe * debug_level Should we trace activities?
301310d63b7dSRichard Lowe * recursion_level Used for tracing
301410d63b7dSRichard Lowe */
301510d63b7dSRichard Lowe void
reset_locals(Name target,Property old_locals,Property conditional,int index)3016*e7afc443SToomas Soome reset_locals(Name target, Property old_locals, Property conditional, int index)
301710d63b7dSRichard Lowe {
3018*e7afc443SToomas Soome Property this_conditional;
301910d63b7dSRichard Lowe Chain cond_chain;
302010d63b7dSRichard Lowe
302110d63b7dSRichard Lowe if (target->dont_activate_cond_values) {
302210d63b7dSRichard Lowe return;
302310d63b7dSRichard Lowe }
302410d63b7dSRichard Lowe
302510d63b7dSRichard Lowe /* Scan the list of conditional properties and restore the old value */
302610d63b7dSRichard Lowe /* to each one Reverse the order relative to when we assigned macros */
302710d63b7dSRichard Lowe this_conditional = get_prop(conditional->next, conditional_prop);
302810d63b7dSRichard Lowe if (this_conditional != NULL) {
302910d63b7dSRichard Lowe reset_locals(target, old_locals, this_conditional, index+1);
303010d63b7dSRichard Lowe } else {
303110d63b7dSRichard Lowe /* Remove conditional target from chain */
303210d63b7dSRichard Lowe if (conditional_targets == NULL ||
303310d63b7dSRichard Lowe conditional_targets->name != target) {
303410d63b7dSRichard Lowe warning(gettext("Internal error: reset target not at head of condtional_targets chain"));
303510d63b7dSRichard Lowe } else {
303610d63b7dSRichard Lowe cond_chain = conditional_targets->next;
303710d63b7dSRichard Lowe retmem_mb((caddr_t) conditional_targets);
303810d63b7dSRichard Lowe conditional_targets = cond_chain;
303910d63b7dSRichard Lowe }
304010d63b7dSRichard Lowe }
304110d63b7dSRichard Lowe get_prop(conditional->body.conditional.name->prop,
304210d63b7dSRichard Lowe macro_prop)->body.macro = old_locals[index].body.macro;
304310d63b7dSRichard Lowe if (conditional->body.conditional.name == virtual_root) {
304410d63b7dSRichard Lowe (void) SETVAR(virtual_root, getvar(virtual_root), false);
304510d63b7dSRichard Lowe }
304610d63b7dSRichard Lowe if (debug_level > 1) {
304710d63b7dSRichard Lowe if (old_locals[index].body.macro.value != NULL) {
304810d63b7dSRichard Lowe (void) printf(gettext("%*sdeactivating conditional value: %s= %s\n"),
304910d63b7dSRichard Lowe recursion_level,
305010d63b7dSRichard Lowe "",
305110d63b7dSRichard Lowe conditional->body.conditional.name->
305210d63b7dSRichard Lowe string_mb,
305310d63b7dSRichard Lowe old_locals[index].body.macro.value->
305410d63b7dSRichard Lowe string_mb);
305510d63b7dSRichard Lowe } else {
305610d63b7dSRichard Lowe (void) printf(gettext("%*sdeactivating conditional value: %s =\n"),
305710d63b7dSRichard Lowe recursion_level,
305810d63b7dSRichard Lowe "",
305910d63b7dSRichard Lowe conditional->body.conditional.name->
306010d63b7dSRichard Lowe string_mb);
306110d63b7dSRichard Lowe }
306210d63b7dSRichard Lowe }
306310d63b7dSRichard Lowe }
306410d63b7dSRichard Lowe
306510d63b7dSRichard Lowe /*
306610d63b7dSRichard Lowe * check_auto_dependencies(target, auto_count, automatics)
306710d63b7dSRichard Lowe *
306810d63b7dSRichard Lowe * Returns true if the target now has a dependency
306910d63b7dSRichard Lowe * it didn't previously have (saved on automatics).
307010d63b7dSRichard Lowe *
307110d63b7dSRichard Lowe * Return value:
307210d63b7dSRichard Lowe * true if new dependency found
307310d63b7dSRichard Lowe *
307410d63b7dSRichard Lowe * Parameters:
307510d63b7dSRichard Lowe * target Target we check
307610d63b7dSRichard Lowe * auto_count Number of old automatic vars
307710d63b7dSRichard Lowe * automatics Saved old automatics
307810d63b7dSRichard Lowe *
307910d63b7dSRichard Lowe * Global variables used:
308010d63b7dSRichard Lowe * keep_state Indicates that .KEEP_STATE is on
308110d63b7dSRichard Lowe */
308210d63b7dSRichard Lowe Boolean
check_auto_dependencies(Name target,int auto_count,Name * automatics)308310d63b7dSRichard Lowe check_auto_dependencies(Name target, int auto_count, Name *automatics)
308410d63b7dSRichard Lowe {
308510d63b7dSRichard Lowe Name *p;
308610d63b7dSRichard Lowe int n;
308710d63b7dSRichard Lowe Property line;
308810d63b7dSRichard Lowe Dependency dependency;
308910d63b7dSRichard Lowe
309010d63b7dSRichard Lowe if (keep_state) {
309110d63b7dSRichard Lowe if ((line = get_prop(target->prop, line_prop)) == NULL) {
309210d63b7dSRichard Lowe return false;
309310d63b7dSRichard Lowe }
309410d63b7dSRichard Lowe /* Go thru new list of automatic depes */
309510d63b7dSRichard Lowe for (dependency = line->body.line.dependencies;
309610d63b7dSRichard Lowe dependency != NULL;
309710d63b7dSRichard Lowe dependency = dependency->next) {
309810d63b7dSRichard Lowe /* And make sure that each one existed before we */
309910d63b7dSRichard Lowe /* built the target */
310010d63b7dSRichard Lowe if (dependency->automatic && !dependency->stale) {
310110d63b7dSRichard Lowe for (n = auto_count, p = automatics;
310210d63b7dSRichard Lowe n > 0;
310310d63b7dSRichard Lowe n--) {
310410d63b7dSRichard Lowe if (*p++ == dependency->name) {
310510d63b7dSRichard Lowe /* If we can find it on the */
310610d63b7dSRichard Lowe /* saved list of autos we */
310710d63b7dSRichard Lowe /* are OK */
310810d63b7dSRichard Lowe goto not_new;
310910d63b7dSRichard Lowe }
311010d63b7dSRichard Lowe }
311110d63b7dSRichard Lowe /* But if we scan over the old list */
311210d63b7dSRichard Lowe /* of auto. without finding it it is */
311310d63b7dSRichard Lowe /* new and we must check it */
311410d63b7dSRichard Lowe return true;
311510d63b7dSRichard Lowe }
311610d63b7dSRichard Lowe not_new:;
311710d63b7dSRichard Lowe }
311810d63b7dSRichard Lowe return false;
311910d63b7dSRichard Lowe } else {
312010d63b7dSRichard Lowe return false;
312110d63b7dSRichard Lowe }
312210d63b7dSRichard Lowe }
312310d63b7dSRichard Lowe
312410d63b7dSRichard Lowe
312510d63b7dSRichard Lowe // Recursively delete each of the Chain struct on the chain.
312610d63b7dSRichard Lowe
312710d63b7dSRichard Lowe static void
delete_query_chain(Chain ch)312810d63b7dSRichard Lowe delete_query_chain(Chain ch)
312910d63b7dSRichard Lowe {
313010d63b7dSRichard Lowe if (ch == NULL) {
313110d63b7dSRichard Lowe return;
313210d63b7dSRichard Lowe } else {
313310d63b7dSRichard Lowe delete_query_chain(ch->next);
313410d63b7dSRichard Lowe retmem_mb((char *) ch);
313510d63b7dSRichard Lowe }
313610d63b7dSRichard Lowe }
313710d63b7dSRichard Lowe
313810d63b7dSRichard Lowe Doname
target_can_be_built(Name target)3139*e7afc443SToomas Soome target_can_be_built(Name target) {
314010d63b7dSRichard Lowe Doname result = build_dont_know;
314110d63b7dSRichard Lowe Name true_target = target;
314210d63b7dSRichard Lowe Property line;
314310d63b7dSRichard Lowe
314410d63b7dSRichard Lowe if (target == wait_name) {
314510d63b7dSRichard Lowe return(build_ok);
314610d63b7dSRichard Lowe }
314710d63b7dSRichard Lowe /*
314810d63b7dSRichard Lowe * If the target is a constructed one for a "::" target,
314910d63b7dSRichard Lowe * we need to consider that.
315010d63b7dSRichard Lowe */
315110d63b7dSRichard Lowe if (target->has_target_prop) {
315210d63b7dSRichard Lowe true_target = get_prop(target->prop,
315310d63b7dSRichard Lowe target_prop)->body.target.target;
315410d63b7dSRichard Lowe }
315510d63b7dSRichard Lowe
315610d63b7dSRichard Lowe (void) exists(true_target);
315710d63b7dSRichard Lowe
315810d63b7dSRichard Lowe if (true_target->state == build_running) {
315910d63b7dSRichard Lowe return(build_running);
316010d63b7dSRichard Lowe }
316110d63b7dSRichard Lowe if (true_target->stat.time != file_doesnt_exist) {
316210d63b7dSRichard Lowe result = build_ok;
316310d63b7dSRichard Lowe }
316410d63b7dSRichard Lowe
316510d63b7dSRichard Lowe /* get line property for the target */
316610d63b7dSRichard Lowe line = get_prop(true_target->prop, line_prop);
316710d63b7dSRichard Lowe
316810d63b7dSRichard Lowe /* first check for explicit rule */
316910d63b7dSRichard Lowe if (line != NULL && line->body.line.command_template != NULL) {
317010d63b7dSRichard Lowe result = build_ok;
317110d63b7dSRichard Lowe }
317210d63b7dSRichard Lowe /* try to find pattern rule */
317310d63b7dSRichard Lowe if (result == build_dont_know) {
317410d63b7dSRichard Lowe result = find_percent_rule(target, NULL, false);
317510d63b7dSRichard Lowe }
317648bbca81SDaniel Hoffman
317710d63b7dSRichard Lowe /* try to find double suffix rule */
317810d63b7dSRichard Lowe if (result == build_dont_know) {
317910d63b7dSRichard Lowe if (target->is_member) {
318010d63b7dSRichard Lowe Property member = get_prop(target->prop, member_prop);
318110d63b7dSRichard Lowe if (member != NULL && member->body.member.member != NULL) {
318210d63b7dSRichard Lowe result = find_ar_suffix_rule(target, member->body.member.member, NULL, false);
318310d63b7dSRichard Lowe } else {
318410d63b7dSRichard Lowe result = find_double_suffix_rule(target, NULL, false);
318510d63b7dSRichard Lowe }
318610d63b7dSRichard Lowe } else {
318710d63b7dSRichard Lowe result = find_double_suffix_rule(target, NULL, false);
318810d63b7dSRichard Lowe }
318910d63b7dSRichard Lowe }
319048bbca81SDaniel Hoffman
319110d63b7dSRichard Lowe /* try to find suffix rule */
319210d63b7dSRichard Lowe if ((result == build_dont_know) && second_pass) {
319310d63b7dSRichard Lowe result = find_suffix_rule(target, target, empty_name, NULL, false);
319410d63b7dSRichard Lowe }
319548bbca81SDaniel Hoffman
319610d63b7dSRichard Lowe /* check for sccs */
319710d63b7dSRichard Lowe if (result == build_dont_know) {
319810d63b7dSRichard Lowe result = sccs_get(target, NULL);
319910d63b7dSRichard Lowe }
320048bbca81SDaniel Hoffman
320110d63b7dSRichard Lowe /* try to find dyn target */
320210d63b7dSRichard Lowe if (result == build_dont_know) {
320310d63b7dSRichard Lowe Name dtarg = find_dyntarget(target);
320410d63b7dSRichard Lowe if (dtarg != NULL) {
320510d63b7dSRichard Lowe result = target_can_be_built(dtarg);
320610d63b7dSRichard Lowe }
320710d63b7dSRichard Lowe }
320848bbca81SDaniel Hoffman
320910d63b7dSRichard Lowe /* check whether target was mentioned in makefile */
321010d63b7dSRichard Lowe if (result == build_dont_know) {
321110d63b7dSRichard Lowe if (target->colons != no_colon) {
321210d63b7dSRichard Lowe result = build_ok;
321310d63b7dSRichard Lowe }
321410d63b7dSRichard Lowe }
321510d63b7dSRichard Lowe
321610d63b7dSRichard Lowe /* result */
321710d63b7dSRichard Lowe return result;
321810d63b7dSRichard Lowe }
3219