⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gcc.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
/* Compiler driver program that can handle many languages.   Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.This file is part of GNU CC.GNU CC is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2, or (at your option)any later version.GNU CC is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with GNU CC; see the file COPYING.  If not, write tothe Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.This paragraph is here to try to keep Sun CC from dying.The number of chars here seems crucial!!!!  *//* This program is the user interface to the C compiler and possibly toother compilers.  It is used because compilation is a complicated procedurewhich involves running several programs and passing temporary files betweenthem, forwarding the users switches to those programs selectively,and deleting the temporary files at the end.CC recognizes how to compile each input file by suffixes in the file names.Once it knows which kind of compilation to perform, the procedure forcompilation is specified by a string called a "spec".  */#include <sys/types.h>#include <ctype.h>#include <signal.h>#include <sys/stat.h>#include <sys/file.h>   /* May get R_OK, etc. on some systems.  */#include "config.h"#include "obstack.h"#include "gvarargs.h"#include <stdio.h>#ifndef R_OK#define R_OK 4#define W_OK 2#define X_OK 1#endif/* Define a generic NULL if one hasn't already been defined.  */#ifndef NULL#define NULL 0#endif#ifndef GENERIC_PTR#if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__)#define GENERIC_PTR void *#else#define GENERIC_PTR char *#endif#endif#ifndef NULL_PTR#define NULL_PTR ((GENERIC_PTR)0)#endif#ifdef USG#define vfork fork#endif /* USG *//* On MSDOS, write temp files in current dir   because there's no place else we can expect to use.  */#if __MSDOS__#ifndef P_tmpdir#define P_tmpdir "./"#endif#endif/* Test if something is a normal file.  */#ifndef S_ISREG#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)#endif/* Test if something is a directory.  */#ifndef S_ISDIR#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)#endif/* By default there is no special suffix for executables.  */#ifndef EXECUTABLE_SUFFIX#define EXECUTABLE_SUFFIX ""#endif/* By default, colon separates directories in a path.  */#ifndef PATH_SEPARATOR#define PATH_SEPARATOR ':'#endif#define obstack_chunk_alloc xmalloc#define obstack_chunk_free freeextern void free ();extern char *getenv ();extern int errno, sys_nerr;extern const char *const sys_errlist[];extern int execv (), execvp ();/* If a stage of compilation returns an exit status >= 1,   compilation of that file ceases.  */#define MIN_FATAL_STATUS 1/* Flag saying to print the full filename of libgcc.a   as found through our usual search mechanism.  */static int print_libgcc_file_name;/* Flag indicating whether we should print the command and arguments */static int verbose_flag;/* Nonzero means write "temp" files in source directory   and use the source file's name in them, and don't delete them.  */static int save_temps_flag;/* The compiler version specified with -V */static char *spec_version;/* The target machine specified with -b.  */static char *spec_machine = DEFAULT_TARGET_MACHINE;/* Nonzero if cross-compiling.   When -b is used, the value comes from the `specs' file.  */#ifdef CROSS_COMPILEstatic int cross_compile = 1;#elsestatic int cross_compile = 0;#endif/* This is the obstack which we use to allocate many strings.  */static struct obstack obstack;/* This is the obstack to build an environment variable to pass to   collect2 that describes all of the relevant switches of what to   pass the compiler in building the list of pointers to constructors   and destructors.  */static struct obstack collect_obstack;extern char *version_string;static void set_spec ();static struct compiler *lookup_compiler ();static char *find_a_file ();static void add_prefix ();static char *skip_whitespace ();static void record_temp_file ();static char *handle_braces ();static char *save_string ();static char *concat ();static int do_spec ();static int do_spec_1 ();static char *find_file ();static int is_linker_dir ();static void validate_switches ();static void validate_all_switches ();static void give_switch ();static void pfatal_with_name ();static void perror_with_name ();static void perror_exec ();static void fatal ();static void error ();void fancy_abort ();char *xmalloc ();char *xrealloc ();/* Specs are strings containing lines, each of which (if not blank)is made up of a program name, and arguments separated by spaces.The program name must be exact and start from root, since no pathis searched and it is unreliable to depend on the current working directory.Redirection of input or output is not supported; the subprograms mustaccept filenames saying what files to read and write.In addition, the specs can contain %-sequences to substitute variable textor for conditional text.  Here is a table of all defined %-sequences.Note that spaces are not generated automatically around the results ofexpanding these sequences; therefore, you can concatenate them togetheror with constant text in a single argument. %%	substitute one % into the program name or argument. %i     substitute the name of the input file being processed. %b     substitute the basename of the input file being processed.	This is the substring up to (and not including) the last period	and not including the directory. %g     substitute the temporary-file-name-base.  This is a string chosen	once per compilation.  Different temporary file names are made by	concatenation of constant strings on the end, as in `%g.s'.	%g also has the same effect of %d. %u	like %g, but make the temporary file name unique. %U	returns the last file name generated with %u. %d	marks the argument containing or following the %d as a	temporary file name, so that that file will be deleted if CC exits	successfully.  Unlike %g, this contributes no text to the argument. %w	marks the argument containing or following the %w as the	"output file" of this compilation.  This puts the argument	into the sequence of arguments that %o will substitute later. %W{...}	like %{...} but mark last argument supplied within	as a file to be deleted on failure. %o	substitutes the names of all the output files, with spaces	automatically placed around them.  You should write spaces	around the %o as well or the results are undefined.	%o is for use in the specs for running the linker.	Input files whose names have no recognized suffix are not compiled	at all, but they are included among the output files, so they will	be linked. %p	substitutes the standard macro predefinitions for the	current target machine.  Use this when running cpp. %P	like %p, but puts `__' before and after the name of each macro.	(Except macros that already have __.)	This is for ANSI C. %I	Substitute a -iprefix option made from GCC_EXEC_PREFIX. %s     current argument is the name of a library or startup file of some sort.        Search for that file in a standard list of directories	and substitute the full name found. %eSTR  Print STR as an error message.  STR is terminated by a newline.        Use this when inconsistent options are detected. %x{OPTION}	Accumulate an option for %X. %X	Output the accumulated linker options specified by compilations. %Y	Output the accumulated assembler options specified by compilations. %a     process ASM_SPEC as a spec.        This allows config.h to specify part of the spec for running as. %A	process ASM_FINAL_SPEC as a spec.  A capital A is actually	used here.  This can be used to run a post-processor after the	assembler has done it's job. %D	Dump out a -L option for each directory in library_prefix,	followed by a -L option for each directory in startfile_prefix. %l     process LINK_SPEC as a spec. %L     process LIB_SPEC as a spec. %S     process STARTFILE_SPEC as a spec.  A capital S is actually used here. %E     process ENDFILE_SPEC as a spec.  A capital E is actually used here. %c	process SIGNED_CHAR_SPEC as a spec. %C     process CPP_SPEC as a spec.  A capital C is actually used here. %1	process CC1_SPEC as a spec. %2	process CC1PLUS_SPEC as a spec. %*	substitute the variable part of a matched option.  (See below.)	Note that each comma in the substituted string is replaced by	a single space. %{S}   substitutes the -S switch, if that switch was given to CC.	If that switch was not specified, this substitutes nothing.	Here S is a metasyntactic variable. %{S*}  substitutes all the switches specified to CC whose names start	with -S.  This is used for -o, -D, -I, etc; switches that take	arguments.  CC considers `-o foo' as being one switch whose	name starts with `o'.  %{o*} would substitute this text,	including the space; thus, two arguments would be generated. %{S*:X} substitutes X if one or more switches whose names start with -S are	specified to CC.  Note that the tail part of the -S option	(i.e. the part matched by the `*') will be substituted for each	occurrence of %* within X. %{S:X} substitutes X, but only if the -S switch was given to CC. %{!S:X} substitutes X, but only if the -S switch was NOT given to CC. %{|S:X} like %{S:X}, but if no S switch, substitute `-'. %{|!S:X} like %{!S:X}, but if there is an S switch, substitute `-'. %{.S:X} substitutes X, but only if processing a file with suffix S. %{!.S:X} substitutes X, but only if NOT processing a file with suffix S. %(Spec) processes a specification defined in a specs file as *Spec: %[Spec] as above, but put __ around -D argumentsThe conditional text X in a %{S:X} or %{!S:X} construct may containother nested % constructs or spaces, or even newlines.  They areprocessed as usual, as described above.The character | is used to indicate that a command should be piped tothe following command, but only if -pipe is specified.Note that it is built into CC which switches take arguments and whichdo not.  You might think it would be useful to generalize this toallow each compiler's spec to say which switches take arguments.  Butthis cannot be done in a consistent fashion.  CC cannot even decidewhich input files have been specified without knowing which switchestake arguments, and it must know which input files to compile in orderto tell which compilers to run.CC also knows implicitly that arguments starting in `-l' are to betreated as compiler output files, and passed to the linker in theirproper position among the other output files.  *//* Define the macros used for specs %a, %l, %L, %S, %c, %C, %1.  *//* config.h can define ASM_SPEC to provide extra args to the assembler   or extra switch-translations.  */#ifndef ASM_SPEC#define ASM_SPEC ""#endif/* config.h can define ASM_FINAL_SPEC to run a post processor after   the assembler has run.  */#ifndef ASM_FINAL_SPEC#define ASM_FINAL_SPEC ""#endif/* config.h can define CPP_SPEC to provide extra args to the C preprocessor   or extra switch-translations.  */#ifndef CPP_SPEC#define CPP_SPEC ""#endif/* config.h can define CC1_SPEC to provide extra args to cc1 and cc1plus   or extra switch-translations.  */#ifndef CC1_SPEC#define CC1_SPEC ""#endif/* config.h can define CC1PLUS_SPEC to provide extra args to cc1plus   or extra switch-translations.  */#ifndef CC1PLUS_SPEC#define CC1PLUS_SPEC ""#endif/* config.h can define LINK_SPEC to provide extra args to the linker   or extra switch-translations.  */#ifndef LINK_SPEC#define LINK_SPEC ""#endif/* config.h can define LIB_SPEC to override the default libraries.  */#ifndef LIB_SPEC#define LIB_SPEC "%{g*:-lg} %{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p}"#endif/* config.h can define STARTFILE_SPEC to override the default crt0 files.  */#ifndef STARTFILE_SPEC#define STARTFILE_SPEC  \  "%{pg:gcrt0.o%s}%{!pg:%{p:mcrt0.o%s}%{!p:crt0.o%s}}"#endif/* config.h can define SWITCHES_NEED_SPACES to control passing -o and -L.   Make the string nonempty to require spaces there.  */#ifndef SWITCHES_NEED_SPACES#define SWITCHES_NEED_SPACES ""#endif/* config.h can define ENDFILE_SPEC to override the default crtn files.  */#ifndef ENDFILE_SPEC#define ENDFILE_SPEC ""#endif/* This spec is used for telling cpp whether char is signed or not.  */#ifndef SIGNED_CHAR_SPEC/* Use #if rather than ?:   because MIPS C compiler rejects like ?: in initializers.  */#if DEFAULT_SIGNED_CHAR#define SIGNED_CHAR_SPEC "%{funsigned-char:-D__CHAR_UNSIGNED__}"#else#define SIGNED_CHAR_SPEC "%{!fsigned-char:-D__CHAR_UNSIGNED__}"#endif#endifstatic char *cpp_spec = CPP_SPEC;static char *cpp_predefines = CPP_PREDEFINES;static char *cc1_spec = CC1_SPEC;static char *cc1plus_spec = CC1PLUS_SPEC;static char *signed_char_spec = SIGNED_CHAR_SPEC;static char *asm_spec = ASM_SPEC;static char *asm_final_spec = ASM_FINAL_SPEC;static char *link_spec = LINK_SPEC;static char *lib_spec = LIB_SPEC;static char *endfile_spec = ENDFILE_SPEC;static char *startfile_spec = STARTFILE_SPEC;static char *switches_need_spaces = SWITCHES_NEED_SPACES;/* This defines which switch letters take arguments.  */#ifndef SWITCH_TAKES_ARG#define SWITCH_TAKES_ARG(CHAR)      \  ((CHAR) == 'D' || (CHAR) == 'U' || (CHAR) == 'o' \   || (CHAR) == 'e' || (CHAR) == 'T' || (CHAR) == 'u' \   || (CHAR) == 'I' || (CHAR) == 'm' \   || (CHAR) == 'L' || (CHAR) == 'A')#endif/* This defines which multi-letter switches take arguments.  */#ifndef WORD_SWITCH_TAKES_ARG#define WORD_SWITCH_TAKES_ARG(STR)			\ (!strcmp (STR, "Tdata") || !strcmp (STR, "Ttext")	\  || !strcmp (STR, "Tbss") || !strcmp (STR, "include")	\  || !strcmp (STR, "imacros") || !strcmp (STR, "aux-info"))#endif/* Record the mapping from file suffixes for compilation specs.  */struct compiler{  char *suffix;			/* Use this compiler for input files				   whose names end in this suffix.  */  char *spec[4];		/* To use this compiler, concatenate these				   specs and pass to do_spec.  */};/* Pointer to a vector of `struct compiler' that gives the spec for   compiling a file, based on its suffix.   A file that does not end in any of these suffixes will be passed   unchanged to the loader and nothing else will be done to it.   An entry containing two 0s is used to terminate the vector.   If multiple entries match a file, the last matching one is used.  */static struct compiler *compilers;/* Number of entries in `compilers', not counting the null terminator.  */static int n_compilers;/* The default list of file name suffixes and their compilation specs.  */static struct compiler default_compilers[] ={  {".c", "@c"},  {"@c",   "cpp -lang-c %{nostdinc*} %{C} %{v} %{A*} %{I*} %{P} %I\	%{C:%{!E:%eGNU C does not support -C without using -E}}\	%{M} %{MM} %{MD:-MD %b.d} %{MMD:-MMD %b.d}\        -undef -D__GNUC__=2 %{ansi:-trigraphs -$ -D__STRICT_ANSI__}\	%{!undef:%{!ansi:%p} %P} %{trigraphs} \        %c %{O*:-D__OPTIMIZE__} %{traditional} %{ftraditional:-traditional}\        %{traditional-cpp:-traditional}\	%{g*} %{W*} %{w} %{pedantic*} %{H} %{d*} %C %{D*} %{U*} %{i*}\        %i %{!M:%{!MM:%{!E:%{!pipe:%g.i}}}}%{E:%W{o*}}%{M:%W{o*}}%{MM:%W{o*}} |\n",   "%{!M:%{!MM:%{!E:cc1 %{!pipe:%g.i} %1 \		   %{!Q:-quiet} -dumpbase %b.c %{d*} %{m*} %{a}\		   %{g*} %{O*} %{W*} %{w} %{pedantic*} %{ansi} \		   %{traditional} %{v:-version} %{pg:-p} %{p} %{f*}\		   %{aux-info*}\		   %{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -