main validate_all_switches lookup_compiler do_spec do_spec_2 do_spec_1 /* Get hold of the name of the compiler */ execute pex_init pex_run pex_run_in_environment obj->funcs->exec_child /*********************************** gcc.c ********************************************/ int main (int argc, char **argv) { validate_all_switches (); for (i = 0; (int) i < n_infiles; i++) { const char *name = infiles[i].name; struct compiler *compiler = lookup_compiler (name, strlen (name), infiles[i].language); infiles[i].incompiler = compiler; } for (i = 0; (int) i < n_infiles; i++) { input_file_compiler = infiles[i].incompiler; if (input_file_compiler) { /* Ok, we found an applicable compiler. Run its spec. */ value = do_spec (input_file_compiler->spec); infiles[i].compiled = true; } } } /* Run ld to link all the compiler output files. */ value = do_spec (link_command_spec); } static struct compiler * lookup_compiler (const char *name, size_t length, const char *language) { struct compiler *cp; return cp; } struct compiler { const char *suffix; /* Use this compiler for input files whose names end in this suffix. */ const char *spec; /* To use this compiler, run this spec. */ const char *cpp_spec; /* If non-NULL, substitute this spec for `%C', rather than the usual cpp_spec. */ const int combinable; /* If nonzero, compiler can deal with multiple source files at once (IMA). */ const int needs_preprocessing; /* If nonzero, source files need to be run through a preprocessor. */ }; /* The default list of file name suffixes and their compilation specs. */ static const struct compiler default_compilers[] = { {".m", "#Objective-C", 0, 0, 0}, {".mi", "#Objective-C", 0, 0, 0}, {".mm", "#Objective-C++", 0, 0, 0}, {".M", "#Objective-C++", 0, 0, 0}, {".mii", "#Objective-C++", 0, 0, 0}, {".cc", "#C++", 0, 0, 0}, {".cxx", "#C++", 0, 0, 0}, {".cpp", "#C++", 0, 0, 0}, {".cp", "#C++", 0, 0, 0}, {".c++", "#C++", 0, 0, 0}, {".C", "#C++", 0, 0, 0}, {".CPP", "#C++", 0, 0, 0}, {".ii", "#C++", 0, 0, 0}, {".ads", "#Ada", 0, 0, 0}, {".adb", "#Ada", 0, 0, 0}, {".f", "#Fortran", 0, 0, 0}, {".F", "#Fortran", 0, 0, 0}, {".for", "#Fortran", 0, 0, 0}, {".FOR", "#Fortran", 0, 0, 0}, {".ftn", "#Fortran", 0, 0, 0}, {".FTN", "#Fortran", 0, 0, 0}, {".fpp", "#Fortran", 0, 0, 0}, {".FPP", "#Fortran", 0, 0, 0}, {".f90", "#Fortran", 0, 0, 0}, {".F90", "#Fortran", 0, 0, 0}, {".f95", "#Fortran", 0, 0, 0}, {".F95", "#Fortran", 0, 0, 0}, {".f03", "#Fortran", 0, 0, 0}, {".F03", "#Fortran", 0, 0, 0}, {".f08", "#Fortran", 0, 0, 0}, {".F08", "#Fortran", 0, 0, 0}, {".r", "#Ratfor", 0, 0, 0}, {".p", "#Pascal", 0, 0, 0}, {".pas", "#Pascal", 0, 0, 0}, {".java", "#Java", 0, 0, 0}, {".class", "#Java", 0, 0, 0}, {".zip", "#Java", 0, 0, 0}, {".jar", "#Java", 0, 0, 0}, /* Next come the entries for C. */ {".c", "@c", 0, 1, 1}, {"@c", /* cc1 has an integrated ISO C preprocessor. We should invoke the external preprocessor if -save-temps is given. */ "...", 0, 1, 1}, {"-", "%{!E:%e-E or -x required when input is from standard input}\ %(trad_capable_cpp) %(cpp_options) %(cpp_debug_options)", 0, 0, 0}, {".h", "@c-header", 0, 0, 0}, {"@c-header", /* cc1 has an integrated ISO C preprocessor. We should invoke the external preprocessor if -save-temps is given. */ "", 0, 0, 0}, {".i", "@cpp-output", 0, 1, 0}, {"@cpp-output", "%{!M:%{!MM:%{!E:cc1 -fpreprocessed %i %(cc1_options) %{!fsyntax-only:%(invoke_as)}}}}", 0, 1, 0}, {".s", "@assembler", 0, 1, 0}, {"@assembler", "%{!M:%{!MM:%{!E:%{!S:as %(asm_debug) %(asm_options) %i %A }}}}", 0, 1, 0}, {".sx", "@assembler-with-cpp", 0, 1, 0}, {".S", "@assembler-with-cpp", 0, 1, 0}, {"@assembler-with-cpp", #ifdef AS_NEEDS_DASH_FOR_PIPED_INPUT "%(trad_capable_cpp) -lang-asm %(cpp_options) -fno-directives-only\ %{E|M|MM:%(cpp_debug_options)}\ %{!M:%{!MM:%{!E:%{!S:-o %|.s |\n\ as %(asm_debug) %(asm_options) %|.s %A }}}}" #else "%(trad_capable_cpp) -lang-asm %(cpp_options) -fno-directives-only\ %{E|M|MM:%(cpp_debug_options)}\ %{!M:%{!MM:%{!E:%{!S:-o %|.s |\n\ as %(asm_debug) %(asm_options) %m.s %A }}}}" #endif , 0, 1, 0}, #include "specs.h" /* Mark end of table. */ {0, 0, 0, 0, 0} }; ---------------------------------------------------------------------------------------------------------- int do_spec (const char *spec) { int value; value = do_spec_2 (spec); value = execute (); return value; } static int do_spec_2 (const char *spec) { result = do_spec_1 (spec, 0, NULL); return result; } static int do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part) { { value = execute (); if (value) return value; } /* Here are digits and numbers that just process a certain constant string as a spec. */ case '1': value = do_spec_1 (cc1_spec, 0, NULL); if (value != 0) return value; break; case '2': value = do_spec_1 (cc1plus_spec, 0, NULL); if (value != 0) return value; break; case 'a': value = do_spec_1 (asm_spec, 0, NULL); if (value != 0) return value; break; case 'A': value = do_spec_1 (asm_final_spec, 0, NULL); if (value != 0) return value; break; case 'C': { const char *const spec = (input_file_compiler->cpp_spec ? input_file_compiler->cpp_spec : cpp_spec); value = do_spec_1 (spec, 0, NULL); if (value != 0) return value; } break; case 'l': value = do_spec_1 (link_spec, 0, NULL); if (value != 0) return value; break; case 'L': value = do_spec_1 (lib_spec, 0, NULL); if (value != 0) return value; break; case 'G': value = do_spec_1 (libgcc_spec, 0, NULL); if (value != 0) return value; break; return result; } static int execute (void) { struct command *commands; /* each command buffer with above info. */ /* Run each piped subprocess. */ pex = pex_init (PEX_USE_PIPES | (report_times ? PEX_RECORD_TIMES : 0), programname, temp_filename); for (i = 0; i < n_commands; i++) { const char *string = commands[i].argv[0]; errmsg = pex_run (pex, ((i + 1 == n_commands ? PEX_LAST : 0) | (string == commands[i].prog ? PEX_SEARCH : 0)), string, CONST_CAST (char **, commands[i].argv), NULL, NULL, &err); } execution_count++; /* Wait for all the subprocesses to finish. */ pex_free (pex); } /************************************ libiberty/pex-common.c **************************************/ /* Run a program. */ const char * pex_run (struct pex_obj *obj, int flags, const char *executable, char * const * argv, const char *orig_outname, const char *errname, int *err) { return pex_run_in_environment (obj, flags, executable, argv, NULL, orig_outname, errname, err); } /* As for pex_run (), but permits the environment for the child process to be specified. */ const char * pex_run_in_environment (struct pex_obj *obj, int flags, const char *executable, char * const * argv, char * const * env, const char *orig_outname, const char *errname, int *err) { /* Run the program. */ pid = obj->funcs->exec_child (obj, flags, executable, argv, env, in, out, errdes, toclose, &errmsg, err); }