/* Argument parsing and main program of GNU Make.
Copyright (C) 1988-2022 Free Software Foundation, Inc.
This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3 of the License, or (at your option) any later
version.
GNU Make is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program. If not, see <https://www.gnu.org/licenses/>. */
#include "makeint.h"
#include "os.h"
#include "filedef.h"
#include "dep.h"
#include "variable.h"
#include "job.h"
#include "commands.h"
#include "rule.h"
#include "debug.h"
#include "getopt.h"
#include "shuffle.h"
#include <assert.h>
#ifdef _AMIGA
# include <dos/dos.h>
# include <proto/dos.h>
#endif
#ifdef WINDOWS32
# include <windows.h>
# include <io.h>
#ifdef HAVE_STRINGS_H
# include <strings.h> /* for strcasecmp */
#endif
# include "pathstuff.h"
# include "sub_proc.h"
# include "w32err.h"
#endif
#ifdef __EMX__
# include <sys/types.h>
# include <sys/wait.h>
#endif
#ifdef HAVE_FCNTL_H
# include <fcntl.h>
#endif
#ifdef _AMIGA
int __stack = 20000; /* Make sure we have 20K of stack space */
#endif
#ifdef VMS
int vms_use_mcr_command = 0;
int vms_always_use_cmd_file = 0;
int vms_gnv_shell = 0;
int vms_legacy_behavior = 0;
int vms_comma_separator = 0;
int vms_unix_simulation = 0;
int vms_report_unix_paths = 0;
/* Evaluates if a VMS environment option is set, only look at first character */
static int
get_vms_env_flag (const char *name, int default_value)
{
char * value;
char x;
value = getenv (name);
if (value == NULL)
return default_value;
x = toupper (value[0]);
switch (x)
{
case '1':
case 'T':
case 'E':
return 1;
break;
case '0':
case 'F':
case 'D':
return 0;
}
}
#endif
#if defined HAVE_WAITPID || defined HAVE_WAIT3
# define HAVE_WAIT_NOHANG
#endif
#ifndef HAVE_UNISTD_H
int chdir ();
#endif
#ifndef STDC_HEADERS
# ifndef sun /* Sun has an incorrect decl in a header. */
void exit (int) NORETURN;
# endif
double atof ();
#endif
static void clean_jobserver (int status);
static void print_data_base (void);
static void print_version (void);
static void decode_switches (int argc, const char **argv, int env);
static struct variable *define_makeflags (int all, int makefile);
static char *quote_for_env (char *out, const char *in);
static void initialize_global_hash_tables (void);
/* True if C is a switch value that corresponds to a short option. */
#define short_option(c) ((c) <= CHAR_MAX)
/* The structure used to hold the list of strings given
in command switches of a type that takes strlist arguments. */
struct stringlist
{
const char **list; /* Nil-terminated list of strings. */
unsigned int idx; /* Index into above. */
unsigned int max; /* Number of pointers allocated. */
};
/* The recognized command switches. */
/* Nonzero means do extra verification (that may slow things down). */
int verify_flag;
/* Nonzero means do not print commands to be executed (-s). */
static int silent_flag;
static const int default_silent_flag = 0;
/* Nonzero means either -s was given, or .SILENT-with-no-deps was seen. */
int run_silent = 0;
/* Nonzero means just touch the files
that would appear to need remaking (-t) */
int touch_flag;
/* Nonzero means just print what commands would need to be executed,
don't actually execute them (-n). */
int just_print_flag;
/* Print debugging info (--debug). */
static struct stringlist *db_flags = 0;
static int debug_flag = 0;
int db_level = 0;
/* Synchronize output (--output-sync). */
char *output_sync_option = 0;
/* Environment variables override makefile definitions. */
int env_overrides = 0;
/* Nonzero means ignore status codes returned by commands
executed to remake files. Just treat them all as successful (-i). */
int ignore_errors_flag = 0;
/* Nonzero means don't remake anything, just print the data base
that results from reading the makefile (-p). */
int print_data_base_flag = 0;
/* Nonzero means don't remake anything; just return a nonzero status
if the specified targets are not up to date (-q). */
int question_flag = 0;
/* Nonzero means do not use any of the builtin rules (-r) / variables (-R). */
int no_builtin_rules_flag = 0;
int no_builtin_variables_flag = 0;
/* Nonzero means keep going even if remaking some file fails (-k). */
int keep_going_flag;
static const int default_keep_going_flag = 0;
/* Nonzero means check symlink mtimes. */
int check_symlink_flag = 0;
/* Nonzero means print directory before starting and when done (-w). */
int print_directory;
static int print_directory_flag = -1;
static const int default_print_directory_flag = -1;
/* Nonzero means print version information. */
int print_version_flag = 0;
/* List of makefiles given with -f switches. */
static struct stringlist *makefiles = 0;
/* Size of the stack when we started. */
#ifdef SET_STACK_SIZE
struct rlimit stack_limit;
#endif
/* Number of job slots for parallelism. */
unsigned int job_slots;
#define INVALID_JOB_SLOTS (-1)
static unsigned int master_job_slots = 0;
static int arg_job_slots = INVALID_JOB_SLOTS;
static const int default_job_slots = INVALID_JOB_SLOTS;
/* Value of job_slots that means no limit. */
static const int inf_jobs = 0;
/* Authorization for the jobserver. */
char *jobserver_auth = NULL;
/* Style for the jobserver. */
static char *jobserver_style = NULL;
/* Shuffle mode for goals and prerequisites. */
static char *shuffle_mode = NULL;
/* Handle for the mutex to synchronize output of our children under -O. */
static char *sync_mutex = NULL;
/* Maximum load average at which multiple jobs will be run.
Negative values mean unlimited, while zero means limit to
zero load (which could be useful to start infinite jobs remotely
but one at a time locally). */
double max_load_average = -1.0;
double default_load_average = -1.0;
/* List of directories given with -C switches. */
static struct stringlist *directories = 0;
/* List of include directories given with -I switches. */
static struct stringlist *include_dirs = 0;
/* List of files given with -o switches. */
static struct stringlist *old_files = 0;
/* List of files given with -W switches. */
static struct stringlist *new_files = 0;
/* List of strings to be eval'd. */
static struct stringlist *eval_strings = 0;
/* If nonzero, we should just print usage and exit. */
static int print_usage_flag = 0;
/* If nonzero, we should print a warning message
for each reference to an undefined variable. */
int warn_undefined_variables_flag;
/* If nonzero, always build all targets, regardless of whether
they appear out of date or not. */
static int always_make_set = 0;
int always_make_flag = 0;
/* If nonzero, we're in the "try to rebuild makefiles" phase. */
int rebuilding_makefiles = 0;
/* Remember the original value of the SHELL variable, from the environment. */
struct variable shell_var;
/* This character introduces a command: it's the first char on the line. */
char cmd_prefix = '\t';
/* Count the number of commands we've invoked, that might change something in
the filesystem. Start with 1 so calloc'd memory never matches. */
unsigned long command_count = 1;
/* Remember the location of the name of the batch file from stdin. */
static int stdin_offset = -1;
/* The usage output. We write it this way to make life easier for the
translators, especially those trying to translate to right-to-left
languages like Hebrew. */
static const char *const usage[] =
{
N_("Options:\n"),
N_("\
-b, -