gcc 源码阅读---程序入口
在gcc 默认编译中,会编译出gcc/g++,cc1这几个程序,
gcc 是个驱动型程序,完成c/c++转为汇编程,调用汇编程序转为.o文件,再调用link程序生成elf执行程序
cc1程序是真正的将c编译为汇篇程序,这是整个编译的核 心
gcc 入口:
gcc_main.c
int
main (int argc, char **argv)
{
driver d (false, /* can_finalize */
false); /* debug */
return d.main (argc, argv);
}
最后调用gcc.c
driver::main (int argc, char **argv)
cc1 入口
main.cc
int
main (int argc, char **argv)
{
toplev toplev (NULL, /* external_timer */
true /* init_signals */);
int r = toplev.main (argc, argv);
if (flag_checking && !seen_error ())
toplev.finalize ();
return r;
}
最后调用 toplev.cc
int
toplev::main (int argc, char **argv)
{
/* Parsing and gimplification sometimes need quite large stack.
Increase stack size limits if possible. */
stack_limit_increase (64 * 1024 * 1024);
/* Stash a copy of the original argv before expansion
for use by SARIF output. */
unique_argv original_argv (dupargv (argv));
expandargv (&argc, &argv);
/* Initialization of GCC's environment, and diagnostics. */
general_init (argv[0], m_init_signals, std::move (original_argv));
/* One-off initialization of options that does not need to be
repeated when options are added for particular functions. */
init_options_once ();
init_opts_obstack ();
/* Initialize global options structures; this must be repeated for
each structure used for parsing options. */
init_options_struct (&global_options, &global_options_set);
lang_hooks.init_options_struct (&global_options);
/* Init GGC heuristics must be caller after we initialize
options. */
init_ggc_heuristics ();
/* Convert the options to an array. */
decode_cmdline_options_to_array_default_mask (argc,
CONST_CAST2 (const char **,
char **, argv),
&save_decoded_options,
&save_decoded_options_count);
/* Save Optimization decoded options. */
save_opt_decoded_options = new vec<cl_decoded_option> ();
for (unsigned i = 1; i < save_decoded_options_count; ++i)
if (save_decoded_options[i].opt_index < cl_options_count
&& cl_options[save_decoded_options[i].opt_index].flags & CL_OPTIMIZATION)
save_opt_decoded_options->safe_push (save_decoded_options[i]);
/* Perform language-specific options initialization. */
lang_hooks.init_options (save_decoded_options_count, save_decoded_options);
/* Parse the options and do minimal processing; basically just
enough to default flags appropriately. */
decode_options (&global_options, &global_options_set,
save_decoded_options, save_decoded_options_count,
UNKNOWN_LOCATION, global_dc,
targetm.target_option.override);
global_dc->get_file_cache ().tune (param_file_cache_files,
param_file_cache_lines);
handle_common_deferred_options ();
init_local_tick ();
initialize_plugins ();
/* Handle the dump options now that plugins have had a chance to install new
passes. */
handle_deferred_dump_options ();
if (version_flag)
print_version (stderr, "", true);
if (help_flag)
print_plugins_help (stderr, "");
/* Exit early if we can (e.g. -help). */
if (!exit_after_options)
{
/* Just in case lang_hooks.post_options ends up calling a debug_hook.
This can happen with incorrect pre-processed input. */
debug_hooks = &do_nothing_debug_hooks;
/* Allow the front end to perform consistency checks and do further
initialization based on the command line options. This hook also
sets the original filename if appropriate (e.g. foo.i -> foo.c)
so we can correctly initialize debug output. */
no_backend = lang_hooks.post_options (&main_input_filename);
process_options ();
if (m_use_TV_TOTAL)
start_timevars ();
do_compile ();
if (flag_self_test && !seen_error ())
{
if (no_backend)
error_at (UNKNOWN_LOCATION, "self-tests incompatible with %<-E%>");
else
run_self_tests ();
}
}
if (warningcount || errorcount || werrorcount)
print_ignored_options ();
/* Invoke registered plugin callbacks if any. Some plugins could
emit some diagnostics here. */
invoke_plugin_callbacks (PLUGIN_FINISH, NULL);
if (auto edit_context_ptr = global_dc->get_edit_context ())
{
pretty_printer pp;
pp_show_color (&pp) = pp_show_color (global_dc->get_reference_printer ());
edit_context_ptr->print_diff (&pp, true);
pp_flush (&pp);
}
diagnostic_finish (global_dc);
finalize_plugins ();
after_memory_report = true;
if (global_dc->execution_failed_p ())
return (FATAL_EXIT_CODE);
return (SUCCESS_EXIT_CODE);
}