/* 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. */
%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
it is subsequently output with %*. SUFFIX is terminated by the next
space or %.
%d marks the argument containing or following the %d as a
- temporary file name, so that that file will be deleted if CC exits
+ temporary file name, so that that file will be deleted if GCC exits
successfully. Unlike %g, this contributes no text to the argument.
%w marks the argument containing or following the %w as the
"output file" of this compilation. This puts the argument
argument vector in the usual fashion. The function returns
a string which is processed as if it had appeared literally
as part of the current spec.
- %{S} substitutes the -S switch, if that switch was given to CC.
+ %{S} substitutes the -S switch, if that switch was given to GCC.
If that switch was not specified, this substitutes nothing.
Here S is a metasyntactic variable.
- %{S*} substitutes all the switches specified to CC whose names start
+ %{S*} substitutes all the switches specified to GCC whose names start
with -S. This is used for -o, -I, etc; switches that take
- arguments. CC considers `-o foo' as being one switch whose
+ arguments. GCC considers `-o foo' as being one switch whose
name starts with `o'. %{o*} would substitute this text,
including the space; thus, two arguments would be generated.
%{S*&T*} likewise, but preserve order of S and T options (the order
of ampersand-separated variables; for each the wild card is
optional. Useful for CPP as %{D*&U*&A*}.
- %{S:X} substitutes X, if the -S switch was given to CC.
- %{!S:X} substitutes X, if the -S switch was NOT given to CC.
+ %{S:X} substitutes X, if the -S switch was given to GCC.
+ %{!S:X} substitutes X, if the -S switch was NOT given to GCC.
%{S*:X} substitutes X if one or more switches whose names start
- with -S was given to CC. Normally X is substituted only
+ with -S was given to GCC. Normally X is substituted only
once, no matter how many such switches appeared. However,
if %* appears somewhere in X, then X will be substituted
once for each matching switch, with the %* replaced by the
%{,S:X} substitutes X, if processing a file which will use spec S.
%{!,S:X} substitutes X, if NOT processing a file which will use spec S.
- %{S|T:X} substitutes X if either -S or -T was given to CC. This may be
+ %{S|T:X} substitutes X if either -S or -T was given to GCC. This may be
combined with '!', '.', ',', and '*' as above binding stronger
than the OR.
If %* appears in X, all of the alternatives must be starred, and
only the first matching alternative is substituted.
- %{S:X; if S was given to CC, substitutes X;
- T:Y; else if T was given to CC, substitutes Y;
+ %{S:X; if S was given to GCC, substitutes X;
+ T:Y; else if T was given to GCC, substitutes Y;
:D} else substitutes D. There can be as many clauses as you need.
This may be combined with '.', '!', ',', '|', and '*' as above.
that a command should be piped to the following command, but only if -pipe
is specified.
-Note that it is built into CC which switches take arguments and which
+Note that it is built into GCC which switches take arguments and which
do not. You might think it would be useful to generalize this to
allow each compiler's spec to say which switches take arguments. But
-this cannot be done in a consistent fashion. CC cannot even decide
+this cannot be done in a consistent fashion. GCC cannot even decide
which input files have been specified without knowing which switches
take arguments, and it must know which input files to compile in order
to tell which compilers to run.
-CC also knows implicitly that arguments starting in `-l' are to be
+GCC also knows implicitly that arguments starting in `-l' are to be
treated as compiler output files, and passed to the linker in their
proper position among the other output files. */
\f
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. */
%{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},
{"-",
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},
fputs (_(" -pass-exit-codes Exit with highest error code from a phase\n"), stdout);
fputs (_(" --help Display this information\n"), stdout);
fputs (_(" --target-help Display target specific command line options\n"), stdout);
- fputs (_(" --help={target|optimizers|warnings|undocumented|params}[,{[^]joined|[^]separate}]\n"), stdout);
+ fputs (_(" --help={target|optimizers|warnings|params|[^]{joined|separate|undocumented}}[,...]\n"), stdout);
fputs (_(" Display specific types of command line options\n"), stdout);
if (! verbose_flag)
fputs (_(" (Use '-v --help' to display command line options of sub-processes)\n"), stdout);
+ fputs (_(" --version Display compiler version information\n"), stdout);
fputs (_(" -dumpspecs Display all of the built in spec strings\n"), stdout);
fputs (_(" -dumpversion Display the version of the compiler\n"), stdout);
fputs (_(" -dumpmachine Display the compiler's target processor\n"), stdout);
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);
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)
{
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:
}
}
+ /* 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 */
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;
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
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
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. */
/* We do not exit here. Instead we have created a fake input file
called 'help-dummy' which needs to be compiled, and we pass this
- on the various sub-processes, along with the --help switch. */
+ on the various sub-processes, along with the --help switch.
+ Ensure their output appears after ours. */
+ fputc ('\n', stdout);
+ fflush (stdout);
}
if (verbose_flag)