From cc92bc827062ef4f77643a559a5ff7662b9f00e3 Mon Sep 17 00:00:00 2001 From: meissner Date: Thu, 2 Apr 2009 20:45:26 +0000 Subject: [PATCH] [PATCH, committed] Add -save-temps=obj, PR 39293 git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@145470 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 16 +++++++ gcc/doc/invoke.texi | 36 ++++++++++++++- gcc/gcc.c | 125 ++++++++++++++++++++++++++++++++++++++-------------- 3 files changed, 143 insertions(+), 34 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a2544459fae..3c1ed8f11a1 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,19 @@ +2009-04-02 Michael Meissner + + PR driver/39293 + * gcc.c (save_temps_flag): Add support for -save-temps=obj. + (cpp_options): Ditto. + (default_compilers): Ditto. + (display_help): Ditto. + (process_command): Ditto. + (do_spec_1): Ditto. + (set_input): Use lbasename instead of duplicate code. + (save_temps_prefix): New static for -save-temps=obj. + (save_temps_length): Ditto. + + * doc/invoke.texi (-save-temps=obj): Document new variant to + -save-temps switch. + 2009-04-02 Jeff Law * reload1.c (fixup_eh_region_notes): Remove write-only "trap_count" diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 52fd70d1ad9..6680389364d 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -315,7 +315,7 @@ Objective-C and Objective-C++ Dialects}. -print-multi-directory -print-multi-lib @gol -print-prog-name=@var{program} -print-search-dirs -Q @gol -print-sysroot -print-sysroot-headers-suffix @gol --save-temps -time} +-save-temps -save-temps=cwd -save-temps=obj -time} @item Optimization Options @xref{Optimize Options,,Options that Control Optimization}. @@ -5168,6 +5168,7 @@ And for @var{n} over four, @option{-fsched-verbose} also includes dependence info. @item -save-temps +@itemx -save-temps=cwd @opindex save-temps Store the usual ``temporary'' intermediate files permanently; place them in the current directory and name them based on the source file. Thus, @@ -5182,6 +5183,39 @@ input source file with the same extension as an intermediate file. The corresponding intermediate file may be obtained by renaming the source file before using @option{-save-temps}. +If you invoke GCC in parallel, compiling several different source +files that share a common base name in different subdirectories or the +same source file compiled for multiple output destinations, it is +likely that the different parallel compilers will interfere with each +other, and overwrite the temporary files. For instance: + +@smallexample +gcc -save-temps -o outdir1/foo.o indir1/foo.c& +gcc -save-temps -o outdir2/foo.o indir2/foo.c& +@end smallexample + +may result in @file{foo.i} and @file{foo.o} being written to +simultaneously by both compilers. + +@item -save-temps=obj +@opindex save-temps=obj +Store the usual ``temporary'' intermediate files permanently. If the +@option{-o} option is used, the temporary files are based on the +object file. If the @option{-o} option is not used, the +@option{-save-temps=obj} switch behaves like @option{-save-temps}. + +For example: + +@smallexample +gcc -save-temps=obj -c foo.c +gcc -save-temps=obj -c bar.c -o dir/xbar.o +gcc -save-temps=obj foobar.c -o dir2/yfoobar +@end smallexample + +would create @file{foo.i}, @file{foo.s}, @file{dir/xbar.i}, +@file{dir/xbar.s}, @file{dir2/yfoobar.i}, @file{dir2/yfoobar.s}, and +@file{dir2/yfoobar.o}. + @item -time @opindex time Report the CPU time taken by each subprocess in the compilation diff --git a/gcc/gcc.c b/gcc/gcc.c index ee953660e5c..c3e6cf5f3e1 100644 --- a/gcc/gcc.c +++ b/gcc/gcc.c @@ -218,7 +218,15 @@ static const char *target_sysroot_hdrs_suffix = 0; /* 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; +static enum save_temps { + SAVE_TEMPS_NONE, /* no -save-temps */ + SAVE_TEMPS_CWD, /* -save-temps in current directory */ + SAVE_TEMPS_OBJ /* -save-temps in object directory */ +} save_temps_flag; + +/* Output file to use to get the object directory for -save-temps=obj */ +static char *save_temps_prefix = 0; +static size_t save_temps_length = 0; /* Nonzero means pass multiple source files to the compiler at one time. */ @@ -393,7 +401,8 @@ or with constant text in a single 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. + and not including the directory unless -save-temps was specified + to put temporaries in a different location. %B same as %b, but include the file suffix (text after the last period). %gSUFFIX substitute a file name that has suffix SUFFIX and is chosen @@ -817,7 +826,7 @@ static const char *cpp_unique_options = static const char *cpp_options = "%(cpp_unique_options) %1 %{m*} %{std*&ansi&trigraphs} %{W*&pedantic*} %{w}\ %{f*} %{g*:%{!g0:%{g*} %{!fno-working-directory:-fworking-directory}}} %{O*}\ - %{undef} %{save-temps:-fpch-preprocess}"; + %{undef} %{save-temps*:-fpch-preprocess}"; /* This contains cpp options which are not passed when the preprocessor output will be used by another program. */ @@ -996,17 +1005,17 @@ static const struct compiler default_compilers[] = %{traditional|ftraditional:\ %eGNU C no longer supports -traditional without -E}\ %{!combine:\ - %{save-temps|traditional-cpp|no-integrated-cpp:%(trad_capable_cpp) \ - %(cpp_options) -o %{save-temps:%b.i} %{!save-temps:%g.i} \n\ - cc1 -fpreprocessed %{save-temps:%b.i} %{!save-temps:%g.i} \ + %{save-temps*|traditional-cpp|no-integrated-cpp:%(trad_capable_cpp) \ + %(cpp_options) -o %{save-temps*:%b.i} %{!save-temps*:%g.i} \n\ + cc1 -fpreprocessed %{save-temps*:%b.i} %{!save-temps*:%g.i} \ %(cc1_options)}\ - %{!save-temps:%{!traditional-cpp:%{!no-integrated-cpp:\ + %{!save-temps*:%{!traditional-cpp:%{!no-integrated-cpp:\ cc1 %(cpp_unique_options) %(cc1_options)}}}\ %{!fsyntax-only:%(invoke_as)}} \ %{combine:\ - %{save-temps|traditional-cpp|no-integrated-cpp:%(trad_capable_cpp) \ - %(cpp_options) -o %{save-temps:%b.i} %{!save-temps:%g.i}}\ - %{!save-temps:%{!traditional-cpp:%{!no-integrated-cpp:\ + %{save-temps*|traditional-cpp|no-integrated-cpp:%(trad_capable_cpp) \ + %(cpp_options) -o %{save-temps*:%b.i} %{!save-temps*:%g.i}}\ + %{!save-temps*:%{!traditional-cpp:%{!no-integrated-cpp:\ cc1 %(cpp_unique_options) %(cc1_options)}}\ %{!fsyntax-only:%(invoke_as)}}}}}}", 0, 1, 1}, {"-", @@ -1018,13 +1027,13 @@ static const struct compiler default_compilers[] = external preprocessor if -save-temps is given. */ "%{E|M|MM:%(trad_capable_cpp) %(cpp_options) %(cpp_debug_options)}\ %{!E:%{!M:%{!MM:\ - %{save-temps|traditional-cpp|no-integrated-cpp:%(trad_capable_cpp) \ - %(cpp_options) -o %{save-temps:%b.i} %{!save-temps:%g.i} \n\ - cc1 -fpreprocessed %{save-temps:%b.i} %{!save-temps:%g.i} \ + %{save-temps*|traditional-cpp|no-integrated-cpp:%(trad_capable_cpp) \ + %(cpp_options) -o %{save-temps*:%b.i} %{!save-temps*:%g.i} \n\ + cc1 -fpreprocessed %{save-temps*:%b.i} %{!save-temps*:%g.i} \ %(cc1_options)\ -o %g.s %{!o*:--output-pch=%i.gch}\ %W{o*:--output-pch=%*}%V}\ - %{!save-temps:%{!traditional-cpp:%{!no-integrated-cpp:\ + %{!save-temps*:%{!traditional-cpp:%{!no-integrated-cpp:\ cc1 %(cpp_unique_options) %(cc1_options)\ -o %g.s %{!o*:--output-pch=%i.gch}\ %W{o*:--output-pch=%*}%V}}}}}}", 0, 0, 0}, @@ -3255,6 +3264,7 @@ display_help (void) fputs (_(" -Xlinker Pass on to the linker\n"), stdout); fputs (_(" -combine Pass multiple source files to compiler at once\n"), stdout); fputs (_(" -save-temps Do not delete intermediate files\n"), stdout); + fputs (_(" -save-temps= Do not delete intermediate files\n"), stdout); fputs (_(" -pipe Use pipes rather than intermediate files\n"), stdout); fputs (_(" -time Time the execution of each subprocess\n"), stdout); fputs (_(" -specs= Override built-in specs with the contents of \n"), stdout); @@ -3789,8 +3799,19 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n" n_infiles++; else if (strcmp (argv[i], "-save-temps") == 0) { - save_temps_flag = 1; + save_temps_flag = SAVE_TEMPS_CWD; + n_switches++; + } + else if (strncmp (argv[i], "-save-temps=", 12) == 0) + { n_switches++; + if (strcmp (argv[i]+12, "cwd") == 0) + save_temps_flag = SAVE_TEMPS_CWD; + else if (strcmp (argv[i]+12, "obj") == 0 + || strcmp (argv[i]+12, "object") == 0) + save_temps_flag = SAVE_TEMPS_OBJ; + else + fatal ("'%s' is an unknown -save-temps option", argv[i]); } else if (strcmp (argv[i], "-combine") == 0) { @@ -3965,6 +3986,8 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n" else argv[i] = convert_filename (argv[i], ! have_c, 0); #endif + /* Save the output name in case -save-temps=obj was used. */ + save_temps_prefix = xstrdup ((p[1] == 0) ? argv[i + 1] : argv[i] + 1); goto normal_switch; default: @@ -4022,6 +4045,25 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n" } } + /* If -save-temps=obj and -o name, create the prefix to use for %b. + Otherwise just make -save-temps=obj the same as -save-temps=cwd. */ + if (save_temps_flag == SAVE_TEMPS_OBJ && save_temps_prefix != NULL) + { + save_temps_length = strlen (save_temps_prefix); + temp = strrchr (lbasename (save_temps_prefix), '.'); + if (temp) + { + save_temps_length -= strlen (temp); + save_temps_prefix[save_temps_length] = '\0'; + } + + } + else if (save_temps_prefix != NULL) + { + free (save_temps_prefix); + save_temps_prefix = NULL; + } + if (save_temps_flag && use_pipes) { /* -save-temps overrides -pipe, so that temp files are produced */ @@ -4776,12 +4818,18 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part) fatal ("spec '%s' invalid", spec); case 'b': - obstack_grow (&obstack, input_basename, basename_length); + if (save_temps_length) + obstack_grow (&obstack, save_temps_prefix, save_temps_length); + else + obstack_grow (&obstack, input_basename, basename_length); arg_going = 1; break; case 'B': - obstack_grow (&obstack, input_basename, suffixed_basename_length); + if (save_temps_length) + obstack_grow (&obstack, save_temps_prefix, save_temps_length); + else + obstack_grow (&obstack, input_basename, suffixed_basename_length); arg_going = 1; break; @@ -4927,6 +4975,26 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part) suffix_length += strlen (TARGET_OBJECT_SUFFIX); } + /* If -save-temps=obj and -o were specified, use that for the + temp file. */ + if (save_temps_length) + { + char *tmp; + temp_filename_length + = save_temps_length + suffix_length + 1; + tmp = (char *) alloca (temp_filename_length); + memcpy (tmp, save_temps_prefix, save_temps_length); + memcpy (tmp + save_temps_length, suffix, suffix_length); + tmp[save_temps_length + suffix_length] = '\0'; + temp_filename = save_string (tmp, + temp_filename_length + 1); + obstack_grow (&obstack, temp_filename, + temp_filename_length); + arg_going = 1; + delete_this_arg = 0; + break; + } + /* If the input_filename has the same suffix specified for the %g, %u, or %U, and -save-temps is specified, we could end up using that file as an intermediate @@ -4938,13 +5006,13 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part) if (save_temps_flag) { char *tmp; - - temp_filename_length = basename_length + suffix_length; - tmp = (char *) alloca (temp_filename_length + 1); - strncpy (tmp, input_basename, basename_length); - strncpy (tmp + basename_length, suffix, suffix_length); - tmp[temp_filename_length] = '\0'; + temp_filename_length = basename_length + suffix_length + 1; + tmp = (char *) alloca (temp_filename_length); + memcpy (tmp, input_basename, basename_length); + memcpy (tmp + basename_length, suffix, suffix_length); + tmp[basename_length + suffix_length] = '\0'; temp_filename = tmp; + if (strcmp (temp_filename, input_filename) != 0) { #ifndef HOST_LACKS_INODE_NUMBERS @@ -6165,16 +6233,7 @@ set_input (const char *filename) input_filename = filename; input_filename_length = strlen (input_filename); - - input_basename = input_filename; -#ifdef HAVE_DOS_BASED_FILE_SYSTEM - /* Skip drive name so 'x:foo' is handled properly. */ - if (input_basename[1] == ':') - input_basename += 2; -#endif - for (p = input_basename; *p; p++) - if (IS_DIR_SEPARATOR (*p)) - input_basename = p + 1; + input_basename = lbasename (input_filename); /* Find a suffix starting with the last period, and set basename_length to exclude that suffix. */ -- 2.11.4.GIT