Hi! I couldn't find a way to add an option in specs, so that it would affect other specs, like e.g. to make -pie the default if -shared/-static/-pie/-r isn't passed in specs would require duplicating *startfile/*endfile: %rename link link_pie_old *link: %{shared|static|pie|r:;:-pie} %(link_pie_old) *endfile: %{ffast-math|funsafe-math-optimizations:crtfastmath.o%s} %{mpc32:crtprec32.o%s} %{mpc64:crtprec64.o%s} %{mpc80:crtprec80.o%s} %{shared|pie:crtendS.o%s;static|r:crtend.o%s;:crtendS.o%s} crtn.o%s *startfile: %{!shared: %{pg|p|profile:gcrt1.o%s; :Scrt1.o%s}} crti.o%s %{static:crtbeginT.o%s;shared|pie:crtbeginS.o%s;r:crtbegin.o%s;:crtbeginS.o%s} with all the drawbacks it has - if builtin specs change, it would need % adjusting, similarly *startfile/*endfile differ for different targets.
With the following patch it is possible to add self_spec like in: %rename self_spec self_spec_pie_old *self_spec: %{shared|static|pie|r:;:-pie} %{fpic|fPIC|fpie|fPIE:;:-fpie} *%(self_spec_pie_old) which introduces the options into further option processing, so -pie gets matched e.g. in *startfile/*endfile. I had to move the -fcompare-debug handling slightly later, because it is remembering the current count of options and repeating them afterwards. Tested on x86_64-linux, ok for trunk? 2011-08-03 Jakub Jelinek <ja...@redhat.com> * gcc.c (self_spec): New variable. (static_specs): Add self_spec. (main): Call do_self_spec on "self_spec" specs after reading user specs files. Move compare_debug handling right after that. --- gcc/gcc.c.jj 2011-07-22 22:15:02.000000000 +0200 +++ gcc/gcc.c 2011-08-03 12:14:41.000000000 +0200 @@ -728,6 +728,7 @@ static const char *startfile_prefix_spec static const char *sysroot_spec = SYSROOT_SPEC; static const char *sysroot_suffix_spec = SYSROOT_SUFFIX_SPEC; static const char *sysroot_hdrs_suffix_spec = SYSROOT_HEADERS_SUFFIX_SPEC; +static const char *self_spec = ""; /* Standard options to cpp, cc1, and as, to reduce duplication in specs. There should be no need to override these in target dependent files, @@ -1215,6 +1216,7 @@ static struct spec_list static_specs[] = INIT_STATIC_SPEC ("sysroot_spec", &sysroot_spec), INIT_STATIC_SPEC ("sysroot_suffix_spec", &sysroot_suffix_spec), INIT_STATIC_SPEC ("sysroot_hdrs_suffix_spec", &sysroot_hdrs_suffix_spec), + INIT_STATIC_SPEC ("self_spec", &self_spec), }; #ifdef EXTRA_SPECS /* additional specs needed */ @@ -6261,48 +6263,6 @@ main (int argc, char **argv) for (i = 0; i < ARRAY_SIZE (driver_self_specs); i++) do_self_spec (driver_self_specs[i]); - if (compare_debug) - { - enum save_temps save; - - if (!compare_debug_second) - { - n_switches_debug_check[1] = n_switches; - n_switches_alloc_debug_check[1] = n_switches_alloc; - switches_debug_check[1] = XDUPVEC (struct switchstr, switches, - n_switches_alloc); - - do_self_spec ("%:compare-debug-self-opt()"); - n_switches_debug_check[0] = n_switches; - n_switches_alloc_debug_check[0] = n_switches_alloc; - switches_debug_check[0] = switches; - - n_switches = n_switches_debug_check[1]; - n_switches_alloc = n_switches_alloc_debug_check[1]; - switches = switches_debug_check[1]; - } - - /* Avoid crash when computing %j in this early. */ - save = save_temps_flag; - save_temps_flag = SAVE_TEMPS_NONE; - - compare_debug = -compare_debug; - do_self_spec ("%:compare-debug-self-opt()"); - - save_temps_flag = save; - - if (!compare_debug_second) - { - n_switches_debug_check[1] = n_switches; - n_switches_alloc_debug_check[1] = n_switches_alloc; - switches_debug_check[1] = switches; - compare_debug = -compare_debug; - n_switches = n_switches_debug_check[0]; - n_switches_alloc = n_switches_debug_check[0]; - switches = switches_debug_check[0]; - } - } - /* If not cross-compiling, look for executables in the standard places. */ if (*cross_compile == '0') @@ -6412,6 +6372,58 @@ main (int argc, char **argv) read_specs (filename ? filename : uptr->filename, FALSE); } + /* Process any user self specs. */ + { + struct spec_list *sl; + for (sl = specs; sl; sl = sl->next) + if (sl->name_len == sizeof "self_spec" - 1 + && !strcmp (sl->name, "self_spec")) + do_self_spec (*sl->ptr_spec); + } + + if (compare_debug) + { + enum save_temps save; + + if (!compare_debug_second) + { + n_switches_debug_check[1] = n_switches; + n_switches_alloc_debug_check[1] = n_switches_alloc; + switches_debug_check[1] = XDUPVEC (struct switchstr, switches, + n_switches_alloc); + + do_self_spec ("%:compare-debug-self-opt()"); + n_switches_debug_check[0] = n_switches; + n_switches_alloc_debug_check[0] = n_switches_alloc; + switches_debug_check[0] = switches; + + n_switches = n_switches_debug_check[1]; + n_switches_alloc = n_switches_alloc_debug_check[1]; + switches = switches_debug_check[1]; + } + + /* Avoid crash when computing %j in this early. */ + save = save_temps_flag; + save_temps_flag = SAVE_TEMPS_NONE; + + compare_debug = -compare_debug; + do_self_spec ("%:compare-debug-self-opt()"); + + save_temps_flag = save; + + if (!compare_debug_second) + { + n_switches_debug_check[1] = n_switches; + n_switches_alloc_debug_check[1] = n_switches_alloc; + switches_debug_check[1] = switches; + compare_debug = -compare_debug; + n_switches = n_switches_debug_check[0]; + n_switches_alloc = n_switches_debug_check[0]; + switches = switches_debug_check[0]; + } + } + + /* If we have a GCC_EXEC_PREFIX envvar, modify it for cpp's sake. */ if (gcc_exec_prefix) gcc_exec_prefix = concat (gcc_exec_prefix, spec_machine, dir_separator_str, Jakub