/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* main.cc
*
* make program main routine plus some helper routines
*/
/*
* Included files
*/
#include <locale.h> /* setlocale() */
#include <libgen.h>
#include <pwd.h> /* getpwnam() */
#include <setjmp.h>
#include <signal.h>
#include <stdlib.h>
#include <fcntl.h> /* open() */
#include <unistd.h> /* execv(), unlink(), access() */
// From read2.cc
extern void job_adjust_fini();
/*
* Defined macros
*/
#ifdef __i386
#else
#error "Unsupported architecture"
#endif
/*
* typedefs & structs
*/
/*
* Static variables
*/
static char *argv_zero_string;
static int mf_argc;
static char **mf_argv;
#ifdef DMAKE_STATISTICS
#endif
static int g_argc;
static char **g_argv;
/*
* File table of contents
*/
extern "C" void cleanup_after_exit(void);
extern "C" {
extern void dmake_exit_callback(void);
extern void dmake_message_callback(char *);
}
extern int main(int, char * []);
static void doalarm(int);
static void enter_argv_values(int , char **, ASCII_Dyn_Array *);
static void make_targets(int, char **, Boolean);
static int parse_command_option(char);
static void read_command_options(int, char **);
static void read_environment(Boolean);
static void read_files_and_state(int, char **);
static void report_recursion(Name);
static void set_sgs_support(void);
static void setup_for_projectdir(void);
static void setup_makeflags_argv(void);
/*
* main(argc, argv)
*
* Parameters:
* argc You know what this is
* argv You know what this is
*
* Static variables used:
* list_all_targets make -T seen
* trace_status make -p seen
*
* Global variables used:
* debug_level Should we trace make actions?
* keep_state Set if .KEEP_STATE seen
* makeflags The Name "MAKEFLAGS", used to get macro
* remote_command_name Name of remote invocation cmd ("on")
* running_list List of parallel running processes
* stdout_stderr_same true if stdout and stderr are the same
* auto_dependencies The Name "SUNPRO_DEPENDENCIES"
* temp_file_directory Set to the dir where we create tmp file
* trace_reader Set to reflect tracing status
* working_on_targets Set when building user targets
*/
int
{
/*
* cp is a -> to the value of the MAKEFLAGS env var,
* which has to be regular chars.
*/
register char *cp;
char *prognameptr;
char *slash_ptr;
int i;
int statval;
bsd_signals();
#ifdef DMAKE_STATISTICS
if (getenv("DMAKE_STATISTICS")) {
getname_stat = true;
}
#endif
#ifndef TEXT_DOMAIN
#endif
for (i = 0; i < argc; i++) {
}
/*
* Set argv_zero_string to some form of argv[0] for
* recursive MAKE builds.
*/
if (*argv[0] == (int) slash_char) {
/* argv[0] starts with a slash */
/* argv[0] contains no slashes */
} else {
/*
* argv[0] contains at least one slash,
* but doesn't start with a slash
*/
char *tmp_current_path;
char *tmp_string;
(void) sprintf(tmp_string,
"%s/%s",
argv[0]);
}
/*
* The following flags are reset if we don't have the
* (.nse_depinfo or .make.state) files locked and only set
* AFTER the file has been locked. This ensures that if the user
* interrupts the program while file_lock() is waiting to lock
* the file, the interrupt handler doesn't remove a lock
* that doesn't belong to us.
*/
make_state_locked = false;
/*
* look for last slash char in the path to look at the binary
* name. This is to resolve the hard link and invoke make
* in svr4 mode.
*/
/* Sun OS make standart */
svr4 = false;
posix = false;
svr4 = false;
posix = true;
} else {
if(prognameptr) {
prognameptr++;
} else {
prognameptr = argv[0];
}
svr4 = true;
posix = false;
}
}
svr4 = true;
posix = false;
}
/*
* Find the dmake_compat_mode: posix, sun, svr4, or gnu_style, .
*/
if (dmake_compat_mode_var != NULL) {
gnu_style = true;
}
//svr4 = false;
//posix = false;
}
/*
* Temporary directory set up.
*/
*tmpdir_var = '\0');
mbs_buffer, getpid());
if (fd >= 0) {
}
}
}
/* find out if stdout and stderr point to the same place */
}
}
stdout_stderr_same = true;
} else {
stdout_stderr_same = false;
}
/* Make the vroot package scan the path using shell semantics */
set_path_style(0);
/*
* If running with .KEEP_STATE, curdir will be set with
* the connected directory.
*/
(void) atexit(cleanup_after_exit);
/*
* Set command line flags
*/
if (debug_level > 0) {
}
/*
* Find the dmake_output_mode: TXT1, TXT2 or HTML1.
*/
/* DMAKE_OUTPUT_MODE not defined, default to TXT1 mode */
} else {
if ((dmake_value2 == NULL) ||
} else {
}
}
/*
* Find the dmake_mode: parallel, or serial.
*/
if ((!pmake_cap_r_specified) &&
char *s, *b;
b = basename(s);
// If we're invoked as 'make' run serially, regardless of DMAKE_MODE
// If we're invoked as 'make' but passed -j, run parallel
// If we're invoked as 'dmake', without DMAKE_MODE, default parallel
// If we're invoked as 'dmake' and DMAKE_MODE is set, honour it.
if ((strcmp(b, "make") == 0) &&
no_parallel = true;
/* DMAKE_MODE not defined, default based on our name */
if (strcmp(b, "dmake") == 0) {
no_parallel = false;
}
} else {
no_parallel = false;
no_parallel = true;
} else {
}
}
free(s);
}
parallel_flag = true;
//
// If dmake is running with -t option, set dmake_mode_type to serial.
// This is done because doname() calls touch_command() that runs serially.
// If we do not do that, maketool will have problems.
//
if(touch) {
no_parallel = true;
}
/*
* Check whether stdout and stderr are physically same.
* This is in order to decide whether we need to redirect
* stderr separately from stdout.
* This check is performed only if __DMAKE_SEPARATE_STDERR
* is not set. This variable may be used in order to preserve
* the 'old' behaviour.
*/
out_err_same = true;
{
{
out_err_same = false;
}
}
}
/*
* Enable interrupt handler for alarms
*/
/*
* Check if make should report
*/
report_dependency("");
}
}
/*
* Make sure SUNPRO_DEPENDENCIES is exported (or not) properly.
*/
if (keep_state) {
} else {
}
working_on_targets = true;
if (trace_status) {
exit_status = 0;
exit(0);
}
if (list_all_targets) {
exit_status = 0;
exit(0);
}
trace_reader = false;
/*
* Set temp_file_directory to the directory the .make.state
* file is written to.
*/
} else {
*slash_ptr = (int) slash_char;
/* when there is only one slash and it's the first
** character, make_state_dir should point to '/'.
*/
if(make_state_dir[0] == '\0') {
make_state_dir[0] = '/';
}
if (make_state_dir[0] == (int) slash_char) {
} else {
(void) sprintf(tmp_current_path2,
"%s/%s",
}
}
report_dir_enter_leave(true);
report_dir_enter_leave(false);
if (build_failed_ever_seen) {
if (posix) {
exit_status = 1;
}
exit(1);
}
exit_status = 0;
exit(0);
/* NOTREACHED */
}
/*
* cleanup_after_exit()
*
* Called from exit(), performs cleanup actions.
*
* Parameters:
* status The argument exit() was called with
* arg Address of an argument vector to
* cleanup_after_exit()
*
* Global variables used:
* command_changed Set if we think .make.state should be rewritten
* current_line Is set we set commands_changed
* do_not_exec_rule
* True if -n flag on
* done The Name ".DONE", rule we run
* keep_state Set if .KEEP_STATE seen
* parallel True if building in parallel
* quest If -q is on we do not run .DONE
* report_dependencies
* True if -P flag on
* running_list List of parallel running processes
* temp_file_name The temp file is removed, if any
*/
extern "C" void
cleanup_after_exit(void)
{
extern long getname_bytes_count;
extern long getname_names_count;
extern long getname_struct_count;
extern long freename_bytes_count;
extern long freename_names_count;
extern long freename_struct_count;
extern long other_alloc;
extern long env_alloc_num;
extern long env_alloc_bytes;
#ifdef DMAKE_STATISTICS
if(getname_stat) {
printf(">>> Getname statistics:\n");
printf(" Allocated:\n");
printf(" Total bytes: %ld Kb (%ld bytes)\n", getname_struct_count/1000 + getname_bytes_count/1000, getname_struct_count + getname_bytes_count);
printf(" Total bytes: %ld Kb (%ld bytes)\n", freename_struct_count/1000 + freename_bytes_count/1000, freename_struct_count + freename_bytes_count);
printf("\n Total used: %ld Kb (%ld bytes)\n", (getname_struct_count/1000 + getname_bytes_count/1000) - (freename_struct_count/1000 + freename_bytes_count/1000), (getname_struct_count + getname_bytes_count) - (freename_struct_count + freename_bytes_count));
printf("\n>>> Other:\n");
" Env (%ld): %ld Kb (%ld bytes)\n",
env_alloc_bytes/1000,
);
}
#endif
parallel = false;
/* If we used the SVR4_MAKE, don't build .DONE or .FAILED */
if (!getenv(USE_SVR4_MAKE)){
/* Build the target .DONE or .FAILED if we caught an error */
if (!quest && !list_all_targets) {
/*
* [tolik] switch DMake to serial mode
*/
no_parallel = true;
(void) doname(failed_name, false, true);
} else {
if (!trace_status) {
/*
* Switch DMake to serial mode
*/
no_parallel = true;
}
}
}
}
/*
* Remove the temp file utilities report dependencies thru if it
* is still around
*/
if (temp_file_name != NULL) {
}
/*
* Do not save the current command in .make.state if make
* was interrupted.
*/
if (current_line != NULL) {
command_changed = true;
}
/*
* For each parallel build process running, remove the temp files
* and zap the command line so it won't be put in .make.state
*/
}
}
}
command_changed = true;
/*
line = get_prop(rp->target->prop, line_prop);
if (line != NULL) {
line->body.line.command_used = NULL;
}
*/
}
/* Remove the statefile lock file if the file has been locked */
(void) unlink(make_state_lockfile);
make_state_locked = false;
}
/* Write .make.state */
}
/*
* handle_interrupt()
*
* This is where C-C traps are caught.
*
* Parameters:
*
* Global variables used (except DMake 1.0):
* current_target Sometimes the current target is removed
* do_not_exec_rule But not if -n is on
* quest or -q
* running_list List of parallel running processes
* touch Current target is not removed if -t on
*/
void
handle_interrupt(int)
{
if (childPid > 0) {
childPid = -1;
}
continue;
}
}
}
}
/* Clean up all parallel children already finished */
finish_children(false);
/* Make sure the processes running under us terminate first */
/* Delete the current targets unless they are precious */
if ((current_target != NULL) &&
}
if (!do_not_exec_rule &&
!touch &&
!quest &&
(current_target != NULL) &&
/* BID_1030811 */
/* azv 16 Oct 95 */
"\n*** %s ",
gettext("not removed.\n"),
gettext("removed.\n"),
} else {
gettext("could not be removed: %s.\n"),
}
}
}
continue;
}
NULL)) {
}
if (!do_not_exec_rule &&
!touch &&
!quest &&
"\n*** %s ",
gettext("not removed.\n"),
gettext("removed.\n"),
} else {
gettext("could not be removed: %s.\n"),
}
}
}
}
/* Have we locked .make.state or .nse_depinfo? */
make_state_locked = false;
}
/*
* Re-read .make.state file (it might be changed by recursive make)
*/
report_dir_enter_leave(false);
exit_status = 2;
exit(2);
}
/*
* doalarm(sig, ...)
*
* Handle the alarm interrupt but do nothing. Side effect is to
* cause return from wait3.
*
* Parameters:
* sig
*
* Global variables used:
*/
/*ARGSUSED*/
static void
doalarm(int)
{
return;
}
/*
* read_command_options(argc, argv)
*
* Scan the cmd line options and process the ones that start with "-"
*
* Return value:
* -M argument, if any
*
* Parameters:
* argc You know what this is
* argv You know what this is
*
* Global variables used:
*/
static void
{
register int ch;
int last_optind_with_double_hyphen = 0;
int last_optind;
int last_current_optind;
register int i;
register int j;
register int k;
* flag to note options:
* -c, f, g, j, m, o
*/
const char *tptr;
const char *CMD_OPTS;
extern char *optarg;
/*
* Added V in SVR4_CMD_OPTS also, which is going to be a hidden
* option, just to make sure that the getopt doesn't fail when some
* users leave their USE_SVR4_MAKE set and try to use the makefiles
* that are designed to issue commands like $(MAKE) -V. Anyway it
* sets the same flag but ensures that getopt doesn't fail.
*/
opterr = 0;
optind = 1;
while (1) {
if (svr4) {
} else {
}
/*
* Fixing bug 4102537:
* Strange behaviour of command make using -- option.
* Not all argv have been processed
* Skip non-flag argv and continue processing.
*/
optind++;
continue;
} else {
break;
}
}
if (ch == '?') {
if (optopt == '-') {
/* Bug 5060758: getopt() changed behavior (s10_60),
* and now we have to deal with cases when options
* with double hyphen appear here, from -$(MAKEFLAGS)
*/
i = current_optind;
if (argv[i][0] == '-') {
/* Check if this option is allowed */
if (tptr) {
if (last_optind_with_double_hyphen != current_optind) {
/* This is first time we are trying to fix "--"
* problem with this option. If we come here second
* time, we will go to fatal error.
*/
/* Eliminate first hyphen character */
for (j=0; argv[i][j] != '\0'; j++) {
}
/* Repeat the processing of this argument */
continue;
}
}
}
}
}
}
}
if (ch == '?') {
if (svr4) {
gettext("Usage : dmake [ -f makefile ][ -c dmake_rcfile ][ -g dmake_group ]\n"));
gettext(" [ -j dmake_max_jobs ][ -m dmake_mode ][ -o dmake_odir ]...\n"));
gettext(" [ -e ][ -i ][ -k ][ -n ][ -p ][ -q ][ -r ][ -s ][ -t ][ -v ]\n"));
} else {
gettext("Usage : dmake [ -f makefile ][ -c dmake_rcfile ][ -g dmake_group ]\n"));
gettext(" [ -j dmake_max_jobs ][ -K statefile ][ -m dmake_mode ][ -x MODE_NAME=VALUE ][ -o dmake_odir ]...\n"));
gettext(" [ -d ][ -dd ][ -D ][ -DD ][ -e ][ -i ][ -k ][ -n ][ -p ][ -P ][ -u ][ -w ]\n"));
gettext(" [ -q ][ -r ][ -s ][ -S ][ -t ][ -v ][ -V ][ target... ][ macro=value... ][ \"macro +=value\"... ]\n"));
}
if (!tptr) {
} else {
}
}
/*
* If we're done processing all of the options of
* ONE argument string...
*/
if (current_optind < optind) {
i = current_optind;
k = 0;
/* If there's an argument for an option... */
k = i + 1;
}
switch (makefile_next) {
case 0:
/* This shouldn't happen */
if (k) {
}
break;
case 1: /* -f seen */
argv[i] = (char *)"-f";
break;
case 2: /* -c seen */
argv[i] = (char *)"-c";
break;
case 4: /* -g seen */
argv[i] = (char *)"-g";
break;
case 8: /* -j seen */
argv[i] = (char *)"-j";
break;
case 16: /* -M seen */
argv[i] = (char *)"-M";
break;
case 32: /* -m seen */
argv[i] = (char *)"-m";
break;
case 128: /* -O seen */
argv[i] = (char *)"-O";
break;
case 256: /* -K seen */
argv[i] = (char *)"-K";
break;
case 512: /* -o seen */
argv[i] = (char *)"-o";
break;
case 1024: /* -x seen */
argv[i] = (char *)"-x";
break;
default: /* > 1 of -c, f, g, j, K, M, m, O, o, x seen */
fatal(gettext("Illegal command line. More than one option requiring\nan argument given in the same argument group"));
}
makefile_next = 0;
}
}
}
static void
{
char *to;
char *from;
switch (*from) {
case ';': /* End of command */
case '(': /* Start group */
case ')': /* End group */
case '{': /* Start group */
case '}': /* End group */
case '[': /* Reg expr - any of a set of chars */
case ']': /* End of set of chars */
case '|': /* Pipe or logical-or */
case '^': /* Old-fashioned pipe */
case '&': /* Background or logical-and */
case '<': /* Redirect stdin */
case '>': /* Redirect stdout */
case '*': /* Reg expr - any sequence of chars */
case '?': /* Reg expr - any single char */
case '$': /* Variable substitution */
case '\'': /* Singe quote - turn off all magic */
case '"': /* Double quote - span whitespace */
case '`': /* Backquote - run a command */
case '#': /* Comment */
case ' ': /* Space (for MACRO=value1 value2 */
case '\\': /* Escape char - turn off magic of next char */
*to++ = '\\';
break;
default:
break;
}
}
*to = '\0';
}
static void
{
char *to;
char *from;
if (*from == '\\') {
from++;
}
}
*to = '\0';
}
/*
* Convert the MAKEFLAGS string value into a vector of char *, similar
* to argv.
*/
static void
{
char *cp;
char *cp1;
char *cp2;
char *cp3;
char *cp_orig;
int i;
char tmp_char;
mf_argc = 1;
if (cp) {
/*
* If new MAKEFLAGS format, no need to add hyphen.
* If old MAKEFLAGS format, add hyphen before flags.
*/
/* New MAKEFLAGS format */
add_hyphen = false;
/* Check if MAKEFLAGS value begins with multiple
* hyphen characters, and remove all duplicates.
* Usually it happens when the next command is
* used: $(MAKE) -$(MAKEFLAGS)
*
* This was a workaround for BugID 5060758, but
* appears to have survived as a fix in make.
*/
while (*cp) {
if (*cp != (int) hyphen_char) {
break;
}
cp++;
if (*cp == (int) hyphen_char) {
/* There are two hyphens. Skip one */
cp++;
}
if (!(*cp)) {
/* There are hyphens only. Skip all */
break;
}
}
} else {
/* Old MAKEFLAGS format */
add_hyphen = true;
}
}
/* Find the number of arguments in MAKEFLAGS */
/* Skip white spaces */
cp++;
}
/* Increment arg count */
mf_argc++;
/* Go to next white space */
if(*cp == (int) backslash_char) {
cp++;
}
cp++;
}
}
}
/* Allocate memory for the new MAKEFLAGS argv */
mf_argv[0] = (char *)"MAKEFLAGS";
/*
* Convert the MAKEFLAGS string value into a vector of char *,
* similar to argv.
*/
for (i = 1; i < mf_argc; i++) {
/* Skip white spaces */
cp++;
}
/* Go to next white space */
if(*cp == (int) backslash_char) {
cp++;
}
cp++;
}
if (add_hyphen) {
mf_argv[i][0] = '\0';
// (void) strcat(mf_argv[i], cp_orig);
} else {
//mf_argv[i] = strdup(cp_orig);
}
}
}
}
/*
* parse_command_option(ch)
*
* Parse make command line options.
*
* Return value:
* Indicates if any -f -c or -M were seen
*
* Parameters:
* ch The character to parse
*
* Static variables used:
* dmake_group_specified Set for make -g
* dmake_max_jobs_specified Set for make -j
* dmake_mode_specified Set for make -m
* dmake_add_mode_specified Set for make -x
* dmake_compat_mode_specified Set for make -x SUN_MAKE_COMPAT_MODE=
* dmake_output_mode_specified Set for make -x DMAKE_OUTPUT_MODE=
* dmake_odir_specified Set for make -o
* dmake_rcfile_specified Set for make -c
* env_wins Set for make -e
* ignore_default_mk Set for make -r
* trace_status Set for make -p
*
* Global variables used:
* .make.state path & name set for make -K
* continue_after_error Set for make -k
* debug_level Set for make -d
* do_not_exec_rule Set for make -n
* filter_stderr Set for make -X
* ignore_errors_all Set for make -i
* no_parallel Set for make -R
* quest Set for make -q
* read_trace_level Set for make -D
* report_dependencies Set for make -P
* silent_all Set for make -s
* touch Set for make -t
*/
static int
{
static int invert_next = 0;
invert_next = 0;
switch (ch) {
case '-': /* Ignore "--" */
return 0;
case '~': /* Invert next option */
invert_next = 1;
return 0;
case 'B': /* Obsolete */
return 0;
case 'b': /* Obsolete */
return 0;
case 'c': /* Read alternative dmakerc file */
if (invert_this) {
dmake_rcfile_specified = false;
} else {
dmake_rcfile_specified = true;
}
return 2;
case 'D': /* Show lines read */
if (invert_this) {
} else {
}
return 0;
case 'd': /* Debug flag */
if (invert_this) {
debug_level--;
} else {
debug_level++;
}
return 0;
case 'e': /* Environment override flag */
if (invert_this) {
env_wins = false;
} else {
env_wins = true;
}
return 0;
case 'f': /* Read alternative makefile(s) */
return 1;
case 'g': /* Use alternative DMake group */
if (invert_this) {
dmake_group_specified = false;
} else {
dmake_group_specified = true;
}
return 4;
case 'i': /* Ignore errors */
if (invert_this) {
ignore_errors_all = false;
} else {
ignore_errors_all = true;
}
return 0;
case 'j': /* Use alternative DMake max jobs */
if (invert_this) {
dmake_max_jobs_specified = false;
} else {
no_parallel = false;
dmake_max_jobs_specified = true;
}
return 8;
case 'K': /* Read alternative .make.state */
return 256;
case 'k': /* Keep making even after errors */
if (invert_this) {
continue_after_error = false;
} else {
continue_after_error = true;
continue_after_error_ever_seen = true;
}
return 0;
case 'M': /* Read alternative make.machines file */
if (invert_this) {
pmake_machinesfile_specified = false;
} else {
pmake_machinesfile_specified = true;
no_parallel = false;
}
return 16;
case 'm': /* Use alternative DMake build mode */
if (invert_this) {
dmake_mode_specified = false;
} else {
dmake_mode_specified = true;
}
return 32;
case 'x': /* Use alternative DMake mode */
if (invert_this) {
dmake_add_mode_specified = false;
} else {
dmake_add_mode_specified = true;
}
return 1024;
case 'N': /* Reverse -n */
if (invert_this) {
do_not_exec_rule = true;
} else {
do_not_exec_rule = false;
}
return 0;
case 'n': /* Print, not exec commands */
if (invert_this) {
do_not_exec_rule = false;
} else {
do_not_exec_rule = true;
}
return 0;
case 'O': /* Integrate with maketool, obsolete */
return 0;
case 'o': /* Use alternative dmake output dir */
if (invert_this) {
dmake_odir_specified = false;
} else {
dmake_odir_specified = true;
}
return 512;
case 'P': /* Print for selected targets */
if (invert_this) {
} else {
}
return 0;
case 'p': /* Print description */
if (invert_this) {
trace_status = false;
do_not_exec_rule = false;
} else {
trace_status = true;
do_not_exec_rule = true;
}
return 0;
case 'q': /* Question flag */
if (invert_this) {
quest = false;
} else {
quest = true;
}
return 0;
case 'R': /* Don't run in parallel */
if (invert_this) {
pmake_cap_r_specified = false;
no_parallel = false;
} else {
pmake_cap_r_specified = true;
no_parallel = true;
}
return 0;
case 'r': /* Turn off internal rules */
if (invert_this) {
ignore_default_mk = false;
} else {
ignore_default_mk = true;
}
return 0;
case 'S': /* Reverse -k */
if (invert_this) {
continue_after_error = true;
} else {
continue_after_error = false;
stop_after_error_ever_seen = true;
}
return 0;
case 's': /* Silent flag */
if (invert_this) {
silent_all = false;
} else {
silent_all = true;
}
return 0;
case 'T': /* Print target list */
if (invert_this) {
list_all_targets = false;
do_not_exec_rule = false;
} else {
list_all_targets = true;
do_not_exec_rule = true;
}
return 0;
case 't': /* Touch flag */
if (invert_this) {
touch = false;
} else {
touch = true;
}
return 0;
case 'u': /* Unconditional flag */
if (invert_this) {
build_unconditional = false;
} else {
build_unconditional = true;
}
return 0;
case 'V': /* SVR4 mode */
svr4 = true;
return 0;
case 'v': /* Version flag */
if (invert_this) {
} else {
exit_status = 0;
exit(0);
}
return 0;
case 'w': /* Unconditional flag */
if (invert_this) {
report_cwd = false;
} else {
report_cwd = true;
}
return 0;
#if 0
case 'X': /* Filter stdout */
if (invert_this) {
filter_stderr = false;
} else {
filter_stderr = true;
}
return 0;
#endif
default:
break;
}
return 0;
}
/*
* setup_for_projectdir()
*
* Read the PROJECTDIR variable, if defined, and set the sccs path
*
* Parameters:
*
* Global variables used:
* sccs_dir_path Set to point to SCCS dir to use
*/
static void
setup_for_projectdir(void)
{
int done=0;
/* Check if we should use PROJECTDIR when reading the SCCS dir. */
if ((sccs_dir_path != NULL) &&
(sccs_dir_path[0] != (int) slash_char)) {
{
}
/*empty block : it'll go & check cwd */
}
else {
done = 1;
} else {
done = 1;
}
}
}
if (!done) {
done = 1;
} else {
}
}
}
}
}
}
char *
make_install_prefix(void)
{
int ret;
char *dir;
PATH_MAX - 1)) < 0)
fatal("failed to read origin from /proc\n");
}
static char *
{
const char *oldpath;
char *newpath;
} else {
}
} else {
} else {
}
}
return (newpath);
}
/*
* set_sgs_support()
*
* Add the libmakestate.so.1 lib to the env var SGS_SUPPORT
* if it's not already in there.
* The SGS_SUPPORT env var and libmakestate.so.1 is used by
* the linker ld to report .make.state info back to make.
*
* In the new world we always will set the 32-bit and 64-bit versions of this
* variable explicitly so that we can take into account the correct isa and our
* /opt/local/lib/libmakestate.so.1:libmakestate.so.1. We still want to search
* the original location just as a safety measure.
*/
static void
{
int len;
// Try the tools path
}
}
// Try the tools path
}
}
if (prev_path) {
}
if (prev_path64) {
}
}
/*
* read_files_and_state(argc, argv)
*
* Read the makefiles we care about and the environment
* Also read the = style command line options
*
* Parameters:
* argc You know what this is
* argv You know what this is
*
* Static variables used:
* env_wins make -e, determines if env vars are RO
* ignore_default_mk make -r, determines if make.rules is read
* not_auto_depen dwight
*
* Global variables used:
* default_target_to_build Set to first proper target from file
* do_not_exec_rule Set to false when makfile is made
* dot The Name ".", used to read current dir
* empty_name The Name "", use as macro value
* keep_state Set if KEEP_STATE is in environment
* make_state The Name ".make.state", used to read file
* makefile_type Set to type of file being read
* makeflags The Name "MAKEFLAGS", used to set macro value
* not_auto dwight
* read_trace_level Checked to se if the reader should trace
* report_dependencies If -P is on we do not read .make.state
* trace_reader Set if reader should trace
* virtual_root The Name "VIRTUAL_ROOT", used to check value
*/
static void
{
register char ch;
register char *cp;
register int i;
register int j;
int length;
register int makefile_next = 0;
static wchar_t state_file_str;
char tmp_char;
wchar_t *tmp_wcs_buffer;
/*
* Remember current mode. It may be changed after reading makefile
* and we will have to correct MAKEFLAGS variable.
*/
/*
* initialize global dependency entry for .NOT_AUTO
*/
/*
* Read internal definitions and rules.
*/
if (read_trace_level > 1) {
trace_reader = true;
}
if (!ignore_default_mk) {
if (svr4) {
} else {
}
(void) read_makefile(default_makefile,
true,
false,
true);
}
/*
* If the user did not redefine the MAKE macro in the
* default makefile (make.rules), then we'd like to
* change the macro value of MAKE to be some form
* of argv[0] for recursive MAKE builds.
*/
if ((def_make_macro != NULL) &&
"make"))) {
(void) SETVAR(def_make_name,
false);
}
trace_reader = false;
/*
* Read environment args. Let file args which follow override unless
* -e option seen. If -e option is not mentioned.
*/
(void) SETVAR(virtual_root,
false);
}
/*
* We now scan mf_argv and argv to see if we need to set
*/
makeflags_and_macro.start = 0;
makeflags_and_macro.size = 0;
/*
* Set MFLAGS and MAKEFLAGS
*
* Before reading makefile we do not know exactly which mode
* (posix or not) is used. So prepare two MAKEFLAGS strings
* for both posix and solaris modes because they are different.
*/
switch (read_trace_level) {
case 2:
case 1:
}
switch (debug_level) {
case 2:
case 1:
}
if (env_wins) {
}
if (ignore_errors_all) {
}
if (continue_after_error) {
if (stop_after_error_ever_seen) {
}
} else {
}
}
if (do_not_exec_rule) {
}
switch (report_dependencies_level) {
case 4:
case 3:
case 2:
case 1:
}
if (trace_status) {
}
if (quest) {
}
if (silent_all) {
}
if (touch) {
}
if (build_unconditional) {
}
if (report_cwd) {
}
/* -c dmake_rcfile */
if (dmake_rcfile_specified) {
}
/* -g dmake_group */
if (dmake_group_specified) {
}
/* -j dmake_max_jobs */
if (dmake_max_jobs_specified) {
}
/* -m dmake_mode */
if (dmake_mode_specified) {
}
/* -x dmake_compat_mode */
// if (dmake_compat_mode_specified) {
// MBSTOWCS(wcs_buffer, "SUN_MAKE_COMPAT_MODE");
// dmake_compat_mode = GETNAME(wcs_buffer, FIND_LENGTH);
// append_makeflags_string(dmake_compat_mode, &makeflags_string);
// append_makeflags_string(dmake_compat_mode, &makeflags_string_posix);
// }
/* -x dmake_output_mode */
if (dmake_output_mode_specified) {
}
/* -o dmake_odir */
if (dmake_odir_specified) {
}
/* -M pmake_machinesfile */
if (pmake_machinesfile_specified) {
}
/* -R */
if (pmake_cap_r_specified) {
}
/*
* Make sure MAKEFLAGS is exported
*/
false);
} else {
false);
}
}
/*
* Add command line macro to POSIX makeflags_string
*/
if (makeflags_and_macro.start) {
tmp_char = (char) space_char;
do {
}
/*
* Now set the value of MAKEFLAGS macro in accordance
* with current mode.
*/
} else {
}
);
} else {
);
} else {
);
}
}
, false
);
/*
* Read command line "-f" arguments and ignore -c, g, j, K, M, m, O and o args.
*/
do_not_exec_rule = false;
if (read_trace_level > 0) {
trace_reader = true;
}
for (i = 1; i < argc; i++) {
if (argv[i] &&
(argv[i][0] == (int) hyphen_char) &&
if (i >= argc - 1) {
}
(void) read_makefile(primary_makefile, true, true, true);
makefile_read = true;
} else if (argv[i] &&
(argv[i][0] == (int) hyphen_char) &&
}
}
/*
* If no command line "-f" args then look for "makefile", and then for
* "Makefile" if "makefile" isn't found.
*/
if (!makefile_read) {
(wchar_t *) NULL,
(wchar_t *) NULL);
if (!posix) {
}
false,
false,
true);
}
if (!makefile_read &&
false,
false,
true);
}
} else {
}
}
false,
false,
true);
} else {
false,
false,
true);
}
}
if (!makefile_read &&
false,
false,
true);
} else {
false,
false,
true);
}
}
if (!makefile_read &&
false,
false,
true);
}
if (!makefile_read &&
false,
false,
true);
}
}
}
trace_reader = false;
/*
* Now get current value of MAKEFLAGS and compare it with
* the saved value we set before reading makefile.
* If they are different then MAKEFLAGS is subsequently set by
* makefile, just leave it there. Otherwise, if make mode
* is changed by using .POSIX target in makefile we need
* to correct MAKEFLAGS value.
*/
{
false);
} else {
false);
} else {
false);
}
}
}
if (makeflags_string.free_after_use) {
}
}
if (posix) {
/*
* If the user did not redefine the ARFLAGS macro in the
* default makefile (make.rules), then we'd like to
* change the macro value of ARFLAGS to be in accordance
* with "POSIX" requirements.
*/
"rv"))) {
false);
}
}
}
/*
* Make sure KEEP_STATE is in the environment if KEEP_STATE is on.
*/
keep_state = true;
}
if (keep_state) {
}
(void) SETVAR(keep_state_name,
false);
/*
* Read state file
*/
/* Before we read state, let's make sure we have
** right state file.
*/
/* just in case macro references are used in make_state file
** name, we better expand them at this stage using expand_value.
*/
/* copy the make_state structure to the other
** and then let make_state point to the new
** one.
*/
/* Just a kludge to avoid two slashes back to back */
}
/* adjust the length to reflect the appended string */
}
} else { /* the file doesn't exist or no permission */
char *slashp;
}
}
}
}
}
if (report_dependencies_level != 1) {
if (read_trace_level > 1) {
trace_reader = true;
}
(void) read_simple_file(make_state,
false,
false,
false,
false,
false,
true);
trace_reader = false;
}
}
}
/*
* Scan the argv for options and "=" type args and make them readonly.
*/
static void
{
register char *cp;
register int i;
int length;
char tmp_char;
wchar_t *tmp_wcs_buffer;
/* Read argv options and "=" type args and make them readonly. */
for (i = 1; i < argc; ++i) {
append = false;
continue;
((argv[i][0] == (int) ' ') &&
opt_separator = i;
continue;
case 1: /* -f seen */
++i;
continue;
case 2: /* -c seen */
}
break;
case 4: /* -g seen */
}
break;
case 8: /* -j seen */
}
break;
case 16: /* -M seen */
}
break;
case 32: /* -m seen */
}
break;
case 256: /* -K seen */
}
keep_state = true;
continue;
case 512: /* -o seen */
}
break;
case 1024: /* -x seen */
}
break;
}
} else {
argv[i+1]);
continue;
}
break;
default: /* Shouldn't reach here */
continue;
}
if (i == (argc - 1)) {
break;
}
} else {
}
/*
* Combine all macro in dynamic array
*/
{
append = true;
cp--;
}
}
if(!append)
cp--;
}
while (*cp != (int) equal_char) {
cp++;
}
cp++;
cp++;
}
} else {
}
} else {
/* Illegal MAKEFLAGS argument */
continue;
}
if(append) {
append = false;
} else {
}
}
}
/*
* Append the DMake option and value to the MAKEFLAGS string.
*/
static void
{
const char *option;
option = " -g ";
option = " -j ";
option = " -m ";
option = " -o ";
option = " -c ";
option = " -M ";
option = " -x DMAKE_OUTPUT_MODE=";
option = " -x SUN_MAKE_COMPAT_MODE=";
} else {
}
return;
}
}
/*
* read_environment(read_only)
*
* This routine reads the process environment when make starts and enters
* it as make macros. The environment variable SHELL is ignored.
*
* Parameters:
* read_only Should we make env vars read only?
*
* Global variables used:
* report_pwd Set if this make was started by other make
*/
static void
{
register char **environment;
int length;
wchar_t *tmp_wcs_buffer;
register wchar_t *name;
register wchar_t *value;
reading_environment = true;
for (; *environment; environment++) {
alloced_tmp_wcs_buffer = true;
} else {
name = wcs_buffer;
}
/*
* Looks like there's a bug in the system, but sometimes
* you can get blank lines in *environment.
*/
if (!value) {
continue;
}
continue;
}
report_pwd = true;
/*
* In POSIX mode we do not want MAKEFLAGS to be readonly.
* If the MAKEFLAGS macro is subsequently set by the makefile,
* it replaces the MAKEFLAGS variable currently found in the
* environment.
*/
if(posix) {
read_only_saved = false;
}
}
/*
* We ignore SUNPRO_DEPENDENCIES. This environment variable is
* set by make and read by cpp which then writes info to
* .make.dependency.xxx. When make is invoked by another make
* (recursive make), we don't want to read this because then
* the child make will end up writing to the parent
* directory's .make.state and clobbering them.
*/
continue;
}
true;
false, no_daemon, false, debug_level);
} else {
false, no_daemon, false, debug_level);
}
if (alloced_tmp_wcs_buffer) {
alloced_tmp_wcs_buffer = false;
}
}
reading_environment = false;
}
/*
* read_makefile(makefile, complain, must_exist, report_file)
*
* Read one makefile and check the result
*
* Return value:
* false is the read failed
*
* Parameters:
* makefile The file to read
* complain Passed thru to read_simple_file()
* must_exist Passed thru to read_simple_file()
* report_file Passed thru to read_simple_file()
*
* Global variables used:
* makefile_type Set to indicate we are reading main file
* recursion_level Initialized
*/
static Boolean
{
Boolean b;
recursion_level = 0;
reading_dependencies = true;
must_exist, report_file, false);
reading_dependencies = false;
return b;
}
/*
* make_targets(argc, argv, parallel_flag)
*
* Call doname on the specified targets
*
* Parameters:
* argc You know what this is
* argv You know what this is
* parallel_flag True if building in parallel
*
* Global variables used:
* build_failed_seen Used to generated message after failed -k
* commands_done Used to generate message "Up to date"
* default_target_to_build First proper target in makefile
* init The Name ".INIT", use to run command
* parallel Global parallel building flag
* quest make -q, suppresses messages
* recursion_level Initialized, used for tracing
* report_dependencies make -P, regroves whole process
*/
static void
{
int i;
char *cp;
recursion_level = 1;
/*
* make remaining args
*/
/*
if ((report_dependencies_level == 0) && parallel) {
*/
if (parallel) {
/*
* If building targets in parallel, start all of the
* remaining args to build in parallel.
*/
for (i = 1; i < argc; i++) {
commands_done = false;
if ((cp[0] == (int) period_char) &&
cp += 2;
}
if((cp[0] == (int) ' ') &&
continue;
}
//default_target_to_build = GETNAME(wcs_buffer,
// FIND_LENGTH);
wcslen(wcs_buffer));
if (default_target_to_build == wait_name) {
if (parallel_process_cnt > 0) {
}
continue;
}
/*
* If we can't execute the current target in
* parallel, hold off the target processing
* to preserve the order of the targets as they appeared
* in command line.
*/
if (!parallel_ok(default_target_to_build, false)
&& parallel_process_cnt > 0) {
}
true,
false,
false);
if (/* !commands_done && */
!quest &&
(report_dependencies_level == 0) /* &&
(exists(default_target_to_build) > file_doesnt_exist) */) {
if (posix) {
if (!commands_done) {
} else {
if (no_action_was_taken) {
}
}
} else {
if (!commands_done &&
}
}
}
}
}
/* Now wait for all of the targets to finish running */
// setjmp(jmpbuffer);
}
for (i = 1; i < argc; i++) {
target_to_make_found = true;
if ((cp[0] == (int) period_char) &&
cp += 2;
}
if((cp[0] == (int) ' ') &&
continue;
}
commands_done = false;
if (parallel) {
} else {
true,
false,
false);
}
if (build_failed_seen) {
build_failed_ever_seen = true;
}
build_failed_seen = false;
if (report_dependencies_level > 0) {
line_prop));
}
if (default_target_to_build->colon_splits > 0) {
}
if (!parallel &&
/* !commands_done && */
!quest &&
(report_dependencies_level == 0) /* &&
(exists(default_target_to_build) > file_doesnt_exist) */) {
if (posix) {
if (!commands_done) {
} else {
if (no_action_was_taken) {
}
}
} else {
if (!commands_done &&
}
}
}
}
}
/*
* If no file arguments have been encountered,
* make the first name encountered that doesnt start with a dot
*/
if (!target_to_make_found) {
if (default_target_to_build == NULL) {
}
commands_done = false;
if (getenv("SPRO_EXPAND_ERRORS")){
(void) printf("::(%s)\n",
}
if (build_failed_seen) {
build_failed_ever_seen = true;
}
build_failed_seen = false;
if (report_dependencies_level > 0) {
prop,
line_prop));
}
if (default_target_to_build->colon_splits > 0) {
}
if (/* !commands_done && */
!quest &&
(report_dependencies_level == 0) /* &&
(exists(default_target_to_build) > file_doesnt_exist) */) {
if (posix) {
if (!commands_done) {
} else {
if (no_action_was_taken) {
}
}
} else {
if (!commands_done &&
}
}
}
}
}
/*
* report_recursion(target)
*
* If this is a recursive make and the parent make has KEEP_STATE on
* this routine reports the dependency to the parent make
*
* Parameters:
* target Target to report
*
* Global variables used:
* makefiles_used List of makefiles read
* recursive_name The Name ".RECURSIVE", printed
* report_dependency dwight
*/
static void
{
return;
}
if (primary_makefile == NULL) {
/*
* This can happen when there is no makefile and
* only implicit rules are being used.
*/
return;
}
(void) fprintf(report_file,
"%s: %s ",
}
/* Next function "append_or_replace_macro_in_dyn_array" must be in "misc.cc". */
/* NIKMOL */
extern void
{
register int len_array;
register int len_macro;
int esc_len;
name++;
}
/* no '=' in macro */
goto ERROR_MACRO;
}
value++;
value++;
}
cp0--;
}
/* another name */
cp1++;
goto LOOK_FOR_NAME;
}
/* another name */
cp1++;
goto LOOK_FOR_NAME;
}
}
/* else: another name */
cp1++;
goto LOOK_FOR_NAME;
}
/* Look for the next macro name in array */
if (*cp3 != (int) doublequote_char) {
/* internal error */
goto ERROR_MACRO;
}
/* internal error */
goto ERROR_MACRO;
}
cp3++;
cp3++;
}
}
}
*cp2 = 0;
}
if (*cp1) {
/* check next name */
goto LOOK_FOR_NAME;
}
goto APPEND_MACRO;
} else {
cp1 = 0;
}
}
if (cp1) {
}
return;
return;
}
static void
{
int make_level_val = 0;
if(make_level_str) {
}
}
if(entering) {
} else {
}
if(report_cwd) {
if(make_level_val <= 0) {
if(entering) {
gettext("%s: Entering directory `%s'\n"),
getprogname(),
get_current_path());
} else {
gettext("%s: Leaving directory `%s'\n"),
getprogname(),
get_current_path());
}
} else {
if(entering) {
gettext("%s[%d]: Entering directory `%s'\n"),
getprogname(),
} else {
gettext("%s[%d]: Leaving directory `%s'\n"),
getprogname(),
}
}
}
}