/* Compiler driver program that can handle many languages.
Copyright (C) 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GCC.
#include "config.h"
#include "system.h"
#include "coretypes.h"
+#include "multilib.h" /* before tm.h */
#include "tm.h"
#include <signal.h>
#if ! defined( SIGCHLD ) && defined( SIGCLD )
static int save_temps_flag;
+/* Nonzero means pass multiple source files to the compiler at one time. */
+
+static int combine_flag = 0;
+
/* Nonzero means use pipes to communicate between subprocesses.
Overridden by either of the above two flags. */
/* Forward declaration for prototypes. */
struct path_prefix;
+struct prefix_list;
static void init_spec (void);
static void store_arg (const char *, int, int);
static const char *handle_spec_function (const char *);
static char *save_string (const char *, int);
static void set_collect_gcc_options (void);
+static void do_spec_path (struct prefix_list *, const char *, int, int, int, const char *, const char *);
static int do_spec_1 (const char *, int, const char *);
static int do_spec_2 (const char *);
static void do_option_spec (const char *, const char *);
static void add_preprocessor_option (const char *, int);
static void add_assembler_option (const char *, int);
static void add_linker_option (const char *, int);
-static void process_command (int, const char *const *);
+static void process_command (int, const char **);
static int execute (void);
static void alloc_args (void);
static void clear_args (void);
static void fatal_error (int);
-#ifdef ENABLE_SHARED_LIBGCC
+#if defined(ENABLE_SHARED_LIBGCC) && !defined(REAL_LIBGCC_SPEC)
static void init_gcc_specs (struct obstack *, const char *, const char *,
const char *);
#endif
#define LIB_SPEC "%{!shared:%{g*:-lg} %{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p}}"
#endif
+/* mudflap specs */
+#ifndef MFWRAP_SPEC
+/* XXX: valid only for GNU ld */
+/* XXX: should exactly match hooks provided by libmudflap.a */
+#define MFWRAP_SPEC " %{static: %{fmudflap|fmudflapth: \
+ --wrap=malloc --wrap=free --wrap=calloc --wrap=realloc\
+ --wrap=mmap --wrap=munmap --wrap=alloca\
+} %{fmudflapth: --wrap=pthread_create --wrap=pthread_join --wrap=pthread_exit\
+}} %{fmudflap|fmudflapth: --wrap=main}"
+#endif
+#ifndef MFLIB_SPEC
+#define MFLIB_SPEC "%{fmudflap|fmudflapth: -export-dynamic}"
+#endif
+
/* config.h can define LIBGCC_SPEC to override how and when libgcc.a is
included. */
#ifndef LIBGCC_SPEC
-#if defined(LINK_LIBGCC_SPECIAL) || defined(LINK_LIBGCC_SPECIAL_1)
+#if defined(REAL_LIBGCC_SPEC)
+#define LIBGCC_SPEC REAL_LIBGCC_SPEC
+#elif defined(LINK_LIBGCC_SPECIAL) || defined(LINK_LIBGCC_SPECIAL_1)
/* Have gcc do the search for libgcc.a. */
#define LIBGCC_SPEC "libgcc.a%s"
#else
%{!fsyntax-only:%{!c:%{!M:%{!MM:%{!E:%{!S:\
%(linker) %l " LINK_PIE_SPEC "%X %{o*} %{A} %{d} %{e*} %{m} %{N} %{n} %{r}\
%{s} %{t} %{u*} %{x} %{z} %{Z} %{!A:%{!nostdlib:%{!nostartfiles:%S}}}\
- %{static:} %{L*} %(link_libgcc) %o %{fprofile-arcs:-lgcov}\
+ %{static:} %{L*} %(mfwrap) %(link_libgcc) %o %(mflib)\
+ %{fprofile-arcs|fprofile-generate:-lgcov}\
%{!nostdlib:%{!nodefaultlibs:%(link_gcc_c_sequence)}}\
%{!A:%{!nostdlib:%{!nostartfiles:%E}}} %{T*} }}}}}}"
#endif
static const char *asm_final_spec = ASM_FINAL_SPEC;
static const char *link_spec = LINK_SPEC;
static const char *lib_spec = LIB_SPEC;
+static const char *mfwrap_spec = MFWRAP_SPEC;
+static const char *mflib_spec = MFLIB_SPEC;
static const char *libgcc_spec = LIBGCC_SPEC;
static const char *endfile_spec = ENDFILE_SPEC;
static const char *startfile_spec = STARTFILE_SPEC;
file that happens to exist is up-to-date. */
static const char *cpp_unique_options =
"%{C|CC:%{!E:%eGCC does not support -C or -CC without -E}}\
- %{!Q:-quiet} %{nostdinc*} %{C} %{CC} %{v} %{I*} %{P} %I\
+ %{!Q:-quiet} %{nostdinc*} %{C} %{CC} %{v} %{I*&F*} %{P} %I\
%{MD:-MD %{!o:%b.d}%{o*:%.d%*}}\
%{MMD:-MMD %{!o:%b.d}%{o*:%.d%*}}\
%{M} %{MM} %{MF*} %{MG} %{MP} %{MQ*} %{MT*}\
%{!E:%{!M:%{!MM:%{MD|MMD:%{o*:-MQ %*}}}}}\
%{trigraphs} %{remap} %{g3:-dD} %{H} %C %{D*&U*&A*} %{i*} %Z %i\
+ %{fmudflap:-D_MUDFLAP -include mf-runtime.h}\
+ %{fmudflapth:-D_MUDFLAP -D_MUDFLAPTH -include mf-runtime.h}\
%{E|M|MM:%W{o*}}";
/* This contains cpp options which are common with cc1_options and are passed
static const char *cc1_options =
"%{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\
%1 %{!Q:-quiet} -dumpbase %B %{d*} %{m*} %{a*}\
- -auxbase%{c|S:%{o*:-strip %*}%{!o*: %b}}%{!c:%{!S: %b}}\
+ %{c|S:%{o*:-auxbase-strip %*}%{!o*:-auxbase %b}}%{!c:%{!S:-auxbase %b}}\
%{g*} %{O*} %{W*&pedantic*} %{w} %{std*} %{ansi}\
%{v:-version} %{pg:-p} %{p} %{f*} %{undef}\
%{Qn:-fno-ident} %{--help:--help}\
%{--target-help:--target-help}\
%{!fsyntax-only:%{S:%W{o*}%{!o*:-o %b.s}}}\
- %{fsyntax-only:-o %j} %{-param*}";
+ %{fsyntax-only:-o %j} %{-param*}\
+ %{fmudflap|fmudflapth:-fno-builtin -fno-merge-constants}";
static const char *asm_options =
"%a %Y %{c:%W{o*}%{!o*:-o %w%b%O}}%{!c:-o %d%w%u%O}";
static const char *multilib_matches;
static const char *multilib_defaults;
static const char *multilib_exclusions;
-#include "multilib.h"
/* Check whether a particular argument is a default argument. */
const char *cpp_spec; /* If non-NULL, substitute this spec
for `%C', rather than the usual
cpp_spec. */
+ const int combinable; /* If nonzero, compiler can deal with
+ multiple source files at once (IMA). */
+ const int needs_preprocessing; /* If nonzero, source files need to
+ be run through a preprocessor. */
};
/* Pointer to a vector of `struct compiler' that gives the spec for
were not present when we built the driver, we will hit these copies
and be given a more meaningful error than "file not used since
linking is not done". */
- {".m", "#Objective-C", 0}, {".mi", "#Objective-C", 0},
- {".cc", "#C++", 0}, {".cxx", "#C++", 0}, {".cpp", "#C++", 0},
- {".cp", "#C++", 0}, {".c++", "#C++", 0}, {".C", "#C++", 0},
- {".CPP", "#C++", 0}, {".ii", "#C++", 0},
- {".ads", "#Ada", 0}, {".adb", "#Ada", 0},
- {".f", "#Fortran", 0}, {".for", "#Fortran", 0}, {".fpp", "#Fortran", 0},
- {".F", "#Fortran", 0}, {".FOR", "#Fortran", 0}, {".FPP", "#Fortran", 0},
- {".r", "#Ratfor", 0},
- {".p", "#Pascal", 0}, {".pas", "#Pascal", 0},
- {".java", "#Java", 0}, {".class", "#Java", 0},
- {".zip", "#Java", 0}, {".jar", "#Java", 0},
+ {".m", "#Objective-C", 0, 0, 0}, {".mi", "#Objective-C", 0, 0, 0},
+ {".cc", "#C++", 0, 0, 0}, {".cxx", "#C++", 0, 0, 0},
+ {".cpp", "#C++", 0, 0, 0}, {".cp", "#C++", 0, 0, 0},
+ {".c++", "#C++", 0, 0, 0}, {".C", "#C++", 0, 0, 0},
+ {".CPP", "#C++", 0, 0, 0}, {".ii", "#C++", 0, 0, 0},
+ {".ads", "#Ada", 0, 0, 0}, {".adb", "#Ada", 0, 0, 0},
+ {".f", "#Fortran", 0, 0, 0}, {".for", "#Fortran", 0, 0, 0},
+ {".F", "#Fortran", 0, 0, 0}, {".FOR", "#Fortran", 0, 0, 0},
+ {".FPP", "#Fortran", 0, 0, 0},
+ {".f90", "#Fortran 95", 0, 0, 0}, {".f95", "#Fortran 95", 0, 0, 0},
+ {".fpp", "#Fortran", 0, 0, 0}, {".F", "#Fortran", 0, 0, 0},
+ {".FOR", "#Fortran", 0, 0, 0}, {".FPP", "#Fortran", 0, 0, 0},
+ {".r", "#Ratfor", 0, 0, 0},
+ {".p", "#Pascal", 0, 0, 0}, {".pas", "#Pascal", 0, 0, 0},
+ {".java", "#Java", 0, 0, 0}, {".class", "#Java", 0, 0, 0},
+ {".zip", "#Java", 0, 0, 0}, {".jar", "#Java", 0, 0, 0},
/* Next come the entries for C. */
- {".c", "@c", 0},
+ {".c", "@c", 0, 1, 1},
{"@c",
/* cc1 has an integrated ISO C preprocessor. We should invoke the
external preprocessor if -save-temps is given. */
%{!E:%{!M:%{!MM:\
%{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} \
%(cc1_options)}\
%{!save-temps:%{!traditional-cpp:%{!no-integrated-cpp:\
cc1 %(cpp_unique_options) %(cc1_options)}}}\
- %{!fsyntax-only:%(invoke_as)}}}}", 0},
+ %{!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:\
+ cc1 %(cpp_unique_options) %(cc1_options)}}\
+ %{!fsyntax-only:%(invoke_as)}}}}}}", 0, 1, 1},
{"-",
"%{!E:%e-E required when input is from standard input}\
- %(trad_capable_cpp) %(cpp_options) %(cpp_debug_options)", 0},
- {".h", "@c-header", 0},
+ %(trad_capable_cpp) %(cpp_options) %(cpp_debug_options)", 0, 0, 0},
+ {".h", "@c-header", 0, 0, 0},
{"@c-header",
/* cc1 has an integrated ISO C preprocessor. We should invoke the
external preprocessor if -save-temps is given. */
%{!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},
- {".i", "@cpp-output", 0},
+ %W{o*:--output-pch=%*}%V}}}}}}", 0, 0, 0},
+ {".i", "@cpp-output", 0, 1, 0},
{"@cpp-output",
- "%{!M:%{!MM:%{!E:cc1 -fpreprocessed %i %(cc1_options) %{!fsyntax-only:%(invoke_as)}}}}", 0},
- {".s", "@assembler", 0},
+ "%{!M:%{!MM:%{!E:cc1 -fpreprocessed %i %(cc1_options) %{!fsyntax-only:%(invoke_as)}}}}", 0, 1, 0},
+ {".s", "@assembler", 0, 1, 0},
{"@assembler",
- "%{!M:%{!MM:%{!E:%{!S:as %(asm_debug) %(asm_options) %i %A }}}}", 0},
- {".S", "@assembler-with-cpp", 0},
+ "%{!M:%{!MM:%{!E:%{!S:as %(asm_debug) %(asm_options) %i %A }}}}", 0, 1, 0},
+ {".S", "@assembler-with-cpp", 0, 1, 0},
{"@assembler-with-cpp",
#ifdef AS_NEEDS_DASH_FOR_PIPED_INPUT
"%(trad_capable_cpp) -lang-asm %(cpp_options)\
%{!M:%{!MM:%{!E:%{!S:-o %|.s |\n\
as %(asm_debug) %(asm_options) %m.s %A }}}}"
#endif
- , 0},
+ , 0, 1, 0},
#include "specs.h"
/* Mark end of table. */
- {0, 0, 0}
+ {0, 0, 0, 0, 0}
};
/* Number of elements in default_compilers, not counting the terminator. */
{"--classpath", "-fclasspath=", "aj"},
{"--bootclasspath", "-fbootclasspath=", "aj"},
{"--CLASSPATH", "-fclasspath=", "aj"},
+ {"--combine", "-combine", 0},
{"--comments", "-C", 0},
{"--comments-in-macros", "-CC", 0},
{"--compile", "-c", 0},
INIT_STATIC_SPEC ("endfile", &endfile_spec),
INIT_STATIC_SPEC ("link", &link_spec),
INIT_STATIC_SPEC ("lib", &lib_spec),
+ INIT_STATIC_SPEC ("mfwrap", &mfwrap_spec),
+ INIT_STATIC_SPEC ("mflib", &mflib_spec),
INIT_STATIC_SPEC ("libgcc", &libgcc_spec),
INIT_STATIC_SPEC ("startfile", &startfile_spec),
INIT_STATIC_SPEC ("switches_need_spaces", &switches_need_spaces),
/* Add appropriate libgcc specs to OBSTACK, taking into account
various permutations of -shared-libgcc, -shared, and such. */
-#ifdef ENABLE_SHARED_LIBGCC
+#if defined(ENABLE_SHARED_LIBGCC) && !defined(REAL_LIBGCC_SPEC)
+
+#ifndef USE_LD_AS_NEEDED
+#define USE_LD_AS_NEEDED 0
+#endif
+
static void
init_gcc_specs (struct obstack *obstack, const char *shared_name,
const char *static_name, const char *eh_name)
buf = concat ("%{static|static-libgcc:", static_name, " ", eh_name,
"}%{!static:%{!static-libgcc:",
+#if USE_LD_AS_NEEDED
+ "%{!shared-libgcc:", static_name,
+ " --as-needed ", shared_name, " --no-as-needed}"
+ "%{shared-libgcc:", shared_name, "%{!shared: ", static_name,
+ "}",
+#else
"%{!shared:%{!shared-libgcc:", static_name, " ",
eh_name, "}%{shared-libgcc:", shared_name, " ",
static_name, "}}%{shared:",
#else
shared_name,
#endif
+#endif
"}}}", NULL);
obstack_grow (obstack, buf, strlen (buf));
next = sl;
}
-#ifdef ENABLE_SHARED_LIBGCC
+#if defined(ENABLE_SHARED_LIBGCC) && !defined(REAL_LIBGCC_SPEC)
/* ??? If neither -shared-libgcc nor --static-libgcc was
seen, then we should be making an educated guess. Some proposed
heuristics for ELF include:
static int argbuf_index;
+/* Position in the argbuf array containing the name of the output file
+ (the value associated with the "-o" flag). */
+
+static int have_o_argbuf_index = 0;
+
/* This is the list of suffixes and codes (%g/%u/%U/%j) and the associated
temp file. If the HOST_BIT_BUCKET is used for %j, no entry is made for
it here. */
argbuf[argbuf_index++] = arg;
argbuf[argbuf_index] = 0;
+ if (strcmp (arg, "-o") == 0)
+ have_o_argbuf_index = argbuf_index;
if (delete_always || delete_failure)
record_temp_file (arg, delete_always, delete_failure);
}
/* Delete all the temporary files whose names we previously recorded. */
+#ifndef DELETE_IF_ORDINARY
+#define DELETE_IF_ORDINARY(NAME,ST,VERBOSE_FLAG) \
+do \
+ { \
+ if (stat (NAME, &ST) >= 0 && S_ISREG (ST.st_mode)) \
+ if (unlink (NAME) < 0) \
+ if (VERBOSE_FLAG) \
+ perror_with_name (NAME); \
+ } while (0)
+#endif
+
static void
delete_if_ordinary (const char *name)
{
if (i == 'y' || i == 'Y')
#endif /* DEBUG */
- if (stat (name, &st) >= 0 && S_ISREG (st.st_mode))
- if (unlink (name) < 0)
- if (verbose_flag)
- perror_with_name (name);
+ DELETE_IF_ORDINARY (name, st, verbose_flag);
}
static void
{
const char *name;
const char *language;
+ struct compiler *incompiler;
+ bool compiled;
+ bool preprocessed;
};
/* Also a vector of input files specified. */
fputs (_(" -Xassembler <arg> Pass <arg> on to the assembler\n"), stdout);
fputs (_(" -Xpreprocessor <arg> Pass <arg> on to the preprocessor\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 (_(" -pipe Use pipes rather than intermediate files\n"), stdout);
fputs (_(" -time Time the execution of each subprocess\n"), stdout);
Store its length in `n_switches'. */
static void
-process_command (int argc, const char *const *argv)
+process_command (int argc, const char **argv)
{
int i;
const char *temp;
const char *spec_lang = 0;
int last_language_n_infiles;
int have_c = 0;
- int have_o = 0;
int lang_n_infiles = 0;
#ifdef MODIFY_TARGET_NAME
int is_modify_target_name;
nstore[endp - startp] = 0;
add_prefix (&exec_prefixes, nstore, 0,
PREFIX_PRIORITY_LAST, 0, NULL, 0);
- add_prefix (&include_prefixes,
- concat (nstore, "include", NULL),
- 0, PREFIX_PRIORITY_LAST, 0, NULL, 0);
+ add_prefix (&include_prefixes, nstore, 0,
+ PREFIX_PRIORITY_LAST, 0, NULL, 0);
if (*endp == 0)
break;
endp = startp = endp + 1;
}
/* Convert new-style -- options to old-style. */
- translate_options (&argc, &argv);
+ translate_options (&argc, (const char *const **) &argv);
/* Do language-specific adjustment/addition of flags. */
- lang_specific_driver (&argc, &argv, &added_libraries);
+ lang_specific_driver (&argc, (const char *const **) &argv, &added_libraries);
/* Scan argv twice. Here, the first time, just count how many switches
there will be in their vector, and how many input files in theirs.
{
/* translate_options () has turned --version into -fversion. */
printf (_("%s (GCC) %s\n"), programname, version_string);
- fputs (_("Copyright (C) 2003 Free Software Foundation, Inc.\n"),
- stdout);
+ printf ("Copyright %s 2004 Free Software Foundation, Inc.\n",
+ _("(C)"));
fputs (_("This is free software; see the source for copying conditions. There is NO\n\
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"),
stdout);
save_temps_flag = 1;
n_switches++;
}
+ else if (strcmp (argv[i], "-combine") == 0)
+ {
+ combine_flag = 1;
+ n_switches++;
+ }
else if (strcmp (argv[i], "-specs") == 0)
{
struct user_specs *user = xmalloc (sizeof (struct user_specs));
&& (IS_DIR_SEPARATOR (value[len - 1])))
{
if (len == 7)
- add_prefix (&include_prefixes, "include", NULL,
+ add_prefix (&include_prefixes, "./", NULL,
PREFIX_PRIORITY_B_OPT, 0, NULL, 0);
else
{
- char * string = xmalloc (len + 1);
-
- strncpy (string, value, len - 7);
- strcpy (string + len - 7, "include");
- add_prefix (&include_prefixes, string, NULL,
+ char *string = xmalloc (len - 6);
+ memcpy (string, value, len - 7);
+ string[len - 7] = 0;
+ add_prefix (&include_prefixes, string, NULL,
PREFIX_PRIORITY_B_OPT, 0, NULL, 0);
}
}
PREFIX_PRIORITY_B_OPT, 0, &warn_B, 0);
add_prefix (&startfile_prefixes, value, NULL,
PREFIX_PRIORITY_B_OPT, 0, &warn_B, 0);
- add_prefix (&include_prefixes, concat (value, "include", NULL),
- NULL, PREFIX_PRIORITY_B_OPT, 0, NULL, 0);
+ add_prefix (&include_prefixes, value, NULL,
+ PREFIX_PRIORITY_B_OPT, 0, NULL, 0);
n_switches++;
}
break;
goto normal_switch;
case 'o':
- have_o = 1;
#if defined(HAVE_TARGET_EXECUTABLE_SUFFIX)
if (! have_c)
{
}
}
- combine_inputs = (have_c && have_o && lang_n_infiles > 1);
-
if ((save_temps_flag || report_times) && use_pipes)
{
/* -save-temps overrides -pipe, so that temp files are produced */
}
}
+void
+do_spec_path (struct prefix_list *pl, const char *option,
+ int omit_if_relative, int separate_options,
+ int only_subdir,
+ const char *dir_for_machine_suffix,
+ const char *dir_for_no_suffix)
+{
+ static size_t bufsize = 0;
+ static char *buffer;
+ int idx;
+
+ /* Used on systems which record the specified -L dirs
+ and use them to search for dynamic linking. */
+ /* Relative directories always come from -B,
+ and it is better not to use them for searching
+ at run time. In particular, stage1 loses. */
+ if (omit_if_relative
+ && !IS_ABSOLUTE_PATH (pl->prefix))
+ return;
+
+ /* Try subdirectory if there is one. */
+ if (machine_suffix && dir_for_machine_suffix)
+ {
+ if (strlen (pl->prefix) + strlen (machine_suffix)
+ >= bufsize)
+ bufsize = (strlen (pl->prefix)
+ + strlen (machine_suffix)) * 2 + 1;
+ buffer = xrealloc (buffer, bufsize);
+ strcpy (buffer, pl->prefix);
+ strcat (buffer, machine_suffix);
+ if (is_directory (buffer, dir_for_machine_suffix, 1))
+ {
+ do_spec_1 (option, separate_options, NULL);
+ if (separate_options)
+ do_spec_1 (" ", 0, NULL);
+ do_spec_1 (buffer, 1, NULL);
+ do_spec_1 (dir_for_machine_suffix, 1, NULL);
+ /* Make this a separate argument. */
+ do_spec_1 (" ", 0, NULL);
+ }
+ }
+ if (!pl->require_machine_suffix && dir_for_no_suffix)
+ {
+ if (is_directory (pl->prefix, dir_for_no_suffix, 1))
+ {
+ do_spec_1 (option, separate_options, NULL);
+ if (separate_options)
+ do_spec_1 (" ", 0, NULL);
+ do_spec_1 (pl->prefix, 1, NULL);
+ do_spec_1 (dir_for_no_suffix, 1, NULL);
+ /* Make this a separate argument. */
+ do_spec_1 (" ", 0, NULL);
+ }
+ }
+
+ if (only_subdir)
+ return;
+
+ if (machine_suffix)
+ {
+ if (is_directory (pl->prefix, machine_suffix, 1))
+ {
+ do_spec_1 (option, separate_options, NULL);
+ if (separate_options)
+ do_spec_1 (" ", 0, NULL);
+ do_spec_1 (pl->prefix, 1, NULL);
+ /* Remove slash from machine_suffix. */
+ if (strlen (machine_suffix) >= bufsize)
+ bufsize = strlen (machine_suffix) * 2 + 1;
+ buffer = xrealloc (buffer, bufsize);
+ strcpy (buffer, machine_suffix);
+ idx = strlen (buffer);
+ if (IS_DIR_SEPARATOR (buffer[idx - 1]))
+ buffer[idx - 1] = 0;
+ do_spec_1 (buffer, 1, NULL);
+ /* Make this a separate argument. */
+ do_spec_1 (" ", 0, NULL);
+ }
+ }
+ if (!pl->require_machine_suffix)
+ {
+ if (is_directory (pl->prefix, "", 1))
+ {
+ do_spec_1 (option, separate_options, NULL);
+ if (separate_options)
+ do_spec_1 (" ", 0, NULL);
+ /* Remove slash from pl->prefix. */
+ if (strlen (pl->prefix) >= bufsize)
+ bufsize = strlen (pl->prefix) * 2 + 1;
+ buffer = xrealloc (buffer, bufsize);
+ strcpy (buffer, pl->prefix);
+ idx = strlen (buffer);
+ if (IS_DIR_SEPARATOR (buffer[idx - 1]))
+ buffer[idx - 1] = 0;
+ do_spec_1 (buffer, 1, NULL);
+ /* Make this a separate argument. */
+ do_spec_1 (" ", 0, NULL);
+ }
+ }
+}
+
/* Process the sub-spec SPEC as a portion of a larger spec.
This is like processing a whole spec except that we do
not initialize at the beginning and we do not supply a
case 'D':
{
struct prefix_list *pl = startfile_prefixes.plist;
- size_t bufsize = 100;
- char *buffer = xmalloc (bufsize);
- int idx;
for (; pl; pl = pl->next)
{
-#ifdef RELATIVE_PREFIX_NOT_LINKDIR
- /* Used on systems which record the specified -L dirs
- and use them to search for dynamic linking. */
- /* Relative directories always come from -B,
- and it is better not to use them for searching
- at run time. In particular, stage1 loses. */
- if (!IS_ABSOLUTE_PATH (pl->prefix))
- continue;
-#endif
- /* Try subdirectory if there is one. */
- if (multilib_dir != NULL
- || (pl->os_multilib && multilib_os_dir != NULL))
- {
- const char *multi_dir;
+ const char *no_suffix_multilib_dir;
- multi_dir = pl->os_multilib ? multilib_os_dir
- : multilib_dir;
- if (machine_suffix && multilib_dir)
- {
- if (strlen (pl->prefix) + strlen (machine_suffix)
- >= bufsize)
- bufsize = (strlen (pl->prefix)
- + strlen (machine_suffix)) * 2 + 1;
- buffer = xrealloc (buffer, bufsize);
- strcpy (buffer, pl->prefix);
- strcat (buffer, machine_suffix);
- if (is_directory (buffer, multilib_dir, 1))
- {
- do_spec_1 ("-L", 0, NULL);
-#ifdef SPACE_AFTER_L_OPTION
- do_spec_1 (" ", 0, NULL);
-#endif
- do_spec_1 (buffer, 1, NULL);
- do_spec_1 (multilib_dir, 1, NULL);
- /* Make this a separate argument. */
- do_spec_1 (" ", 0, NULL);
- }
- }
- if (!pl->require_machine_suffix)
- {
- if (is_directory (pl->prefix, multi_dir, 1))
- {
- do_spec_1 ("-L", 0, NULL);
-#ifdef SPACE_AFTER_L_OPTION
- do_spec_1 (" ", 0, NULL);
-#endif
- do_spec_1 (pl->prefix, 1, NULL);
- do_spec_1 (multi_dir, 1, NULL);
- /* Make this a separate argument. */
- do_spec_1 (" ", 0, NULL);
- }
- }
- }
- if (machine_suffix)
- {
- if (is_directory (pl->prefix, machine_suffix, 1))
- {
- do_spec_1 ("-L", 0, NULL);
-#ifdef SPACE_AFTER_L_OPTION
- do_spec_1 (" ", 0, NULL);
-#endif
- do_spec_1 (pl->prefix, 1, NULL);
- /* Remove slash from machine_suffix. */
- if (strlen (machine_suffix) >= bufsize)
- bufsize = strlen (machine_suffix) * 2 + 1;
- buffer = xrealloc (buffer, bufsize);
- strcpy (buffer, machine_suffix);
- idx = strlen (buffer);
- if (IS_DIR_SEPARATOR (buffer[idx - 1]))
- buffer[idx - 1] = 0;
- do_spec_1 (buffer, 1, NULL);
- /* Make this a separate argument. */
- do_spec_1 (" ", 0, NULL);
- }
- }
- if (!pl->require_machine_suffix)
- {
- if (is_directory (pl->prefix, "", 1))
- {
- do_spec_1 ("-L", 0, NULL);
-#ifdef SPACE_AFTER_L_OPTION
- do_spec_1 (" ", 0, NULL);
+ no_suffix_multilib_dir = pl->os_multilib ? multilib_os_dir
+ : multilib_dir;
+ /* Do not separate options, include non-multilibbed variant. */
+ do_spec_path (pl, "-L",
+#ifdef RELATIVE_PREFIX_NOT_LINKDIR
+ 1,
+#else
+ 0,
#endif
- /* Remove slash from pl->prefix. */
- if (strlen (pl->prefix) >= bufsize)
- bufsize = strlen (pl->prefix) * 2 + 1;
- buffer = xrealloc (buffer, bufsize);
- strcpy (buffer, pl->prefix);
- idx = strlen (buffer);
- if (IS_DIR_SEPARATOR (buffer[idx - 1]))
- buffer[idx - 1] = 0;
- do_spec_1 (buffer, 1, NULL);
- /* Make this a separate argument. */
- do_spec_1 (" ", 0, NULL);
- }
- }
+ 0, 0, multilib_dir, no_suffix_multilib_dir);
}
- free (buffer);
}
break;
if (combine_inputs)
{
for (i = 0; (int) i < n_infiles; i++)
- store_arg (infiles[i].name, 0, 0);
+ if ((!infiles[i].language) || (infiles[i].language[0] != '*'))
+ if (infiles[i].incompiler == input_file_compiler)
+ {
+ store_arg (infiles[i].name, 0, 0);
+ infiles[i].compiled = true;
+ }
}
else
{
}
for (; pl; pl = pl->next)
- {
- do_spec_1 ("-isystem", 1, NULL);
- /* Make this a separate argument. */
- do_spec_1 (" ", 0, NULL);
- do_spec_1 (pl->prefix, 1, NULL);
- do_spec_1 (" ", 0, NULL);
- }
+ /* Separate options, don't include non-suffixed variant. */
+ do_spec_path (pl, "-isystem", 0, 1, 1, "include", "include");
}
break;
kill (getpid (), signum);
}
-extern int main (int, const char *const *);
+extern int main (int, const char **);
int
-main (int argc, const char *const *argv)
+main (int argc, const char **argv)
{
size_t i;
int value;
int linker_was_run = 0;
+ int lang_n_infiles = 0;
int num_linker_inputs = 0;
char *explicit_link_files;
char *specs_file;
explicit_link_files = xcalloc (1, n_infiles);
- if (combine_inputs)
+ if (combine_flag)
+ combine_inputs = true;
+ else
+ combine_inputs = false;
+
+ for (i = 0; (int) i < n_infiles; i++)
{
- int lang_n_infiles = 0;
- for (i = 0; (int) i < n_infiles; i++)
- {
- const char *name = infiles[i].name;
- struct compiler *compiler
- = lookup_compiler (name, strlen (name), infiles[i].language);
- if (compiler == NULL)
- error ("%s: linker input file unused because linking not done",
- name);
- else if (lang_n_infiles > 0 && compiler != input_file_compiler)
- fatal ("cannot specify -o with -c or -S and multiple languages");
- else
- {
- lang_n_infiles++;
- input_file_compiler = compiler;
- }
- }
+ const char *name = infiles[i].name;
+ struct compiler *compiler = lookup_compiler (name,
+ strlen (name),
+ infiles[i].language);
+
+ if (compiler && !(compiler->combinable))
+ combine_inputs = false;
+
+ if (lang_n_infiles > 0 && compiler != input_file_compiler
+ && infiles[i].language && infiles[i].language[0] != '*')
+ infiles[i].incompiler = compiler;
+ else if (compiler)
+ {
+ lang_n_infiles++;
+ input_file_compiler = compiler;
+ infiles[i].incompiler = compiler;
+ }
+ else
+ {
+ /* Since there is no compiler for this input file, assume it is a
+ linker file. */
+ explicit_link_files[i] = 1;
+ infiles[i].incompiler = NULL;
+ }
+ infiles[i].compiled = false;
+ infiles[i].preprocessed = false;
}
- for (i = 0; (int) i < (combine_inputs ? 1 : n_infiles); i++)
+ if (combine_flag && save_temps_flag)
+ {
+ bool save_combine_inputs = combine_inputs;
+ /* Must do a separate pre-processing pass for C & Objective-C files, to
+ obtain individual .i files. */
+
+ combine_inputs = false;
+ for (i = 0; (int) i < n_infiles; i++)
+ {
+ int this_file_error = 0;
+
+ input_file_number = i;
+ set_input (infiles[i].name);
+ if (infiles[i].incompiler
+ && (infiles[i].incompiler)->needs_preprocessing)
+ input_file_compiler = infiles[i].incompiler;
+ else
+ continue;
+
+ if (input_file_compiler)
+ {
+ if (input_file_compiler->spec[0] == '#')
+ {
+ error ("%s: %s compiler not installed on this system",
+ input_filename, &input_file_compiler->spec[1]);
+ this_file_error = 1;
+ }
+ else
+ {
+ value = do_spec (input_file_compiler->spec);
+ infiles[i].preprocessed = true;
+ if (have_o_argbuf_index)
+ infiles[i].name = argbuf[have_o_argbuf_index];
+ else
+ abort ();
+ infiles[i].incompiler = lookup_compiler (infiles[i].name,
+ strlen (infiles[i].name),
+ infiles[i].language);
+
+ if (value < 0)
+ this_file_error = 1;
+ }
+ }
+
+ if (this_file_error)
+ {
+ delete_failure_queue ();
+ error_count++;
+ break;
+ }
+ clear_failure_queue ();
+ }
+ combine_inputs = save_combine_inputs;
+ }
+
+ for (i = 0; (int) i < n_infiles; i++)
{
int this_file_error = 0;
input_file_number = i;
set_input (infiles[i].name);
+ if (infiles[i].compiled)
+ continue;
+
/* Use the same thing in %o, unless cp->spec says otherwise. */
outfiles[i] = input_filename;
input_file_compiler
= lookup_compiler (infiles[i].name, input_filename_length,
infiles[i].language);
+ else
+ input_file_compiler = infiles[i].incompiler;
if (input_file_compiler)
{
else
{
value = do_spec (input_file_compiler->spec);
+ infiles[i].compiled = true;
if (value < 0)
this_file_error = 1;
}
{
delete_failure_queue ();
error_count++;
+ break;
}
/* If this compilation succeeded, don't delete those files later. */
clear_failure_queue ();
}
#if defined (OS2) ||defined (HAVE_DOS_BASED_FILE_SYSTEM)
- /* look again, but case-insensitively this time. */
+ /* Look again, but case-insensitively this time. */
if (cp < compilers)
for (cp = compilers + n_compilers - 1; cp >= compilers; cp--)
{
= xmalloc (sizeof (struct mswitchstr)
* (n_mdswitches + (n_switches ? n_switches : 1)));
for (i = 0; i < n_switches; i++)
- {
- int xlen = strlen (switches[i].part1);
- for (j = 0; j < cnt; j++)
- if (xlen == matches[j].len
- && ! strncmp (switches[i].part1, matches[j].str, xlen))
- {
- mswitches[n_mswitches].str = matches[j].replace;
- mswitches[n_mswitches].len = matches[j].rep_len;
- mswitches[n_mswitches].replace = (char *) 0;
- mswitches[n_mswitches].rep_len = 0;
- n_mswitches++;
- break;
- }
- }
+ if (switches[i].live_cond != SWITCH_IGNORE)
+ {
+ int xlen = strlen (switches[i].part1);
+ for (j = 0; j < cnt; j++)
+ if (xlen == matches[j].len
+ && ! strncmp (switches[i].part1, matches[j].str, xlen))
+ {
+ mswitches[n_mswitches].str = matches[j].replace;
+ mswitches[n_mswitches].len = matches[j].rep_len;
+ mswitches[n_mswitches].replace = (char *) 0;
+ mswitches[n_mswitches].rep_len = 0;
+ n_mswitches++;
+ break;
+ }
+ }
/* Add MULTILIB_DEFAULTS switches too, as long as they were not present
on the command line nor any options mutually incompatible with