aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMichael Meissner <meissner@linux.vnet.ibm.com>2009-04-02 20:45:26 +0000
committerMichael Meissner <meissner@gcc.gnu.org>2009-04-02 20:45:26 +0000
commit14fdc6134e2a667f631cf91941402aaf09ffc24d (patch)
treea1bf78807a1ba33fc1076ae4a3406af0080a11b1 /gcc
parent9fabb197c5515193874df456a3cd1dbcfe741c3c (diff)
downloadgcc-14fdc6134e2a667f631cf91941402aaf09ffc24d.zip
gcc-14fdc6134e2a667f631cf91941402aaf09ffc24d.tar.gz
gcc-14fdc6134e2a667f631cf91941402aaf09ffc24d.tar.bz2
[PATCH, committed] Add -save-temps=obj, PR 39293
From-SVN: r145470
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog16
-rw-r--r--gcc/doc/invoke.texi36
-rw-r--r--gcc/gcc.c125
3 files changed, 143 insertions, 34 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index a254445..3c1ed8f 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,19 @@
+2009-04-02 Michael Meissner <meissner@linux.vnet.ibm.com>
+
+ 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 <law@redhat.com>
* reload1.c (fixup_eh_region_notes): Remove write-only "trap_count"
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 52fd70d..6680389 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 ee95366..c3e6cf5 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 <arg> Pass <arg> 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=<arg> 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=<file> Override built-in specs with the contents of <file>\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. */