📄 gcc.c
字号:
/* Suffix to attach to directories searched for commands. This looks like `MACHINE/VERSION/'. */static char *machine_suffix = 0;/* Suffix to attach to directories searched for commands. This is just `MACHINE/'. */static char *just_machine_suffix = 0;/* Adjusted value of GCC_EXEC_PREFIX envvar. */static char *gcc_exec_prefix;/* Default prefixes to attach to command names. */#ifdef CROSS_COMPILE /* Don't use these prefixes for a cross compiler. */#undef MD_EXEC_PREFIX#undef MD_STARTFILE_PREFIX#undef MD_STARTFILE_PREFIX_1#endif#ifndef STANDARD_EXEC_PREFIX#define STANDARD_EXEC_PREFIX "/usr/libexec/gcc2/"#endif /* !defined STANDARD_EXEC_PREFIX */static char *standard_exec_prefix = STANDARD_EXEC_PREFIX;static char *standard_exec_prefix_1 = "/usr/lib/gcc/";#ifdef MD_EXEC_PREFIXstatic char *md_exec_prefix = MD_EXEC_PREFIX;#endif#ifndef STANDARD_STARTFILE_PREFIX#define STANDARD_STARTFILE_PREFIX "/usr/local/lib/"#endif /* !defined STANDARD_STARTFILE_PREFIX */#ifdef MD_STARTFILE_PREFIXstatic char *md_startfile_prefix = MD_STARTFILE_PREFIX;#endif#ifdef MD_STARTFILE_PREFIX_1static char *md_startfile_prefix_1 = MD_STARTFILE_PREFIX_1;#endifstatic char *standard_startfile_prefix = STANDARD_STARTFILE_PREFIX;static char *standard_startfile_prefix_1 = "/lib/";static char *standard_startfile_prefix_2 = "/usr/lib/";/* Clear out the vector of arguments (after a command is executed). */static voidclear_args (){ argbuf_index = 0;}/* Add one argument to the vector at the end. This is done when a space is seen or at the end of the line. If DELETE_ALWAYS is nonzero, the arg is a filename and the file should be deleted eventually. If DELETE_FAILURE is nonzero, the arg is a filename and the file should be deleted if this compilation fails. */static voidstore_arg (arg, delete_always, delete_failure) char *arg; int delete_always, delete_failure;{ if (argbuf_index + 1 == argbuf_length) { argbuf = (char **) xrealloc (argbuf, (argbuf_length *= 2) * sizeof (char *)); } argbuf[argbuf_index++] = arg; argbuf[argbuf_index] = 0; if (delete_always || delete_failure) record_temp_file (arg, delete_always, delete_failure);}/* Record the names of temporary files we tell compilers to write, and delete them at the end of the run. *//* This is the common prefix we use to make temp file names. It is chosen once for each run of this program. It is substituted into a spec by %g. Thus, all temp file names contain this prefix. In practice, all temp file names start with this prefix. This prefix comes from the envvar TMPDIR if it is defined; otherwise, from the P_tmpdir macro if that is defined; otherwise, in /usr/tmp or /tmp. */static char *temp_filename;/* Length of the prefix. */static int temp_filename_length;/* Define the list of temporary files to delete. */struct temp_file{ char *name; struct temp_file *next;};/* Queue of files to delete on success or failure of compilation. */static struct temp_file *always_delete_queue;/* Queue of files to delete on failure of compilation. */static struct temp_file *failure_delete_queue;/* Record FILENAME as a file to be deleted automatically. ALWAYS_DELETE nonzero means delete it if all compilation succeeds; otherwise delete it in any case. FAIL_DELETE nonzero means delete it if a compilation step fails; otherwise delete it in any case. */static voidrecord_temp_file (filename, always_delete, fail_delete) char *filename; int always_delete; int fail_delete;{ register char *name; name = xmalloc (strlen (filename) + 1); strcpy (name, filename); if (always_delete) { register struct temp_file *temp; for (temp = always_delete_queue; temp; temp = temp->next) if (! strcmp (name, temp->name)) goto already1; temp = (struct temp_file *) xmalloc (sizeof (struct temp_file)); temp->next = always_delete_queue; temp->name = name; always_delete_queue = temp; already1:; } if (fail_delete) { register struct temp_file *temp; for (temp = failure_delete_queue; temp; temp = temp->next) if (! strcmp (name, temp->name)) goto already2; temp = (struct temp_file *) xmalloc (sizeof (struct temp_file)); temp->next = failure_delete_queue; temp->name = name; failure_delete_queue = temp; already2:; }}/* Delete all the temporary files whose names we previously recorded. */static voiddelete_temp_files (){ register struct temp_file *temp; for (temp = always_delete_queue; temp; temp = temp->next) {#ifdef DEBUG int i; printf ("Delete %s? (y or n) ", temp->name); fflush (stdout); i = getchar (); if (i != '\n') while (getchar () != '\n') ; if (i == 'y' || i == 'Y')#endif /* DEBUG */ { struct stat st; if (stat (temp->name, &st) >= 0) { /* Delete only ordinary files. */ if (S_ISREG (st.st_mode)) if (unlink (temp->name) < 0) if (verbose_flag) perror_with_name (temp->name); } } } always_delete_queue = 0;}/* Delete all the files to be deleted on error. */static voiddelete_failure_queue (){ register struct temp_file *temp; for (temp = failure_delete_queue; temp; temp = temp->next) {#ifdef DEBUG int i; printf ("Delete %s? (y or n) ", temp->name); fflush (stdout); i = getchar (); if (i != '\n') while (getchar () != '\n') ; if (i == 'y' || i == 'Y')#endif /* DEBUG */ { if (unlink (temp->name) < 0) if (verbose_flag) perror_with_name (temp->name); } }}static voidclear_failure_queue (){ failure_delete_queue = 0;}/* Compute a string to use as the base of all temporary file names. It is substituted for %g. */static voidchoose_temp_base (){ char *base = getenv ("TMPDIR"); int len; if (base == (char *)0) {#ifdef P_tmpdir if (access (P_tmpdir, R_OK | W_OK) == 0) base = P_tmpdir;#endif if (base == (char *)0) { if (access ("/usr/tmp", R_OK | W_OK) == 0) base = "/usr/tmp/"; else base = "/tmp/"; } } len = strlen (base); temp_filename = xmalloc (len + sizeof("/ccXXXXXX")); strcpy (temp_filename, base); if (len > 0 && temp_filename[len-1] != '/') temp_filename[len++] = '/'; strcpy (temp_filename + len, "ccXXXXXX"); mktemp (temp_filename); temp_filename_length = strlen (temp_filename); if (temp_filename_length == 0) abort ();}/* Routine to add variables to the environment. We do this to pass the pathname of the gcc driver, and the directories search to the collect2 program, which is being run as ld. This way, we can be sure of executing the right compiler when collect2 wants to build constructors and destructors. Since the environment variables we use come from an obstack, we don't have to worry about allocating space for them. */#ifndef HAVE_PUTENVputenv (str) char *str;{#ifndef VMS /* nor about VMS */ extern char **environ; char **old_environ = environ; char **envp; int num_envs = 0; int name_len = 1; int str_len = strlen (str); char *p = str; int ch; while ((ch = *p++) != '\0' && ch != '=') name_len++; if (!ch) abort (); /* Search for replacing an existing environment variable, and count the number of total environment variables. */ for (envp = old_environ; *envp; envp++) { num_envs++; if (!strncmp (str, *envp, name_len)) { *envp = str; return; } } /* Add a new environment variable */ environ = (char **) xmalloc (sizeof (char *) * (num_envs+2)); *environ = str; bcopy (old_environ, environ+1, sizeof (char *) * (num_envs+1));#endif /* VMS */}#endif /* HAVE_PUTENV *//* Rebuild the COMPILER_PATH and LIBRARY_PATH environment variables for collect. */static voidputenv_from_prefixes (paths, env_var) struct path_prefix *paths; char *env_var;{ int suffix_len = (machine_suffix) ? strlen (machine_suffix) : 0; int first_time = TRUE; struct prefix_list *pprefix; obstack_grow (&collect_obstack, env_var, strlen (env_var)); for (pprefix = paths->plist; pprefix != 0; pprefix = pprefix->next) { int len = strlen (pprefix->prefix); if (machine_suffix) { if (!first_time) obstack_grow (&collect_obstack, ":", 1); first_time = FALSE; obstack_grow (&collect_obstack, pprefix->prefix, len); obstack_grow (&collect_obstack, machine_suffix, suffix_len); } if (just_machine_suffix && pprefix->require_machine_suffix == 2) { if (!first_time) obstack_grow (&collect_obstack, ":", 1); first_time = FALSE; obstack_grow (&collect_obstack, pprefix->prefix, len); obstack_grow (&collect_obstack, machine_suffix, suffix_len); } if (!pprefix->require_machine_suffix) { if (!first_time) obstack_grow (&collect_obstack, ":", 1); first_time = FALSE; obstack_grow (&collect_obstack, pprefix->prefix, len); } } obstack_grow (&collect_obstack, "\0", 1); putenv (obstack_finish (&collect_obstack));}/* Search for NAME using the prefix list PREFIXES. MODE is passed to access to check permissions. Return 0 if not found, otherwise return its name, allocated with malloc. */static char *find_a_file (pprefix, name, mode) struct path_prefix *pprefix; char *name; int mode;{ char *temp; char *file_suffix = ((mode & X_OK) != 0 ? EXECUTABLE_SUFFIX : ""); struct prefix_list *pl; int len = pprefix->max_len + strlen (name) + strlen (file_suffix) + 1; if (machine_suffix) len += strlen (machine_suffix); temp = xmalloc (len); /* Determine the filename to execute (special case for absolute paths). */ if (*name == '/') { if (access (name, mode)) { strcpy (temp, name); return temp; } } else for (pl = pprefix->plist; pl; pl = pl->next) { if (machine_suffix) { strcpy (temp, pl->prefix); strcat (temp, machine_suffix); strcat (temp, name); if (access (temp, mode) == 0) { if (pl->used_flag_ptr != 0) *pl->used_flag_ptr = 1; return temp; } /* Some systems have a suffix for executable files. So try appending that. */ if (file_suffix[0] != 0) { strcat (temp, file_suffix); if (access (temp, mode) == 0) { if (pl->used_flag_ptr != 0) *pl->used_flag_ptr = 1; return temp; } } } /* Certain prefixes are tried with just the machine type, not the version. This is used for finding as, ld, etc. */ if (just_machine_suffix && pl->require_machine_suffix == 2) { strcpy (temp, pl->prefix); strcat (temp, just_machine_suffix); strcat (temp, name); if (access (temp, mode) == 0) { if (pl->used_flag_ptr != 0) *pl->used_flag_ptr = 1; return temp; } /* Some systems have a suffix for executable files. So try appending that. */ if (file_suffix[0] != 0) { strcat (temp, file_suffix); if (access (temp, mode) == 0) { if (pl->used_flag_ptr != 0) *pl->used_flag_ptr = 1; return temp; } } } /* Certain prefixes can't be used without the machine suffix when the machine or version is explicitly specified. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -