1e4b17023SJohn Marino /* Wrapper to call lto. Used by collect2 and the linker plugin.
2e4b17023SJohn Marino Copyright (C) 2009, 2010 Free Software Foundation, Inc.
3e4b17023SJohn Marino
4e4b17023SJohn Marino Factored out of collect2 by Rafael Espindola <espindola@google.com>
5e4b17023SJohn Marino
6e4b17023SJohn Marino This file is part of GCC.
7e4b17023SJohn Marino
8e4b17023SJohn Marino GCC is free software; you can redistribute it and/or modify it under
9e4b17023SJohn Marino the terms of the GNU General Public License as published by the Free
10e4b17023SJohn Marino Software Foundation; either version 3, or (at your option) any later
11e4b17023SJohn Marino version.
12e4b17023SJohn Marino
13e4b17023SJohn Marino GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14e4b17023SJohn Marino WARRANTY; without even the implied warranty of MERCHANTABILITY or
15e4b17023SJohn Marino FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16e4b17023SJohn Marino for more details.
17e4b17023SJohn Marino
18e4b17023SJohn Marino You should have received a copy of the GNU General Public License
19e4b17023SJohn Marino along with GCC; see the file COPYING3. If not see
20e4b17023SJohn Marino <http://www.gnu.org/licenses/>. */
21e4b17023SJohn Marino
22e4b17023SJohn Marino
23e4b17023SJohn Marino /* This program is passed a gcc, a list of gcc arguments and a list of
24e4b17023SJohn Marino object files containing IL. It scans the argument list to check if
25e4b17023SJohn Marino we are in whopr mode or not modifies the arguments and needed and
26e4b17023SJohn Marino prints a list of output files on stdout.
27e4b17023SJohn Marino
28e4b17023SJohn Marino Example:
29e4b17023SJohn Marino
30e4b17023SJohn Marino $ lto-wrapper gcc/xgcc -B gcc a.o b.o -o test -flto
31e4b17023SJohn Marino
32e4b17023SJohn Marino The above will print something like
33e4b17023SJohn Marino /tmp/ccwbQ8B2.lto.o
34e4b17023SJohn Marino
35e4b17023SJohn Marino If WHOPR is used instead, more than one file might be produced
36e4b17023SJohn Marino ./ccXj2DTk.lto.ltrans.o
37e4b17023SJohn Marino ./ccCJuXGv.lto.ltrans.o
38e4b17023SJohn Marino */
39e4b17023SJohn Marino
40e4b17023SJohn Marino #include "config.h"
41e4b17023SJohn Marino #include "system.h"
42e4b17023SJohn Marino #include "coretypes.h"
43e4b17023SJohn Marino #include "intl.h"
44e4b17023SJohn Marino #include "diagnostic.h"
45e4b17023SJohn Marino #include "obstack.h"
46e4b17023SJohn Marino #include "opts.h"
47e4b17023SJohn Marino #include "options.h"
48e4b17023SJohn Marino #include "simple-object.h"
49e4b17023SJohn Marino
50e4b17023SJohn Marino /* From lto-streamer.h which we cannot include with -fkeep-inline-functions.
51e4b17023SJohn Marino ??? Split out a lto-streamer-core.h. */
52e4b17023SJohn Marino
53e4b17023SJohn Marino #define LTO_SECTION_NAME_PREFIX ".gnu.lto_"
54e4b17023SJohn Marino
55e4b17023SJohn Marino /* End of lto-streamer.h copy. */
56e4b17023SJohn Marino
57e4b17023SJohn Marino int debug; /* true if -save-temps. */
58e4b17023SJohn Marino int verbose; /* true if -v. */
59e4b17023SJohn Marino
60e4b17023SJohn Marino enum lto_mode_d {
61e4b17023SJohn Marino LTO_MODE_NONE, /* Not doing LTO. */
62e4b17023SJohn Marino LTO_MODE_LTO, /* Normal LTO. */
63e4b17023SJohn Marino LTO_MODE_WHOPR /* WHOPR. */
64e4b17023SJohn Marino };
65e4b17023SJohn Marino
66e4b17023SJohn Marino /* Current LTO mode. */
67e4b17023SJohn Marino static enum lto_mode_d lto_mode = LTO_MODE_NONE;
68e4b17023SJohn Marino
69e4b17023SJohn Marino static char *ltrans_output_file;
70e4b17023SJohn Marino static char *flto_out;
71e4b17023SJohn Marino static char *args_name;
72e4b17023SJohn Marino static unsigned int nr;
73e4b17023SJohn Marino static char **input_names;
74e4b17023SJohn Marino static char **output_names;
75e4b17023SJohn Marino static char *makefile;
76e4b17023SJohn Marino
77e4b17023SJohn Marino static void maybe_unlink_file (const char *);
78e4b17023SJohn Marino
79e4b17023SJohn Marino /* Delete tempfiles. */
80e4b17023SJohn Marino
81e4b17023SJohn Marino static void
lto_wrapper_cleanup(void)82e4b17023SJohn Marino lto_wrapper_cleanup (void)
83e4b17023SJohn Marino {
84e4b17023SJohn Marino static bool cleanup_done = false;
85e4b17023SJohn Marino unsigned int i;
86e4b17023SJohn Marino
87e4b17023SJohn Marino if (cleanup_done)
88e4b17023SJohn Marino return;
89e4b17023SJohn Marino
90e4b17023SJohn Marino /* Setting cleanup_done prevents an infinite loop if one of the
91e4b17023SJohn Marino calls to maybe_unlink_file fails. */
92e4b17023SJohn Marino cleanup_done = true;
93e4b17023SJohn Marino
94e4b17023SJohn Marino if (ltrans_output_file)
95e4b17023SJohn Marino maybe_unlink_file (ltrans_output_file);
96e4b17023SJohn Marino if (flto_out)
97e4b17023SJohn Marino maybe_unlink_file (flto_out);
98e4b17023SJohn Marino if (args_name)
99e4b17023SJohn Marino maybe_unlink_file (args_name);
100e4b17023SJohn Marino if (makefile)
101e4b17023SJohn Marino maybe_unlink_file (makefile);
102e4b17023SJohn Marino for (i = 0; i < nr; ++i)
103e4b17023SJohn Marino {
104e4b17023SJohn Marino maybe_unlink_file (input_names[i]);
105e4b17023SJohn Marino if (output_names[i])
106e4b17023SJohn Marino maybe_unlink_file (output_names[i]);
107e4b17023SJohn Marino }
108e4b17023SJohn Marino }
109e4b17023SJohn Marino
110e4b17023SJohn Marino static void
fatal_signal(int signum)111e4b17023SJohn Marino fatal_signal (int signum)
112e4b17023SJohn Marino {
113e4b17023SJohn Marino signal (signum, SIG_DFL);
114e4b17023SJohn Marino lto_wrapper_cleanup ();
115e4b17023SJohn Marino /* Get the same signal again, this time not handled,
116e4b17023SJohn Marino so its normal effect occurs. */
117e4b17023SJohn Marino kill (getpid (), signum);
118e4b17023SJohn Marino }
119e4b17023SJohn Marino
120e4b17023SJohn Marino /* Just die. CMSGID is the error message. */
121e4b17023SJohn Marino
122e4b17023SJohn Marino static void __attribute__ ((format (printf, 1, 2)))
fatal(const char * cmsgid,...)123e4b17023SJohn Marino fatal (const char * cmsgid, ...)
124e4b17023SJohn Marino {
125e4b17023SJohn Marino va_list ap;
126e4b17023SJohn Marino
127e4b17023SJohn Marino va_start (ap, cmsgid);
128e4b17023SJohn Marino fprintf (stderr, "lto-wrapper: ");
129e4b17023SJohn Marino vfprintf (stderr, _(cmsgid), ap);
130e4b17023SJohn Marino fprintf (stderr, "\n");
131e4b17023SJohn Marino va_end (ap);
132e4b17023SJohn Marino
133e4b17023SJohn Marino lto_wrapper_cleanup ();
134e4b17023SJohn Marino exit (FATAL_EXIT_CODE);
135e4b17023SJohn Marino }
136e4b17023SJohn Marino
137e4b17023SJohn Marino
138e4b17023SJohn Marino /* Die when sys call fails. CMSGID is the error message. */
139e4b17023SJohn Marino
140e4b17023SJohn Marino static void __attribute__ ((format (printf, 1, 2)))
fatal_perror(const char * cmsgid,...)141e4b17023SJohn Marino fatal_perror (const char *cmsgid, ...)
142e4b17023SJohn Marino {
143e4b17023SJohn Marino int e = errno;
144e4b17023SJohn Marino va_list ap;
145e4b17023SJohn Marino
146e4b17023SJohn Marino va_start (ap, cmsgid);
147e4b17023SJohn Marino fprintf (stderr, "lto-wrapper: ");
148e4b17023SJohn Marino vfprintf (stderr, _(cmsgid), ap);
149e4b17023SJohn Marino fprintf (stderr, ": %s\n", xstrerror (e));
150e4b17023SJohn Marino va_end (ap);
151e4b17023SJohn Marino
152e4b17023SJohn Marino lto_wrapper_cleanup ();
153e4b17023SJohn Marino exit (FATAL_EXIT_CODE);
154e4b17023SJohn Marino }
155e4b17023SJohn Marino
156e4b17023SJohn Marino
157e4b17023SJohn Marino /* Execute a program, and wait for the reply. ARGV are the arguments. The
158e4b17023SJohn Marino last one must be NULL. */
159e4b17023SJohn Marino
160e4b17023SJohn Marino static struct pex_obj *
collect_execute(char ** argv)161e4b17023SJohn Marino collect_execute (char **argv)
162e4b17023SJohn Marino {
163e4b17023SJohn Marino struct pex_obj *pex;
164e4b17023SJohn Marino const char *errmsg;
165e4b17023SJohn Marino int err;
166e4b17023SJohn Marino
167e4b17023SJohn Marino if (verbose)
168e4b17023SJohn Marino {
169e4b17023SJohn Marino char **p_argv;
170e4b17023SJohn Marino const char *str;
171e4b17023SJohn Marino
172e4b17023SJohn Marino for (p_argv = argv; (str = *p_argv) != (char *) 0; p_argv++)
173e4b17023SJohn Marino fprintf (stderr, " %s", str);
174e4b17023SJohn Marino
175e4b17023SJohn Marino fprintf (stderr, "\n");
176e4b17023SJohn Marino }
177e4b17023SJohn Marino
178e4b17023SJohn Marino fflush (stdout);
179e4b17023SJohn Marino fflush (stderr);
180e4b17023SJohn Marino
181e4b17023SJohn Marino pex = pex_init (0, "lto-wrapper", NULL);
182e4b17023SJohn Marino if (pex == NULL)
183e4b17023SJohn Marino fatal_perror ("pex_init failed");
184e4b17023SJohn Marino
185e4b17023SJohn Marino /* Do not use PEX_LAST here, we use our stdout for communicating with
186e4b17023SJohn Marino collect2 or the linker-plugin. Any output from the sub-process
187e4b17023SJohn Marino will confuse that. */
188e4b17023SJohn Marino errmsg = pex_run (pex, PEX_SEARCH, argv[0], argv, NULL,
189e4b17023SJohn Marino NULL, &err);
190e4b17023SJohn Marino if (errmsg != NULL)
191e4b17023SJohn Marino {
192e4b17023SJohn Marino if (err != 0)
193e4b17023SJohn Marino {
194e4b17023SJohn Marino errno = err;
195e4b17023SJohn Marino fatal_perror (errmsg);
196e4b17023SJohn Marino }
197e4b17023SJohn Marino else
198e4b17023SJohn Marino fatal (errmsg);
199e4b17023SJohn Marino }
200e4b17023SJohn Marino
201e4b17023SJohn Marino return pex;
202e4b17023SJohn Marino }
203e4b17023SJohn Marino
204e4b17023SJohn Marino
205e4b17023SJohn Marino /* Wait for a process to finish, and exit if a nonzero status is found.
206e4b17023SJohn Marino PROG is the program name. PEX is the process we should wait for. */
207e4b17023SJohn Marino
208e4b17023SJohn Marino static int
collect_wait(const char * prog,struct pex_obj * pex)209e4b17023SJohn Marino collect_wait (const char *prog, struct pex_obj *pex)
210e4b17023SJohn Marino {
211e4b17023SJohn Marino int status;
212e4b17023SJohn Marino
213e4b17023SJohn Marino if (!pex_get_status (pex, 1, &status))
214e4b17023SJohn Marino fatal_perror ("can't get program status");
215e4b17023SJohn Marino pex_free (pex);
216e4b17023SJohn Marino
217e4b17023SJohn Marino if (status)
218e4b17023SJohn Marino {
219e4b17023SJohn Marino if (WIFSIGNALED (status))
220e4b17023SJohn Marino {
221e4b17023SJohn Marino int sig = WTERMSIG (status);
222e4b17023SJohn Marino if (WCOREDUMP (status))
223e4b17023SJohn Marino fatal ("%s terminated with signal %d [%s], core dumped",
224e4b17023SJohn Marino prog, sig, strsignal (sig));
225e4b17023SJohn Marino else
226e4b17023SJohn Marino fatal ("%s terminated with signal %d [%s]",
227e4b17023SJohn Marino prog, sig, strsignal (sig));
228e4b17023SJohn Marino }
229e4b17023SJohn Marino
230e4b17023SJohn Marino if (WIFEXITED (status))
231e4b17023SJohn Marino fatal ("%s returned %d exit status", prog, WEXITSTATUS (status));
232e4b17023SJohn Marino }
233e4b17023SJohn Marino
234e4b17023SJohn Marino return 0;
235e4b17023SJohn Marino }
236e4b17023SJohn Marino
237e4b17023SJohn Marino
238e4b17023SJohn Marino /* Unlink a temporary LTRANS file unless requested otherwise. */
239e4b17023SJohn Marino
240e4b17023SJohn Marino static void
maybe_unlink_file(const char * file)241e4b17023SJohn Marino maybe_unlink_file (const char *file)
242e4b17023SJohn Marino {
243e4b17023SJohn Marino if (! debug)
244e4b17023SJohn Marino {
245e4b17023SJohn Marino if (unlink_if_ordinary (file)
246e4b17023SJohn Marino && errno != ENOENT)
247e4b17023SJohn Marino fatal_perror ("deleting LTRANS file %s", file);
248e4b17023SJohn Marino }
249e4b17023SJohn Marino else
250e4b17023SJohn Marino fprintf (stderr, "[Leaving LTRANS %s]\n", file);
251e4b17023SJohn Marino }
252e4b17023SJohn Marino
253e4b17023SJohn Marino
254e4b17023SJohn Marino /* Execute program ARGV[0] with arguments ARGV. Wait for it to finish. */
255e4b17023SJohn Marino
256e4b17023SJohn Marino static void
fork_execute(char ** argv)257e4b17023SJohn Marino fork_execute (char **argv)
258e4b17023SJohn Marino {
259e4b17023SJohn Marino struct pex_obj *pex;
260e4b17023SJohn Marino char *new_argv[3];
261e4b17023SJohn Marino char *at_args;
262e4b17023SJohn Marino FILE *args;
263e4b17023SJohn Marino int status;
264e4b17023SJohn Marino
265e4b17023SJohn Marino args_name = make_temp_file (".args");
266e4b17023SJohn Marino at_args = concat ("@", args_name, NULL);
267e4b17023SJohn Marino args = fopen (args_name, "w");
268e4b17023SJohn Marino if (args == NULL)
269e4b17023SJohn Marino fatal ("failed to open %s", args_name);
270e4b17023SJohn Marino
271e4b17023SJohn Marino status = writeargv (&argv[1], args);
272e4b17023SJohn Marino
273e4b17023SJohn Marino if (status)
274e4b17023SJohn Marino fatal ("could not write to temporary file %s", args_name);
275e4b17023SJohn Marino
276e4b17023SJohn Marino fclose (args);
277e4b17023SJohn Marino
278e4b17023SJohn Marino new_argv[0] = argv[0];
279e4b17023SJohn Marino new_argv[1] = at_args;
280e4b17023SJohn Marino new_argv[2] = NULL;
281e4b17023SJohn Marino
282e4b17023SJohn Marino pex = collect_execute (new_argv);
283e4b17023SJohn Marino collect_wait (new_argv[0], pex);
284e4b17023SJohn Marino
285e4b17023SJohn Marino maybe_unlink_file (args_name);
286e4b17023SJohn Marino args_name = NULL;
287e4b17023SJohn Marino free (at_args);
288e4b17023SJohn Marino }
289e4b17023SJohn Marino
290e4b17023SJohn Marino /* Template of LTRANS dumpbase suffix. */
291e4b17023SJohn Marino #define DUMPBASE_SUFFIX ".ltrans18446744073709551615"
292e4b17023SJohn Marino
293e4b17023SJohn Marino /* Create decoded options from the COLLECT_GCC and COLLECT_GCC_OPTIONS
294e4b17023SJohn Marino environment according to LANG_MASK. */
295e4b17023SJohn Marino
296e4b17023SJohn Marino static void
get_options_from_collect_gcc_options(const char * collect_gcc,const char * collect_gcc_options,unsigned int lang_mask,struct cl_decoded_option ** decoded_options,unsigned int * decoded_options_count)297e4b17023SJohn Marino get_options_from_collect_gcc_options (const char *collect_gcc,
298e4b17023SJohn Marino const char *collect_gcc_options,
299e4b17023SJohn Marino unsigned int lang_mask,
300e4b17023SJohn Marino struct cl_decoded_option **decoded_options,
301e4b17023SJohn Marino unsigned int *decoded_options_count)
302e4b17023SJohn Marino {
303e4b17023SJohn Marino struct obstack argv_obstack;
304e4b17023SJohn Marino char *argv_storage;
305e4b17023SJohn Marino const char **argv;
306e4b17023SJohn Marino int j, k, argc;
307e4b17023SJohn Marino
308e4b17023SJohn Marino argv_storage = xstrdup (collect_gcc_options);
309e4b17023SJohn Marino obstack_init (&argv_obstack);
310e4b17023SJohn Marino obstack_ptr_grow (&argv_obstack, collect_gcc);
311e4b17023SJohn Marino
312e4b17023SJohn Marino for (j = 0, k = 0; argv_storage[j] != '\0'; ++j)
313e4b17023SJohn Marino {
314e4b17023SJohn Marino if (argv_storage[j] == '\'')
315e4b17023SJohn Marino {
316e4b17023SJohn Marino obstack_ptr_grow (&argv_obstack, &argv_storage[k]);
317e4b17023SJohn Marino ++j;
318e4b17023SJohn Marino do
319e4b17023SJohn Marino {
320e4b17023SJohn Marino if (argv_storage[j] == '\0')
321e4b17023SJohn Marino fatal ("malformed COLLECT_GCC_OPTIONS");
322e4b17023SJohn Marino else if (strncmp (&argv_storage[j], "'\\''", 4) == 0)
323e4b17023SJohn Marino {
324e4b17023SJohn Marino argv_storage[k++] = '\'';
325e4b17023SJohn Marino j += 4;
326e4b17023SJohn Marino }
327e4b17023SJohn Marino else if (argv_storage[j] == '\'')
328e4b17023SJohn Marino break;
329e4b17023SJohn Marino else
330e4b17023SJohn Marino argv_storage[k++] = argv_storage[j++];
331e4b17023SJohn Marino }
332e4b17023SJohn Marino while (1);
333e4b17023SJohn Marino argv_storage[k++] = '\0';
334e4b17023SJohn Marino }
335e4b17023SJohn Marino }
336e4b17023SJohn Marino
337e4b17023SJohn Marino obstack_ptr_grow (&argv_obstack, NULL);
338e4b17023SJohn Marino argc = obstack_object_size (&argv_obstack) / sizeof (void *) - 1;
339e4b17023SJohn Marino argv = XOBFINISH (&argv_obstack, const char **);
340e4b17023SJohn Marino
341e4b17023SJohn Marino decode_cmdline_options_to_array (argc, (const char **)argv,
342e4b17023SJohn Marino lang_mask,
343e4b17023SJohn Marino decoded_options, decoded_options_count);
344e4b17023SJohn Marino obstack_free (&argv_obstack, NULL);
345e4b17023SJohn Marino }
346e4b17023SJohn Marino
347e4b17023SJohn Marino /* Append OPTION to the options array DECODED_OPTIONS with size
348e4b17023SJohn Marino DECODED_OPTIONS_COUNT. */
349e4b17023SJohn Marino
350e4b17023SJohn Marino static void
append_option(struct cl_decoded_option ** decoded_options,unsigned int * decoded_options_count,struct cl_decoded_option * option)351e4b17023SJohn Marino append_option (struct cl_decoded_option **decoded_options,
352e4b17023SJohn Marino unsigned int *decoded_options_count,
353e4b17023SJohn Marino struct cl_decoded_option *option)
354e4b17023SJohn Marino {
355e4b17023SJohn Marino ++*decoded_options_count;
356e4b17023SJohn Marino *decoded_options
357e4b17023SJohn Marino = (struct cl_decoded_option *)
358e4b17023SJohn Marino xrealloc (*decoded_options,
359e4b17023SJohn Marino (*decoded_options_count
360e4b17023SJohn Marino * sizeof (struct cl_decoded_option)));
361e4b17023SJohn Marino memcpy (&(*decoded_options)[*decoded_options_count - 1], option,
362e4b17023SJohn Marino sizeof (struct cl_decoded_option));
363e4b17023SJohn Marino }
364e4b17023SJohn Marino
365e4b17023SJohn Marino /* Try to merge and complain about options FDECODED_OPTIONS when applied
366e4b17023SJohn Marino ontop of DECODED_OPTIONS. */
367e4b17023SJohn Marino
368e4b17023SJohn Marino static void
merge_and_complain(struct cl_decoded_option ** decoded_options,unsigned int * decoded_options_count,struct cl_decoded_option * fdecoded_options,unsigned int fdecoded_options_count)369e4b17023SJohn Marino merge_and_complain (struct cl_decoded_option **decoded_options,
370e4b17023SJohn Marino unsigned int *decoded_options_count,
371e4b17023SJohn Marino struct cl_decoded_option *fdecoded_options,
372e4b17023SJohn Marino unsigned int fdecoded_options_count)
373e4b17023SJohn Marino {
374e4b17023SJohn Marino unsigned int i, j;
375e4b17023SJohn Marino
376e4b17023SJohn Marino /* ??? Merge options from files. Most cases can be
377e4b17023SJohn Marino handled by either unioning or intersecting
378e4b17023SJohn Marino (for example -fwrapv is a case for unioning,
379e4b17023SJohn Marino -ffast-math is for intersection). Most complaints
380e4b17023SJohn Marino about real conflicts between different options can
381e4b17023SJohn Marino be deferred to the compiler proper. Options that
382e4b17023SJohn Marino we can neither safely handle by intersection nor
383e4b17023SJohn Marino unioning would need to be complained about here.
384e4b17023SJohn Marino Ideally we'd have a flag in the opt files that
385e4b17023SJohn Marino tells whether to union or intersect or reject.
386e4b17023SJohn Marino In absence of that it's unclear what a good default is.
387e4b17023SJohn Marino It's also difficult to get positional handling correct. */
388e4b17023SJohn Marino
389e4b17023SJohn Marino /* The following does what the old LTO option code did,
390e4b17023SJohn Marino union all target and a selected set of common options. */
391e4b17023SJohn Marino for (i = 0; i < fdecoded_options_count; ++i)
392e4b17023SJohn Marino {
393e4b17023SJohn Marino struct cl_decoded_option *foption = &fdecoded_options[i];
394e4b17023SJohn Marino switch (foption->opt_index)
395e4b17023SJohn Marino {
396*5ce9237cSJohn Marino case OPT_SPECIAL_unknown:
397*5ce9237cSJohn Marino case OPT_SPECIAL_ignore:
398*5ce9237cSJohn Marino case OPT_SPECIAL_program_name:
399*5ce9237cSJohn Marino case OPT_SPECIAL_input_file:
400*5ce9237cSJohn Marino break;
401*5ce9237cSJohn Marino
402e4b17023SJohn Marino default:
403e4b17023SJohn Marino if (!(cl_options[foption->opt_index].flags & CL_TARGET))
404e4b17023SJohn Marino break;
405e4b17023SJohn Marino
406e4b17023SJohn Marino /* Fallthru. */
407e4b17023SJohn Marino case OPT_fPIC:
408e4b17023SJohn Marino case OPT_fpic:
409e4b17023SJohn Marino case OPT_fpie:
410e4b17023SJohn Marino case OPT_fcommon:
411e4b17023SJohn Marino case OPT_fexceptions:
412e4b17023SJohn Marino case OPT_fgnu_tm:
413e4b17023SJohn Marino /* Do what the old LTO code did - collect exactly one option
414e4b17023SJohn Marino setting per OPT code, we pick the first we encounter.
415e4b17023SJohn Marino ??? This doesn't make too much sense, but when it doesn't
416e4b17023SJohn Marino then we should complain. */
417e4b17023SJohn Marino for (j = 0; j < *decoded_options_count; ++j)
418e4b17023SJohn Marino if ((*decoded_options)[j].opt_index == foption->opt_index)
419e4b17023SJohn Marino break;
420e4b17023SJohn Marino if (j == *decoded_options_count)
421e4b17023SJohn Marino append_option (decoded_options, decoded_options_count, foption);
422e4b17023SJohn Marino break;
423e4b17023SJohn Marino }
424e4b17023SJohn Marino }
425e4b17023SJohn Marino }
426e4b17023SJohn Marino
427e4b17023SJohn Marino /* Execute gcc. ARGC is the number of arguments. ARGV contains the arguments. */
428e4b17023SJohn Marino
429e4b17023SJohn Marino static void
run_gcc(unsigned argc,char * argv[])430e4b17023SJohn Marino run_gcc (unsigned argc, char *argv[])
431e4b17023SJohn Marino {
432e4b17023SJohn Marino unsigned i, j;
433e4b17023SJohn Marino const char **new_argv;
434e4b17023SJohn Marino const char **argv_ptr;
435e4b17023SJohn Marino char *list_option_full = NULL;
436e4b17023SJohn Marino const char *linker_output = NULL;
437e4b17023SJohn Marino const char *collect_gcc, *collect_gcc_options;
438e4b17023SJohn Marino int parallel = 0;
439e4b17023SJohn Marino int jobserver = 0;
440e4b17023SJohn Marino bool no_partition = false;
441e4b17023SJohn Marino struct cl_decoded_option *fdecoded_options = NULL;
442e4b17023SJohn Marino unsigned int fdecoded_options_count = 0;
443e4b17023SJohn Marino struct cl_decoded_option *decoded_options;
444e4b17023SJohn Marino unsigned int decoded_options_count;
445e4b17023SJohn Marino struct obstack argv_obstack;
446e4b17023SJohn Marino int new_head_argc;
447e4b17023SJohn Marino
448e4b17023SJohn Marino /* Get the driver and options. */
449e4b17023SJohn Marino collect_gcc = getenv ("COLLECT_GCC");
450e4b17023SJohn Marino if (!collect_gcc)
451e4b17023SJohn Marino fatal ("environment variable COLLECT_GCC must be set");
452e4b17023SJohn Marino collect_gcc_options = getenv ("COLLECT_GCC_OPTIONS");
453e4b17023SJohn Marino if (!collect_gcc_options)
454e4b17023SJohn Marino fatal ("environment variable COLLECT_GCC_OPTIONS must be set");
455e4b17023SJohn Marino get_options_from_collect_gcc_options (collect_gcc, collect_gcc_options,
456e4b17023SJohn Marino CL_LANG_ALL,
457e4b17023SJohn Marino &decoded_options,
458e4b17023SJohn Marino &decoded_options_count);
459e4b17023SJohn Marino
460e4b17023SJohn Marino /* Look at saved options in the IL files. */
461e4b17023SJohn Marino for (i = 1; i < argc; ++i)
462e4b17023SJohn Marino {
463e4b17023SJohn Marino char *data, *p;
464e4b17023SJohn Marino char *fopts;
465e4b17023SJohn Marino int fd;
466e4b17023SJohn Marino const char *errmsg;
467e4b17023SJohn Marino int err;
468e4b17023SJohn Marino off_t file_offset = 0, offset, length;
469e4b17023SJohn Marino long loffset;
470e4b17023SJohn Marino simple_object_read *sobj;
471e4b17023SJohn Marino int consumed;
472e4b17023SJohn Marino struct cl_decoded_option *f2decoded_options;
473e4b17023SJohn Marino unsigned int f2decoded_options_count;
474e4b17023SJohn Marino char *filename = argv[i];
475e4b17023SJohn Marino if ((p = strrchr (argv[i], '@'))
476e4b17023SJohn Marino && p != argv[i]
477e4b17023SJohn Marino && sscanf (p, "@%li%n", &loffset, &consumed) >= 1
478e4b17023SJohn Marino && strlen (p) == (unsigned int) consumed)
479e4b17023SJohn Marino {
480e4b17023SJohn Marino filename = XNEWVEC (char, p - argv[i] + 1);
481e4b17023SJohn Marino memcpy (filename, argv[i], p - argv[i]);
482e4b17023SJohn Marino filename[p - argv[i]] = '\0';
483e4b17023SJohn Marino file_offset = (off_t) loffset;
484e4b17023SJohn Marino }
485e4b17023SJohn Marino fd = open (argv[i], O_RDONLY);
486e4b17023SJohn Marino if (fd == -1)
487e4b17023SJohn Marino continue;
488e4b17023SJohn Marino sobj = simple_object_start_read (fd, file_offset, "__GNU_LTO",
489e4b17023SJohn Marino &errmsg, &err);
490e4b17023SJohn Marino if (!sobj)
491e4b17023SJohn Marino {
492e4b17023SJohn Marino close (fd);
493e4b17023SJohn Marino continue;
494e4b17023SJohn Marino }
495e4b17023SJohn Marino if (!simple_object_find_section (sobj, LTO_SECTION_NAME_PREFIX "." "opts",
496e4b17023SJohn Marino &offset, &length, &errmsg, &err))
497e4b17023SJohn Marino {
498e4b17023SJohn Marino simple_object_release_read (sobj);
499e4b17023SJohn Marino close (fd);
500e4b17023SJohn Marino continue;
501e4b17023SJohn Marino }
502e4b17023SJohn Marino lseek (fd, file_offset + offset, SEEK_SET);
503e4b17023SJohn Marino data = (char *)xmalloc (length);
504e4b17023SJohn Marino read (fd, data, length);
505e4b17023SJohn Marino fopts = data;
506e4b17023SJohn Marino do
507e4b17023SJohn Marino {
508e4b17023SJohn Marino get_options_from_collect_gcc_options (collect_gcc,
509e4b17023SJohn Marino fopts, CL_LANG_ALL,
510e4b17023SJohn Marino &f2decoded_options,
511e4b17023SJohn Marino &f2decoded_options_count);
512e4b17023SJohn Marino if (!fdecoded_options)
513e4b17023SJohn Marino {
514e4b17023SJohn Marino fdecoded_options = f2decoded_options;
515e4b17023SJohn Marino fdecoded_options_count = f2decoded_options_count;
516e4b17023SJohn Marino }
517e4b17023SJohn Marino else
518e4b17023SJohn Marino merge_and_complain (&fdecoded_options,
519e4b17023SJohn Marino &fdecoded_options_count,
520e4b17023SJohn Marino f2decoded_options, f2decoded_options_count);
521e4b17023SJohn Marino
522e4b17023SJohn Marino fopts += strlen (fopts) + 1;
523e4b17023SJohn Marino }
524e4b17023SJohn Marino while (fopts - data < length);
525e4b17023SJohn Marino
526e4b17023SJohn Marino free (data);
527e4b17023SJohn Marino simple_object_release_read (sobj);
528e4b17023SJohn Marino close (fd);
529e4b17023SJohn Marino }
530e4b17023SJohn Marino
531e4b17023SJohn Marino /* Initalize the common arguments for the driver. */
532e4b17023SJohn Marino obstack_init (&argv_obstack);
533e4b17023SJohn Marino obstack_ptr_grow (&argv_obstack, collect_gcc);
534e4b17023SJohn Marino obstack_ptr_grow (&argv_obstack, "-xlto");
535e4b17023SJohn Marino obstack_ptr_grow (&argv_obstack, "-c");
536e4b17023SJohn Marino
537e4b17023SJohn Marino /* Append compiler driver arguments as far as they were merged. */
538e4b17023SJohn Marino for (j = 1; j < fdecoded_options_count; ++j)
539e4b17023SJohn Marino {
540e4b17023SJohn Marino struct cl_decoded_option *option = &fdecoded_options[j];
541e4b17023SJohn Marino
542e4b17023SJohn Marino /* File options have been properly filtered by lto-opts.c. */
543e4b17023SJohn Marino switch (option->opt_index)
544e4b17023SJohn Marino {
545e4b17023SJohn Marino /* Drop arguments that we want to take from the link line. */
546e4b17023SJohn Marino case OPT_flto_:
547e4b17023SJohn Marino case OPT_flto:
548e4b17023SJohn Marino case OPT_flto_partition_none:
549e4b17023SJohn Marino case OPT_flto_partition_1to1:
550e4b17023SJohn Marino case OPT_flto_partition_balanced:
551e4b17023SJohn Marino continue;
552e4b17023SJohn Marino
553e4b17023SJohn Marino default:
554e4b17023SJohn Marino break;
555e4b17023SJohn Marino }
556e4b17023SJohn Marino
557e4b17023SJohn Marino /* For now do what the original LTO option code was doing - pass
558e4b17023SJohn Marino on any CL_TARGET flag and a few selected others. */
559e4b17023SJohn Marino switch (option->opt_index)
560e4b17023SJohn Marino {
561e4b17023SJohn Marino case OPT_fPIC:
562e4b17023SJohn Marino case OPT_fpic:
563e4b17023SJohn Marino case OPT_fpie:
564e4b17023SJohn Marino case OPT_fcommon:
565e4b17023SJohn Marino case OPT_fexceptions:
566e4b17023SJohn Marino case OPT_fgnu_tm:
567e4b17023SJohn Marino break;
568e4b17023SJohn Marino
569e4b17023SJohn Marino default:
570e4b17023SJohn Marino if (!(cl_options[option->opt_index].flags & CL_TARGET))
571e4b17023SJohn Marino continue;
572e4b17023SJohn Marino }
573e4b17023SJohn Marino
574e4b17023SJohn Marino /* Pass the option on. */
575e4b17023SJohn Marino for (i = 0; i < option->canonical_option_num_elements; ++i)
576e4b17023SJohn Marino obstack_ptr_grow (&argv_obstack, option->canonical_option[i]);
577e4b17023SJohn Marino }
578e4b17023SJohn Marino
579e4b17023SJohn Marino /* Append linker driver arguments. Compiler options from the linker
580e4b17023SJohn Marino driver arguments will override / merge with those from the compiler. */
581e4b17023SJohn Marino for (j = 1; j < decoded_options_count; ++j)
582e4b17023SJohn Marino {
583e4b17023SJohn Marino struct cl_decoded_option *option = &decoded_options[j];
584e4b17023SJohn Marino
585e4b17023SJohn Marino /* Do not pass on frontend specific flags not suitable for lto. */
586e4b17023SJohn Marino if (!(cl_options[option->opt_index].flags
587e4b17023SJohn Marino & (CL_COMMON|CL_TARGET|CL_DRIVER|CL_LTO)))
588e4b17023SJohn Marino continue;
589e4b17023SJohn Marino
590e4b17023SJohn Marino switch (option->opt_index)
591e4b17023SJohn Marino {
592e4b17023SJohn Marino case OPT_o:
593e4b17023SJohn Marino linker_output = option->arg;
594e4b17023SJohn Marino /* We generate new intermediate output, drop this arg. */
595e4b17023SJohn Marino continue;
596e4b17023SJohn Marino
597e4b17023SJohn Marino case OPT_save_temps:
598e4b17023SJohn Marino debug = 1;
599e4b17023SJohn Marino break;
600e4b17023SJohn Marino
601e4b17023SJohn Marino case OPT_v:
602e4b17023SJohn Marino verbose = 1;
603e4b17023SJohn Marino break;
604e4b17023SJohn Marino
605e4b17023SJohn Marino case OPT_flto_partition_none:
606e4b17023SJohn Marino no_partition = true;
607e4b17023SJohn Marino break;
608e4b17023SJohn Marino
609e4b17023SJohn Marino case OPT_flto_:
610e4b17023SJohn Marino if (strcmp (option->arg, "jobserver") == 0)
611e4b17023SJohn Marino {
612e4b17023SJohn Marino jobserver = 1;
613e4b17023SJohn Marino parallel = 1;
614e4b17023SJohn Marino }
615e4b17023SJohn Marino else
616e4b17023SJohn Marino {
617e4b17023SJohn Marino parallel = atoi (option->arg);
618e4b17023SJohn Marino if (parallel <= 1)
619e4b17023SJohn Marino parallel = 0;
620e4b17023SJohn Marino }
621e4b17023SJohn Marino /* Fallthru. */
622e4b17023SJohn Marino
623e4b17023SJohn Marino case OPT_flto:
624e4b17023SJohn Marino lto_mode = LTO_MODE_WHOPR;
625e4b17023SJohn Marino /* We've handled these LTO options, do not pass them on. */
626e4b17023SJohn Marino continue;
627e4b17023SJohn Marino
628e4b17023SJohn Marino default:
629e4b17023SJohn Marino break;
630e4b17023SJohn Marino }
631e4b17023SJohn Marino
632e4b17023SJohn Marino /* Pass the option on. */
633e4b17023SJohn Marino for (i = 0; i < option->canonical_option_num_elements; ++i)
634e4b17023SJohn Marino obstack_ptr_grow (&argv_obstack, option->canonical_option[i]);
635e4b17023SJohn Marino }
636e4b17023SJohn Marino
637e4b17023SJohn Marino if (no_partition)
638e4b17023SJohn Marino {
639e4b17023SJohn Marino lto_mode = LTO_MODE_LTO;
640e4b17023SJohn Marino jobserver = 0;
641e4b17023SJohn Marino parallel = 0;
642e4b17023SJohn Marino }
643e4b17023SJohn Marino
644e4b17023SJohn Marino if (linker_output)
645e4b17023SJohn Marino {
646e4b17023SJohn Marino char *output_dir, *base, *name;
647e4b17023SJohn Marino bool bit_bucket = strcmp (linker_output, HOST_BIT_BUCKET) == 0;
648e4b17023SJohn Marino
649e4b17023SJohn Marino output_dir = xstrdup (linker_output);
650e4b17023SJohn Marino base = output_dir;
651e4b17023SJohn Marino for (name = base; *name; name++)
652e4b17023SJohn Marino if (IS_DIR_SEPARATOR (*name))
653e4b17023SJohn Marino base = name + 1;
654e4b17023SJohn Marino *base = '\0';
655e4b17023SJohn Marino
656e4b17023SJohn Marino linker_output = &linker_output[base - output_dir];
657e4b17023SJohn Marino if (*output_dir == '\0')
658e4b17023SJohn Marino {
659e4b17023SJohn Marino static char current_dir[] = { '.', DIR_SEPARATOR, '\0' };
660e4b17023SJohn Marino output_dir = current_dir;
661e4b17023SJohn Marino }
662e4b17023SJohn Marino if (!bit_bucket)
663e4b17023SJohn Marino {
664e4b17023SJohn Marino obstack_ptr_grow (&argv_obstack, "-dumpdir");
665e4b17023SJohn Marino obstack_ptr_grow (&argv_obstack, output_dir);
666e4b17023SJohn Marino }
667e4b17023SJohn Marino
668e4b17023SJohn Marino obstack_ptr_grow (&argv_obstack, "-dumpbase");
669e4b17023SJohn Marino }
670e4b17023SJohn Marino
671e4b17023SJohn Marino /* Remember at which point we can scrub args to re-use the commons. */
672e4b17023SJohn Marino new_head_argc = obstack_object_size (&argv_obstack) / sizeof (void *);
673e4b17023SJohn Marino
674e4b17023SJohn Marino if (lto_mode == LTO_MODE_LTO)
675e4b17023SJohn Marino {
676e4b17023SJohn Marino flto_out = make_temp_file (".lto.o");
677e4b17023SJohn Marino if (linker_output)
678e4b17023SJohn Marino obstack_ptr_grow (&argv_obstack, linker_output);
679e4b17023SJohn Marino obstack_ptr_grow (&argv_obstack, "-o");
680e4b17023SJohn Marino obstack_ptr_grow (&argv_obstack, flto_out);
681e4b17023SJohn Marino }
682e4b17023SJohn Marino else
683e4b17023SJohn Marino {
684e4b17023SJohn Marino const char *list_option = "-fltrans-output-list=";
685e4b17023SJohn Marino size_t list_option_len = strlen (list_option);
686e4b17023SJohn Marino char *tmp;
687e4b17023SJohn Marino
688e4b17023SJohn Marino if (linker_output)
689e4b17023SJohn Marino {
690e4b17023SJohn Marino char *dumpbase = (char *) xmalloc (strlen (linker_output)
691e4b17023SJohn Marino + sizeof (".wpa") + 1);
692e4b17023SJohn Marino strcpy (dumpbase, linker_output);
693e4b17023SJohn Marino strcat (dumpbase, ".wpa");
694e4b17023SJohn Marino obstack_ptr_grow (&argv_obstack, dumpbase);
695e4b17023SJohn Marino }
696e4b17023SJohn Marino
697e4b17023SJohn Marino if (linker_output && debug)
698e4b17023SJohn Marino {
699e4b17023SJohn Marino ltrans_output_file = (char *) xmalloc (strlen (linker_output)
700e4b17023SJohn Marino + sizeof (".ltrans.out") + 1);
701e4b17023SJohn Marino strcpy (ltrans_output_file, linker_output);
702e4b17023SJohn Marino strcat (ltrans_output_file, ".ltrans.out");
703e4b17023SJohn Marino }
704e4b17023SJohn Marino else
705e4b17023SJohn Marino ltrans_output_file = make_temp_file (".ltrans.out");
706e4b17023SJohn Marino list_option_full = (char *) xmalloc (sizeof (char) *
707e4b17023SJohn Marino (strlen (ltrans_output_file) + list_option_len + 1));
708e4b17023SJohn Marino tmp = list_option_full;
709e4b17023SJohn Marino
710e4b17023SJohn Marino obstack_ptr_grow (&argv_obstack, tmp);
711e4b17023SJohn Marino strcpy (tmp, list_option);
712e4b17023SJohn Marino tmp += list_option_len;
713e4b17023SJohn Marino strcpy (tmp, ltrans_output_file);
714e4b17023SJohn Marino
715e4b17023SJohn Marino obstack_ptr_grow (&argv_obstack, "-fwpa");
716e4b17023SJohn Marino }
717e4b17023SJohn Marino
718e4b17023SJohn Marino /* Append the input objects and possible preceeding arguments. */
719e4b17023SJohn Marino for (i = 1; i < argc; ++i)
720e4b17023SJohn Marino obstack_ptr_grow (&argv_obstack, argv[i]);
721e4b17023SJohn Marino obstack_ptr_grow (&argv_obstack, NULL);
722e4b17023SJohn Marino
723e4b17023SJohn Marino new_argv = XOBFINISH (&argv_obstack, const char **);
724e4b17023SJohn Marino argv_ptr = &new_argv[new_head_argc];
725e4b17023SJohn Marino fork_execute (CONST_CAST (char **, new_argv));
726e4b17023SJohn Marino
727e4b17023SJohn Marino if (lto_mode == LTO_MODE_LTO)
728e4b17023SJohn Marino {
729e4b17023SJohn Marino printf("%s\n", flto_out);
730e4b17023SJohn Marino free (flto_out);
731e4b17023SJohn Marino flto_out = NULL;
732e4b17023SJohn Marino }
733e4b17023SJohn Marino else
734e4b17023SJohn Marino {
735e4b17023SJohn Marino FILE *stream = fopen (ltrans_output_file, "r");
736e4b17023SJohn Marino FILE *mstream = NULL;
737e4b17023SJohn Marino struct obstack env_obstack;
738e4b17023SJohn Marino
739e4b17023SJohn Marino if (!stream)
740e4b17023SJohn Marino fatal_perror ("fopen: %s", ltrans_output_file);
741e4b17023SJohn Marino
742e4b17023SJohn Marino /* Parse the list of LTRANS inputs from the WPA stage. */
743e4b17023SJohn Marino obstack_init (&env_obstack);
744e4b17023SJohn Marino nr = 0;
745e4b17023SJohn Marino for (;;)
746e4b17023SJohn Marino {
747e4b17023SJohn Marino const unsigned piece = 32;
748e4b17023SJohn Marino char *output_name = NULL;
749e4b17023SJohn Marino char *buf, *input_name = (char *)xmalloc (piece);
750e4b17023SJohn Marino size_t len;
751e4b17023SJohn Marino
752e4b17023SJohn Marino buf = input_name;
753e4b17023SJohn Marino cont:
754e4b17023SJohn Marino if (!fgets (buf, piece, stream))
755e4b17023SJohn Marino break;
756e4b17023SJohn Marino len = strlen (input_name);
757e4b17023SJohn Marino if (input_name[len - 1] != '\n')
758e4b17023SJohn Marino {
759e4b17023SJohn Marino input_name = (char *)xrealloc (input_name, len + piece);
760e4b17023SJohn Marino buf = input_name + len;
761e4b17023SJohn Marino goto cont;
762e4b17023SJohn Marino }
763e4b17023SJohn Marino input_name[len - 1] = '\0';
764e4b17023SJohn Marino
765e4b17023SJohn Marino if (input_name[0] == '*')
766e4b17023SJohn Marino output_name = &input_name[1];
767e4b17023SJohn Marino
768e4b17023SJohn Marino nr++;
769e4b17023SJohn Marino input_names = (char **)xrealloc (input_names, nr * sizeof (char *));
770e4b17023SJohn Marino output_names = (char **)xrealloc (output_names, nr * sizeof (char *));
771e4b17023SJohn Marino input_names[nr-1] = input_name;
772e4b17023SJohn Marino output_names[nr-1] = output_name;
773e4b17023SJohn Marino }
774e4b17023SJohn Marino fclose (stream);
775e4b17023SJohn Marino maybe_unlink_file (ltrans_output_file);
776e4b17023SJohn Marino ltrans_output_file = NULL;
777e4b17023SJohn Marino
778e4b17023SJohn Marino if (parallel)
779e4b17023SJohn Marino {
780e4b17023SJohn Marino makefile = make_temp_file (".mk");
781e4b17023SJohn Marino mstream = fopen (makefile, "w");
782e4b17023SJohn Marino }
783e4b17023SJohn Marino
784e4b17023SJohn Marino /* Execute the LTRANS stage for each input file (or prepare a
785e4b17023SJohn Marino makefile to invoke this in parallel). */
786e4b17023SJohn Marino for (i = 0; i < nr; ++i)
787e4b17023SJohn Marino {
788e4b17023SJohn Marino char *output_name;
789e4b17023SJohn Marino char *input_name = input_names[i];
790e4b17023SJohn Marino /* If it's a pass-through file do nothing. */
791e4b17023SJohn Marino if (output_names[i])
792e4b17023SJohn Marino continue;
793e4b17023SJohn Marino
794e4b17023SJohn Marino /* Replace the .o suffix with a .ltrans.o suffix and write
795e4b17023SJohn Marino the resulting name to the LTRANS output list. */
796e4b17023SJohn Marino obstack_grow (&env_obstack, input_name, strlen (input_name) - 2);
797e4b17023SJohn Marino obstack_grow (&env_obstack, ".ltrans.o", sizeof (".ltrans.o"));
798e4b17023SJohn Marino output_name = XOBFINISH (&env_obstack, char *);
799e4b17023SJohn Marino
800e4b17023SJohn Marino /* Adjust the dumpbase if the linker output file was seen. */
801e4b17023SJohn Marino if (linker_output)
802e4b17023SJohn Marino {
803e4b17023SJohn Marino char *dumpbase
804e4b17023SJohn Marino = (char *) xmalloc (strlen (linker_output)
805e4b17023SJohn Marino + sizeof(DUMPBASE_SUFFIX) + 1);
806e4b17023SJohn Marino snprintf (dumpbase,
807e4b17023SJohn Marino strlen (linker_output) + sizeof(DUMPBASE_SUFFIX),
808e4b17023SJohn Marino "%s.ltrans%u", linker_output, i);
809e4b17023SJohn Marino argv_ptr[0] = dumpbase;
810e4b17023SJohn Marino }
811e4b17023SJohn Marino
812e4b17023SJohn Marino argv_ptr[1] = "-fltrans";
813e4b17023SJohn Marino argv_ptr[2] = "-o";
814e4b17023SJohn Marino argv_ptr[3] = output_name;
815e4b17023SJohn Marino argv_ptr[4] = input_name;
816e4b17023SJohn Marino argv_ptr[5] = NULL;
817e4b17023SJohn Marino if (parallel)
818e4b17023SJohn Marino {
819e4b17023SJohn Marino fprintf (mstream, "%s:\n\t@%s ", output_name, new_argv[0]);
820e4b17023SJohn Marino for (j = 1; new_argv[j] != NULL; ++j)
821e4b17023SJohn Marino fprintf (mstream, " '%s'", new_argv[j]);
822e4b17023SJohn Marino fprintf (mstream, "\n");
823e4b17023SJohn Marino /* If we are not preserving the ltrans input files then
824e4b17023SJohn Marino truncate them as soon as we have processed it. This
825e4b17023SJohn Marino reduces temporary disk-space usage. */
826e4b17023SJohn Marino if (! debug)
827e4b17023SJohn Marino fprintf (mstream, "\t@-touch -r %s %s.tem > /dev/null 2>&1 "
828e4b17023SJohn Marino "&& mv %s.tem %s\n",
829e4b17023SJohn Marino input_name, input_name, input_name, input_name);
830e4b17023SJohn Marino }
831e4b17023SJohn Marino else
832e4b17023SJohn Marino {
833e4b17023SJohn Marino fork_execute (CONST_CAST (char **, new_argv));
834e4b17023SJohn Marino maybe_unlink_file (input_name);
835e4b17023SJohn Marino }
836e4b17023SJohn Marino
837e4b17023SJohn Marino output_names[i] = output_name;
838e4b17023SJohn Marino }
839e4b17023SJohn Marino if (parallel)
840e4b17023SJohn Marino {
841e4b17023SJohn Marino struct pex_obj *pex;
842e4b17023SJohn Marino char jobs[32];
843e4b17023SJohn Marino
844e4b17023SJohn Marino fprintf (mstream, "all:");
845e4b17023SJohn Marino for (i = 0; i < nr; ++i)
846e4b17023SJohn Marino fprintf (mstream, " \\\n\t%s", output_names[i]);
847e4b17023SJohn Marino fprintf (mstream, "\n");
848e4b17023SJohn Marino fclose (mstream);
849e4b17023SJohn Marino if (!jobserver)
850e4b17023SJohn Marino {
851e4b17023SJohn Marino /* Avoid passing --jobserver-fd= and similar flags
852e4b17023SJohn Marino unless jobserver mode is explicitly enabled. */
853e4b17023SJohn Marino putenv (xstrdup ("MAKEFLAGS="));
854e4b17023SJohn Marino putenv (xstrdup ("MFLAGS="));
855e4b17023SJohn Marino }
856e4b17023SJohn Marino new_argv[0] = getenv ("MAKE");
857e4b17023SJohn Marino if (!new_argv[0])
858e4b17023SJohn Marino new_argv[0] = "make";
859e4b17023SJohn Marino new_argv[1] = "-f";
860e4b17023SJohn Marino new_argv[2] = makefile;
861e4b17023SJohn Marino i = 3;
862e4b17023SJohn Marino if (!jobserver)
863e4b17023SJohn Marino {
864e4b17023SJohn Marino snprintf (jobs, 31, "-j%d", parallel);
865e4b17023SJohn Marino new_argv[i++] = jobs;
866e4b17023SJohn Marino }
867e4b17023SJohn Marino new_argv[i++] = "all";
868e4b17023SJohn Marino new_argv[i++] = NULL;
869e4b17023SJohn Marino pex = collect_execute (CONST_CAST (char **, new_argv));
870e4b17023SJohn Marino collect_wait (new_argv[0], pex);
871e4b17023SJohn Marino maybe_unlink_file (makefile);
872e4b17023SJohn Marino makefile = NULL;
873e4b17023SJohn Marino for (i = 0; i < nr; ++i)
874e4b17023SJohn Marino maybe_unlink_file (input_names[i]);
875e4b17023SJohn Marino }
876e4b17023SJohn Marino for (i = 0; i < nr; ++i)
877e4b17023SJohn Marino {
878e4b17023SJohn Marino fputs (output_names[i], stdout);
879e4b17023SJohn Marino putc ('\n', stdout);
880e4b17023SJohn Marino free (input_names[i]);
881e4b17023SJohn Marino }
882e4b17023SJohn Marino nr = 0;
883e4b17023SJohn Marino free (output_names);
884e4b17023SJohn Marino free (input_names);
885e4b17023SJohn Marino free (list_option_full);
886e4b17023SJohn Marino obstack_free (&env_obstack, NULL);
887e4b17023SJohn Marino }
888e4b17023SJohn Marino
889e4b17023SJohn Marino obstack_free (&argv_obstack, NULL);
890e4b17023SJohn Marino }
891e4b17023SJohn Marino
892e4b17023SJohn Marino
893e4b17023SJohn Marino /* Entry point. */
894e4b17023SJohn Marino
895e4b17023SJohn Marino int
main(int argc,char * argv[])896e4b17023SJohn Marino main (int argc, char *argv[])
897e4b17023SJohn Marino {
898e4b17023SJohn Marino const char *p;
899e4b17023SJohn Marino
900e4b17023SJohn Marino p = argv[0] + strlen (argv[0]);
901e4b17023SJohn Marino while (p != argv[0] && !IS_DIR_SEPARATOR (p[-1]))
902e4b17023SJohn Marino --p;
903e4b17023SJohn Marino progname = p;
904e4b17023SJohn Marino
905e4b17023SJohn Marino xmalloc_set_program_name (progname);
906e4b17023SJohn Marino
907e4b17023SJohn Marino gcc_init_libintl ();
908e4b17023SJohn Marino
909e4b17023SJohn Marino diagnostic_initialize (global_dc, 0);
910e4b17023SJohn Marino
911e4b17023SJohn Marino if (signal (SIGINT, SIG_IGN) != SIG_IGN)
912e4b17023SJohn Marino signal (SIGINT, fatal_signal);
913e4b17023SJohn Marino #ifdef SIGHUP
914e4b17023SJohn Marino if (signal (SIGHUP, SIG_IGN) != SIG_IGN)
915e4b17023SJohn Marino signal (SIGHUP, fatal_signal);
916e4b17023SJohn Marino #endif
917e4b17023SJohn Marino if (signal (SIGTERM, SIG_IGN) != SIG_IGN)
918e4b17023SJohn Marino signal (SIGTERM, fatal_signal);
919e4b17023SJohn Marino #ifdef SIGPIPE
920e4b17023SJohn Marino if (signal (SIGPIPE, SIG_IGN) != SIG_IGN)
921e4b17023SJohn Marino signal (SIGPIPE, fatal_signal);
922e4b17023SJohn Marino #endif
923e4b17023SJohn Marino #ifdef SIGCHLD
924e4b17023SJohn Marino /* We *MUST* set SIGCHLD to SIG_DFL so that the wait4() call will
925e4b17023SJohn Marino receive the signal. A different setting is inheritable */
926e4b17023SJohn Marino signal (SIGCHLD, SIG_DFL);
927e4b17023SJohn Marino #endif
928e4b17023SJohn Marino
929e4b17023SJohn Marino /* We may be called with all the arguments stored in some file and
930e4b17023SJohn Marino passed with @file. Expand them into argv before processing. */
931e4b17023SJohn Marino expandargv (&argc, &argv);
932e4b17023SJohn Marino
933e4b17023SJohn Marino run_gcc (argc, argv);
934e4b17023SJohn Marino
935e4b17023SJohn Marino return 0;
936e4b17023SJohn Marino }
937