/* Collect static initialization info into data structures that can be
traversed by C++ initialization and finalization routines.
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007 Free Software Foundation, Inc.
Contributed by Chris Smith (csmith@convex.com).
Heavily modified by Michael Meissner (meissner@cygnus.com),
Per Bothner (bothner@cygnus.com), and John Gilmore (gnu@cygnus.com).
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2, or (at your option) any later
+Software Foundation; either version 3, or (at your option) any later
version.
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
for more details.
You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING. If not, write to the Free
-Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301, USA. */
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
/* Build tables of static constructors and destructors and run ld. */
the utilities are not correct for a cross-compiler; we have to hope that
cross-versions are in the proper directories. */
-#ifdef CROSS_COMPILE
+#ifdef CROSS_DIRECTORY_STRUCTURE
#undef OBJECT_FORMAT_COFF
#undef MD_EXEC_PREFIX
#undef REAL_LD_FILE_NAME
#endif
static struct head frame_tables; /* list of frame unwind info tables */
+static bool at_file_supplied; /* Whether to use @file arguments */
+static char *response_file; /* Name of any current response file */
+
struct obstack temporary_obstack;
char * temporary_firstobj;
if (status != 0 && output_file != 0 && output_file[0])
maybe_unlink (output_file);
+ if (response_file)
+ maybe_unlink (response_file);
+
exit (status);
}
maybe_unlink (export_file);
#endif
+ if (response_file)
+ maybe_unlink (response_file);
+
signal (signo, SIG_DFL);
raise (signo);
}
static struct path_prefix cpath, path;
-#ifdef CROSS_COMPILE
+#ifdef CROSS_DIRECTORY_STRUCTURE
/* This is the name of the target machine. We use it to form the name
of the files to execute. */
else
endp++;
}
+ free (nstore);
}
\f
/* Main program. */
static const char *const strip_suffix = "strip";
static const char *const gstrip_suffix = "gstrip";
-#ifdef CROSS_COMPILE
+#ifdef CROSS_DIRECTORY_STRUCTURE
/* If we look for a program in the compiler directories, we just use
the short name, since these directories are already system-specific.
But it we look for a program in the system directories, we need to
#endif
const char *const full_strip_suffix = strip_suffix;
const char *const full_gstrip_suffix = gstrip_suffix;
-#endif /* CROSS_COMPILE */
+#endif /* CROSS_DIRECTORY_STRUCTURE */
const char *arg;
FILE *outf;
char **object_lst;
const char **object;
int first_file;
- int num_c_args = argc+9;
+ int num_c_args;
+ char **old_argv;
+
+ old_argv = argv;
+ expandargv (&argc, &argv);
+ if (argv != old_argv)
+ at_file_supplied = 1;
+
+ num_c_args = argc + 9;
no_demangle = !! getenv ("COLLECT_NO_DEMANGLE");
c_file_name = getenv ("COLLECT_GCC");
if (c_file_name == 0)
{
-#ifdef CROSS_COMPILE
+#ifdef CROSS_DIRECTORY_STRUCTURE
c_file_name = concat (target_machine, "-gcc", NULL);
#else
c_file_name = "gcc";
error ("%s returned %d exit status", prog, ret);
collect_exit (ret);
}
+
+ if (response_file)
+ {
+ unlink (response_file);
+ response_file = NULL;
+ }
}
\f
struct pex_obj *pex;
const char *errmsg;
int err;
+ char *response_arg = NULL;
+ char *response_argv[3] ATTRIBUTE_UNUSED;
+
+ if (HAVE_GNU_LD && at_file_supplied && argv[0] != NULL)
+ {
+ /* If using @file arguments, create a temporary file and put the
+ contents of argv into it. Then change argv to an array corresponding
+ to a single argument @FILE, where FILE is the temporary filename. */
+
+ char **current_argv = argv + 1;
+ char *argv0 = argv[0];
+ int status;
+ FILE *f;
+
+ /* Note: we assume argv contains at least one element; this is
+ checked above. */
+
+ response_file = make_temp_file ("");
+
+ f = fopen (response_file, "w");
+
+ if (f == NULL)
+ fatal ("could not open response file %s", response_file);
+
+ status = writeargv (current_argv, f);
+
+ if (status)
+ fatal ("could not write to response file %s", response_file);
+
+ status = fclose (f);
+
+ if (EOF == status)
+ fatal ("could not close response file %s", response_file);
+
+ response_arg = concat ("@", response_file, NULL);
+ response_argv[0] = argv0;
+ response_argv[1] = response_arg;
+ response_argv[2] = NULL;
+
+ argv = response_argv;
+ }
if (vflag || debug)
{
fatal (errmsg);
}
+ if (response_arg)
+ free (response_arg);
+
return pex;
}