/[llvm-project]/llvm-gcc-4.2/trunk/driverdriver.c
ViewVC logotype

Contents of /llvm-gcc-4.2/trunk/driverdriver.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 105535 - (show annotations) (download)
Mon Jun 7 12:09:02 2010 CDT (4 years, 11 months ago) by bwilson
File MIME type: text/plain
File size: 44877 byte(s)
Follow multiple levels of symbolic links for the driver-driver.  Otherwise,
the driver-driver fails to find the right compiler when it is linked via
multiple levels of symlinks, e.g., cc -> llvm-gcc-4.2 ->
$DEVELOPER_DIR/usr/bin/llvm-gcc-4.2.  Radar 8022536.
1 /* APPLE LOCAL file driver driver */
2
3 /* Darwin driver program that handles -arch commands and invokes
4 appropriate compiler driver.
5 Copyright (C) 2004, 2005 Free Software Foundation, Inc.
6
7 This file is part of GCC.
8
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 2, or (at your option) any later
12 version.
13
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING. If not, write to the Free
21 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
22 02111-1307, USA. */
23
24
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <unistd.h>
29 #include <errno.h>
30 #include <mach-o/arch.h>
31 #include <limits.h>
32 #include <sys/types.h>
33 #include <sys/stat.h>
34 #include <sys/wait.h>
35 #include <regex.h>
36 #include "libiberty.h"
37 #include "filenames.h"
38 #include "stdbool.h"
39 /* Hack!.
40 Pay the price for including darwin.h. */
41 typedef int tree;
42 typedef int rtx;
43 #define GTY(x) /* nothing */
44 #define USED_FOR_TARGET 1
45 /* Include darwin.h for SWITCH_TAKES_ARG and
46 WORD_SWIATCH_TAKES_ARG. */
47
48 #include "darwin.h"
49
50 /* Include gcc.h for DEFAULT_SWITCH_TAKES_ARG and
51 DEFAULT_WORD_SWIATCH_TAKES_ARG. */
52
53 #include "gcc.h"
54
55 /* This program name. */
56 const char *progname;
57
58 /* driver prefix. */
59 const char *driver_exec_prefix;
60
61 /* driver prefix length. */
62 int prefix_len;
63
64 /* current working directory. */
65 char *curr_dir;
66
67 /* Use if -o flag is absent. */
68 const char *final_output = "a.out";
69
70 /* Variabless to track presence and/or absence of important command
71 line options. */
72 int compile_only_request = 0;
73 int asm_output_request = 0;
74 int dash_capital_m_seen = 0;
75 int preprocessed_output_request = 0;
76 int ima_is_used = 0;
77 int dash_dynamiclib_seen = 0;
78 int verbose_flag = 0;
79 int save_temps_seen = 0;
80 int dash_m32_seen = 0;
81 int dash_m64_seen = 0;
82
83 /* Support at the max 10 arch. at a time. This is historical limit. */
84 #define MAX_ARCHES 10
85
86 /* Name of user supplied architectures. */
87 const char *arches[MAX_ARCHES];
88
89 /* -arch counter. */
90 static int num_arches;
91
92 /* Input filenames. */
93 struct input_filename
94 {
95 const char *name;
96 int index;
97 struct input_filename *next;
98 };
99 struct input_filename *in_files;
100 struct input_filename *last_infile;
101
102 static int num_infiles;
103
104 /* User specified output file name. */
105 const char *output_filename = NULL;
106
107 /* Output file names used for arch specific driver invocation. These
108 are input file names for 'lipo'. */
109 const char **out_files;
110 static int num_outfiles;
111
112 /* Architecture names used by config.guess does not match the names
113 used by NXGet... Use this hand coded mapping to connect them. */
114 struct arch_config_guess_map
115 {
116 const char *arch_name;
117 const char *config_string;
118 };
119
120 struct arch_config_guess_map arch_config_map [] =
121 {
122 {"i386", "i686"},
123 {"ppc", "powerpc"},
124 {"ppc64", "powerpc"},
125 {"x86_64", "i686"},
126 {"arm", "arm"},
127 {"armv4t", "arm"},
128 {"armv5", "arm"},
129 {"xscale", "arm"},
130 {"armv6", "arm"},
131 {"armv7", "arm"},
132 {NULL, NULL}
133 };
134
135 /* List of interpreted command line flags. Supply this to gcc driver. */
136 const char **new_argv;
137 int new_argc;
138
139 /* For each of the options in new_argv, specifies an architecture to
140 which the option applies (or if NULL, the option applies to all). */
141 const char **arch_conditional;
142
143 /* Argument list for 'lipo'. */
144 const char **lipo_argv;
145
146 /* Info about the sub process. Need one subprocess for each arch plus
147 additional one for 'lipo'. */
148 struct command
149 {
150 const char *prog;
151 const char **argv;
152 int pid;
153 } commands[MAX_ARCHES+1];
154
155 /* total number of argc. */
156 static int total_argc;
157
158 static int greatest_status = 0;
159 static int signal_count = 0;
160
161 #ifndef SWITCH_TAKES_ARG
162 #define SWITCH_TAKES_ARG(CHAR) DEFAULT_SWITCH_TAKES_ARG(CHAR)
163 #endif
164
165 #ifndef WORD_SWITCH_TAKES_ARG
166 #define WORD_SWITCH_TAKES_ARG(STR) DEFAULT_WORD_SWITCH_TAKES_ARG (STR)
167 #endif
168
169
170 /* Local function prototypes. */
171 static const char * get_arch_name (const char *);
172 static char * get_driver_name (const char *);
173 static void delete_out_files (void);
174 static char * strip_path_and_suffix (const char *, const char *);
175 static void initialize (void);
176 static void final_cleanup (void);
177 static int do_wait (int, const char *);
178 static void do_lipo (int, const char *);
179 static void do_compile (const char **, int);
180 static void do_compile_separately (void);
181 static void do_lipo_separately (void);
182 static int filter_args_for_arch (const char **, int, const char **,
183 const char *);
184 static int add_arch_options (int, const char **, int);
185 static int remove_arch_options (const char**, int);
186 static void add_arch (const char *);
187 static const char *resolve_symlink (const char *, char *, int, int);
188 static const char *resolve_path_to_executable (const char *filename);
189 static int get_prog_name_len (const char *prog);
190
191 /* Find arch name for the given input string. If input name is NULL then local
192 arch name is used. */
193
194 static const char *
195 get_arch_name (const char *name)
196 {
197 NXArchInfo * a_info;
198 const NXArchInfo * all_info;
199 cpu_type_t cputype;
200 struct arch_config_guess_map *map;
201 const char *aname;
202
203 if (name) {
204 /* Find config name based on arch name. */
205 aname = NULL;
206 map = arch_config_map;
207 while (map->arch_name) {
208 if (!strcmp (map->arch_name, name))
209 return name;
210 else map++;
211 }
212 a_info = (NXArchInfo *) NXGetArchInfoFromName (name);
213 } else {
214 a_info = (NXArchInfo *) NXGetLocalArchInfo();
215 if (a_info) {
216 if (dash_m32_seen) {
217 /* If -m32 is seen then do not change cpu type. */
218 } else if (dash_m64_seen) {
219 /* If -m64 is seen then enable CPU_ARCH_ABI64. */
220 a_info->cputype |= CPU_ARCH_ABI64;
221 } else if (sizeof (long) == 8)
222 /* On x86, by default (name is NULL here) enable 64 bit code. */
223 a_info->cputype |= CPU_ARCH_ABI64;
224 }
225 }
226
227 if (!a_info)
228 fatal ("Invalid arch name : %s", name);
229
230 all_info = NXGetAllArchInfos();
231
232 if (!all_info)
233 fatal ("Unable to get architecture information");
234
235 /* Find first arch. that matches cputype. */
236 cputype = a_info->cputype;
237
238 while (all_info->name)
239 {
240 if (all_info->cputype == cputype)
241 break;
242 else
243 all_info++;
244 }
245
246 return all_info->name;
247 }
248
249 /* Find driver name based on input arch name. */
250
251 static char *
252 get_driver_name (const char *arch_name)
253 {
254 char *driver_name;
255 const char *config_name;
256 int len;
257 int index;
258 struct arch_config_guess_map *map;
259
260 /* find config name based on arch name. */
261 config_name = NULL;
262 map = arch_config_map;
263 while (map->arch_name)
264 {
265 if (!strcmp (map->arch_name, arch_name))
266 {
267 config_name = map->config_string;
268 break;
269 }
270 else map++;
271 }
272
273 if (!config_name)
274 fatal ("Unable to guess config name for arch %s", arch_name);
275
276 len = strlen (config_name) + strlen (PDN) + prefix_len + 1;
277 driver_name = (char *) malloc (sizeof (char) * len);
278 driver_name[0] = '\0';
279
280 if (driver_exec_prefix)
281 strcpy (driver_name, driver_exec_prefix);
282 strcat (driver_name, config_name);
283 strcat (driver_name, PDN);
284
285 return driver_name;
286 }
287
288 /* Delete out_files. */
289
290 static void
291 delete_out_files (void)
292 {
293 const char *temp;
294 struct stat st;
295 int i = 0;
296
297 for (i = 0, temp = out_files[i];
298 temp && i < total_argc * MAX_ARCHES;
299 temp = out_files[++i])
300 if (stat (temp, &st) >= 0 && S_ISREG (st.st_mode))
301 unlink (temp);
302
303 }
304
305 /* Put fatal error message on stderr and exit. */
306
307 void
308 fatal (const char *msgid, ...)
309 {
310 va_list ap;
311
312 va_start (ap, msgid);
313
314 fprintf (stderr, "%s: ", progname);
315 vfprintf (stderr, msgid, ap);
316 va_end (ap);
317 fprintf (stderr, "\n");
318 delete_out_files ();
319 exit (1);
320 }
321
322 /* Print error message and exit. */
323
324 static void
325 pfatal_pexecute (const char *errmsg_fmt, const char *errmsg_arg)
326 {
327 if (errmsg_arg)
328 {
329 int save_errno = errno;
330
331 /* Space for trailing '\0' is in %s. */
332 char *msg = (char *) malloc (strlen (errmsg_fmt) + strlen (errmsg_arg));
333 sprintf (msg, errmsg_fmt, errmsg_arg);
334 errmsg_fmt = msg;
335
336 errno = save_errno;
337 }
338
339 fprintf (stderr,"%s: %s: %s\n", progname, errmsg_fmt, xstrerror (errno));
340 delete_out_files ();
341 exit (1);
342 }
343
344 #ifdef DEBUG
345 static void
346 debug_command_line (const char **debug_argv, int debug_argc)
347 {
348 int i;
349
350 fprintf (stderr,"%s: debug_command_line\n", progname);
351 fprintf (stderr,"%s: arg count = %d\n", progname, debug_argc);
352
353 for (i = 0; debug_argv[i]; i++)
354 fprintf (stderr,"%s: arg [%d] %s\n", progname, i, debug_argv[i]);
355 }
356 #endif
357
358 /* Strip directory name from the input file name and replace file name
359 suffix with new. */
360
361 static char *
362 strip_path_and_suffix (const char *full_name, const char *new_suffix)
363 {
364 char *name;
365 char *p;
366
367 if (!full_name || !new_suffix)
368 return NULL;
369
370 /* Strip path name. */
371 p = (char *)full_name + strlen (full_name);
372 while (p != full_name && !IS_DIR_SEPARATOR (p[-1]))
373 --p;
374
375 /* Now 'p' is a file name with suffix. */
376 name = (char *) malloc (strlen (p) + 1 + strlen (new_suffix));
377
378 strcpy (name, p);
379
380 p = name + strlen (name);
381 while (p != name && *p != '.')
382 --p;
383
384 /* If did not reach at the beginning of name then '.' is found.
385 Replace '.' with NULL. */
386 if (p != name)
387 *p = '\0';
388
389 strcat (name, new_suffix);
390 return name;
391 }
392
393 /* Initialization */
394
395 static void
396 initialize (void)
397 {
398
399 int i;
400
401 /* Let's count, how many additional arguments driver driver will supply
402 to compiler driver:
403
404 Each "-arch" "<blah>" is replaced by approriate "-mcpu=<blah>".
405 That leaves one additional arg space available.
406
407 Note that only one -m* is supplied to each compiler driver. Which
408 means, extra "-arch" "<blah>" are removed from the original command
409 line. But lets not count how many additional slots are available.
410
411 Driver driver may need to specify temp. output file name, say
412 "-o" "foobar". That needs two extra argments.
413
414 Sometimes linker wants one additional "-Wl,-arch_multiple".
415
416 Sometimes linker wants to see "-final_output" "outputname".
417
418 In the end, we may need five extra arguments, plus one extra
419 space for the NULL terminator. */
420
421 new_argv = (const char **) malloc ((total_argc + 6) * sizeof (const char *));
422 if (!new_argv)
423 abort ();
424
425 arch_conditional = (const char **) malloc ((total_argc + 6) * sizeof (const char *));
426 if (!arch_conditional)
427 abort ();
428
429 for (i = 0; i < total_argc + 6; i++)
430 arch_conditional[i] = NULL;
431
432 /* First slot, new_argv[0] is reserved for the driver name. */
433 new_argc = 1;
434
435 /* For each -arch, three arguments are needed.
436 For example, "-arch" "ppc" "file". Additional slots are for
437 "lipo" "-create" "-o" "outputfilename" and the NULL. */
438 lipo_argv = (const char **) malloc ((total_argc * 3 + 5) * sizeof (const char *));
439 if (!lipo_argv)
440 abort ();
441
442 /* Need separate out_files for each arch, max is MAX_ARCHES.
443 Need separate out_files for each input file. */
444
445 out_files = (const char **) malloc ((total_argc * MAX_ARCHES) * sizeof (const char *));
446 if (!out_files)
447 abort ();
448
449 num_arches = 0;
450 num_infiles = 0;
451
452 in_files = NULL;
453 last_infile = NULL;
454
455 for (i = 0; i < (MAX_ARCHES + 1); i++)
456 {
457 commands[i].prog = NULL;
458 commands[i].argv = NULL;
459 commands[i].pid = 0;
460 }
461 }
462
463 /* Cleanup. */
464
465 static void
466 final_cleanup (void)
467 {
468 int i;
469 struct input_filename *next;
470 delete_out_files ();
471 free (new_argv);
472 free (lipo_argv);
473 free (out_files);
474
475 for (i = 0, next = in_files;
476 i < num_infiles && next;
477 i++)
478 {
479 next = in_files->next;
480 free (in_files);
481 in_files = next;
482 }
483 }
484
485 /* Wait for the process pid and return appropriate code. */
486
487 static int
488 do_wait (int pid, const char *prog)
489 {
490 int status = 0;
491 int ret = 0;
492
493 pid = pwait (pid, &status, 0);
494
495 if (WIFSIGNALED (status))
496 {
497 if (!signal_count &&
498 WEXITSTATUS (status) > greatest_status)
499 greatest_status = WEXITSTATUS (status);
500 ret = -1;
501 }
502 else if (WIFEXITED (status)
503 && WEXITSTATUS (status) >= 1)
504 {
505 if (WEXITSTATUS (status) > greatest_status)
506 greatest_status = WEXITSTATUS (status);
507 signal_count++;
508 ret = -1;
509 }
510 return ret;
511 }
512
513 /* Invoke 'lipo' and combine and all output files. */
514
515 static void
516 do_lipo (int start_outfile_index, const char *out_file)
517 {
518 int i, j, pid;
519 char *errmsg_fmt, *errmsg_arg;
520
521 /* Populate lipo arguments. */
522 lipo_argv[0] = "lipo";
523 lipo_argv[1] = "-create";
524 lipo_argv[2] = "-o";
525 lipo_argv[3] = out_file;
526
527 /* Already 4 lipo arguments are set. Now add all lipo inputs. */
528 j = 4;
529 for (i = 0; i < num_arches; i++)
530 lipo_argv[j++] = out_files[start_outfile_index + i];
531
532 /* Add the NULL at the end. */
533 lipo_argv[j++] = NULL;
534
535 #ifdef DEBUG
536 debug_command_line (lipo_argv, j);
537 #endif
538
539 if (verbose_flag)
540 {
541 for (i = 0; lipo_argv[i]; i++)
542 fprintf (stderr, "%s ", lipo_argv[i]);
543 fprintf (stderr, "\n");
544 }
545 pid = pexecute (lipo_argv[0], (char *const *)lipo_argv, progname, NULL, &errmsg_fmt,
546 &errmsg_arg, PEXECUTE_SEARCH | PEXECUTE_ONE);
547
548 if (pid == -1)
549 pfatal_pexecute (errmsg_fmt, errmsg_arg);
550
551 do_wait (pid, lipo_argv[0]);
552 }
553
554 /* Invoke compiler for all architectures. */
555
556 static void
557 do_compile (const char **current_argv, int current_argc)
558 {
559 char *errmsg_fmt, *errmsg_arg;
560 int index = 0;
561
562 int dash_o_index = current_argc;
563 int of_index = current_argc + 1;
564 int argc_count = current_argc + 2;
565
566 const char **arch_specific_argv;
567
568 int arch_specific_argc;
569
570 while (index < num_arches)
571 {
572 int additional_arch_options = 0;
573
574 current_argv[0] = get_driver_name (get_arch_name (arches[index]));
575
576 /* setup output file. */
577 out_files[num_outfiles] = make_temp_file (".out");
578 current_argv[dash_o_index] = "-o";
579 current_argv[of_index] = out_files [num_outfiles];
580 num_outfiles++;
581
582 /* Add arch option as the last option. Do not add any other option
583 before removing this option. */
584 additional_arch_options = add_arch_options (index, current_argv, argc_count);
585 argc_count += additional_arch_options;
586
587 current_argv[argc_count] = NULL;
588
589 arch_specific_argv =
590 (const char **) malloc ((argc_count + 1) * sizeof (const char *));
591
592 arch_specific_argc = filter_args_for_arch (current_argv,
593 argc_count,
594 arch_specific_argv,
595 get_arch_name (arches[index]));
596
597 commands[index].prog = arch_specific_argv[0];
598 commands[index].argv = arch_specific_argv;
599
600 #ifdef DEBUG
601 debug_command_line (arch_specific_argv, arch_specific_argc);
602 #endif
603 commands[index].pid = pexecute (arch_specific_argv[0],
604 (char *const *)arch_specific_argv,
605 progname, NULL,
606 &errmsg_fmt,
607 &errmsg_arg,
608 PEXECUTE_SEARCH | PEXECUTE_ONE);
609
610 if (commands[index].pid == -1)
611 pfatal_pexecute (errmsg_fmt, errmsg_arg);
612
613 do_wait (commands[index].pid, commands[index].prog);
614 fflush (stdout);
615
616 /* Remove the last arch option added in the current_argv list. */
617 if (additional_arch_options)
618 argc_count -= remove_arch_options (current_argv, argc_count);
619 index++;
620 free (arch_specific_argv);
621 }
622 }
623
624 /* Invoke compiler for each input file separately.
625 Construct command line for each invocation with one input file. */
626
627 static void
628 do_compile_separately (void)
629 {
630 const char **new_new_argv;
631 int i, new_new_argc;
632 struct input_filename *current_ifn;
633
634 if (num_infiles == 1 || ima_is_used)
635 abort ();
636
637 /* Total number of arguments in separate compiler invocation is :
638 total number of original arguments - total no input files + one input
639 file + "-o" + output file + arch specific options + NULL . */
640 new_new_argv = (const char **) malloc ((new_argc - num_infiles + 5) * sizeof (const char *));
641 if (!new_new_argv)
642 abort ();
643
644 for (current_ifn = in_files; current_ifn && current_ifn->name;
645 current_ifn = current_ifn->next)
646 {
647 struct input_filename *ifn = in_files;
648 int go_back = 0;
649 new_new_argc = 1;
650 bool ifn_found = false;
651
652 for (i = 1; i < new_argc; i++)
653 {
654 if (ifn && ifn->name && !strcmp (new_argv[i], ifn->name))
655 {
656 /* This argument is one of the input file. */
657
658 if (!strcmp (new_argv[i], current_ifn->name))
659 {
660 if (ifn_found)
661 fatal ("file %s specified more than once on the command line", current_ifn->name);
662
663 /* If it is current input file name then add it in the new
664 list. */
665 new_new_argv[new_new_argc] = new_argv[i];
666 arch_conditional[new_new_argc] = arch_conditional[i];
667 new_new_argc++;
668 ifn_found = true;
669 }
670 /* This input file can not appear in
671 again on the command line so next time look for next input
672 file. */
673 ifn = ifn->next;
674 }
675 else
676 {
677 /* This argument is not a input file name. Add it into new
678 list. */
679 new_new_argv[new_new_argc] = new_argv[i];
680 arch_conditional[new_new_argc] = arch_conditional[i];
681 new_new_argc++;
682 }
683 }
684
685 /* OK now we have only one input file and all other arguments. */
686 do_compile (new_new_argv, new_new_argc);
687 }
688 }
689
690 /* Invoke 'lipo' on set of output files and create multile FAT binaries. */
691
692 static void
693 do_lipo_separately (void)
694 {
695 int ifn_index;
696 struct input_filename *ifn;
697 for (ifn_index = 0, ifn = in_files;
698 ifn_index < num_infiles && ifn && ifn->name;
699 ifn_index++, ifn = ifn->next)
700 do_lipo (ifn_index * num_arches,
701 strip_path_and_suffix (ifn->name, ".o"));
702 }
703
704 /* Remove all options which are architecture-specific and are not for the
705 current architecture (arch). */
706 static int
707 filter_args_for_arch (const char **orig_argv, int orig_argc,
708 const char **new_argv, const char *arch)
709 {
710 int new_argc = 0;
711 int i;
712
713 for (i = 0; i < orig_argc; i++)
714 if (arch_conditional[i] == NULL
715 || *arch_conditional[i] == '\0'
716 || ! strcmp (arch_conditional[i], arch))
717 new_argv[new_argc++] = orig_argv[i];
718
719 new_argv[new_argc] = NULL;
720
721 return new_argc;
722 }
723
724 /* Replace -arch <blah> options with appropriate "-mcpu=<blah>" OR
725 "-march=<blah>". INDEX is the index in arches[] table. We cannot
726 return more than 1 as do_compile_separately only allocated one
727 extra slot for us. */
728
729 static int
730 add_arch_options (int index, const char **current_argv, int arch_index)
731 {
732 int count;
733
734 /* We are adding 1 argument for selected arches. */
735 count = 1;
736
737 #ifdef DEBUG
738 fprintf (stderr, "%s: add_arch_options: %s\n", progname, arches[index]);
739 #endif
740
741 if (!strcmp (arches[index], "ppc601"))
742 current_argv[arch_index] = "-mcpu=601";
743 else if (!strcmp (arches[index], "ppc603"))
744 current_argv[arch_index] = "-mcpu=603";
745 else if (!strcmp (arches[index], "ppc604"))
746 current_argv[arch_index] = "-mcpu=604";
747 else if (!strcmp (arches[index], "ppc604e"))
748 current_argv[arch_index] = "-mcpu=604e";
749 else if (!strcmp (arches[index], "ppc750"))
750 current_argv[arch_index] = "-mcpu=750";
751 else if (!strcmp (arches[index], "ppc7400"))
752 current_argv[arch_index] = "-mcpu=7400";
753 else if (!strcmp (arches[index], "ppc7450"))
754 current_argv[arch_index] = "-mcpu=7450";
755 else if (!strcmp (arches[index], "ppc970"))
756 current_argv[arch_index] = "-mcpu=970";
757 else if (!strcmp (arches[index], "ppc64"))
758 current_argv[arch_index] = "-m64";
759 else if (!strcmp (arches[index], "i486"))
760 current_argv[arch_index] = "-march=i486";
761 else if (!strcmp (arches[index], "i586"))
762 current_argv[arch_index] = "-march=i586";
763 else if (!strcmp (arches[index], "i686"))
764 current_argv[arch_index] = "-march=i686";
765 else if (!strcmp (arches[index], "pentium"))
766 current_argv[arch_index] = "-march=pentium";
767 else if (!strcmp (arches[index], "pentium2"))
768 current_argv[arch_index] = "-march=pentium2";
769 else if (!strcmp (arches[index], "pentpro"))
770 current_argv[arch_index] = "-march=pentiumpro";
771 else if (!strcmp (arches[index], "pentIIm3"))
772 current_argv[arch_index] = "-march=pentium2";
773 else if (!strcmp (arches[index], "x86_64"))
774 current_argv[arch_index] = "-m64";
775 else if (!strcmp (arches[index], "arm"))
776 current_argv[arch_index] = "-march=armv4t";
777 else if (!strcmp (arches[index], "armv4t"))
778 current_argv[arch_index] = "-march=armv4t";
779 else if (!strcmp (arches[index], "armv5"))
780 current_argv[arch_index] = "-march=armv5tej";
781 else if (!strcmp (arches[index], "xscale"))
782 current_argv[arch_index] = "-march=xscale";
783 else if (!strcmp (arches[index], "armv6"))
784 current_argv[arch_index] = "-march=armv6k";
785 else if (!strcmp (arches[index], "armv7"))
786 current_argv[arch_index] = "-march=armv7a";
787 else
788 count = 0;
789
790 return count;
791 }
792
793 /* Remove the last option, which is arch option, added by
794 add_arch_options. Return how count of arguments removed. */
795 static int
796 remove_arch_options (const char **current_argv, int arch_index)
797 {
798 #ifdef DEBUG
799 fprintf (stderr, "%s: Removing argument no %d\n", progname, arch_index);
800 #endif
801
802 current_argv[arch_index] = '\0';
803
804 #ifdef DEBUG
805 debug_command_line (current_argv, arch_index);
806 #endif
807
808 return 1;
809 }
810
811 /* Add new arch request. */
812 void
813 add_arch (const char *new_arch)
814 {
815 int i;
816
817 /* User can say cc -arch ppc -arch ppc foo.c
818 Do not invoke ppc compiler twice in this case. */
819 for (i = 0; i < num_arches; i++)
820 {
821 if (!strcmp (arches[i], new_arch))
822 return;
823 }
824
825 arches[num_arches] = new_arch;
826 num_arches++;
827 }
828
829 /* Rewrite the command line as requested in the QA_OVERRIDE_GCC3_OPTIONS
830 environment variable -- used for testing the compiler, working around bugs
831 in the Apple build environment, etc.
832
833 The override string is made up of a set of space-separated clauses. The
834 first letter of each clause describes what's to be done:
835 +string Add string as a new argument (at the end of the command line).
836 Multi-word command lines can be added with +x +y
837 s/x/y/ substitute x for y in the command line. X must be an entire
838 argument, and can be a regular expression as accepted by the
839 POSIX regexp code. Y will be substituted as a single argument,
840 and will not have regexp replacements added in.
841 xoption Removes argument matching option
842 Xoption Removes argument matching option and following word
843 Ox Removes any optimization flags in command line and replaces
844 with -Ox.
845
846
847 Here's some examples:
848 O2
849 s/precomp-trustfile=foo//
850 +-fexplore-antartica
851 +-fast
852 s/-fsetvalue=* //
853 x-fwritable-strings
854 s/-O[0-2]/-Osize/
855 x-v
856 X-o +-o +foo.o
857
858 Option substitutions are processed from left to right; matches and changes
859 are cumulative. An error in processing one element (such as trying to
860 remove an element and successor when the match is at the end) cause the
861 particular change to stop, but additional changes in the environment
862 variable to be applied.
863
864 Key details:
865 * we always want to be able to adjust optimization levels for testing
866 * adding options is a common task
867 * substitution and deletion are less common.
868
869 If the first character of the environment variable is #, changes are
870 silent. If not, diagnostics are written to stderr explaining what
871 changes are being performed.
872
873 */
874
875 char **arg_array;
876 int arg_array_size=0;
877 int arg_count = 0;
878 int confirm_changes = 1;
879 const int ARG_ARRAY_INCREMENT_SIZE = 8;
880 #define FALSE 0
881
882 /* Routines for the argument array. The argument array routines are
883 responsible for allocation and deallocation of all objects in the
884 array */
885
886 void read_args (int argc, char **argv)
887 {
888 int i;
889
890 arg_array_size = argc+10;
891 arg_count = argc;
892 arg_array = (char**) malloc(sizeof(char*)*arg_array_size);
893
894 for (i=0;i<argc;i++) {
895 arg_array[i] = malloc (strlen (argv[i])+1);
896 strcpy (arg_array[i], argv[i]);
897 }
898 }
899
900 /* Insert the argument before pos. */
901 void insert_arg(int pos, char *arg_to_insert)
902 {
903 int i;
904 char *newArg = malloc (strlen (arg_to_insert)+1);
905 strcpy(newArg, arg_to_insert);
906
907 if (arg_count == arg_array_size) {
908 /* expand array */
909 arg_array_size = arg_count + ARG_ARRAY_INCREMENT_SIZE;
910 arg_array = (char**) realloc (arg_array, arg_array_size);
911 }
912
913 for (i = arg_count; i > pos; i--) {
914 arg_array[i+1] = arg_array[i];
915 }
916
917 arg_array[pos] = newArg;
918 arg_count++;
919
920 if (confirm_changes)
921 fprintf(stderr,"### Adding argument %s at position %d\n",arg_to_insert, pos);
922 }
923
924
925 void replace_arg (char *str, int pos) {
926 char *newArg = malloc(strlen(str)+1);
927 strcpy(newArg,str);
928
929 if (confirm_changes)
930 fprintf (stderr,"### Replacing %s with %s\n",arg_array[pos], str);
931
932 free (arg_array[pos]);
933 arg_array[pos] = newArg;
934 }
935
936 void append_arg (char *str)
937 {
938 char *new_arg = malloc (strlen (str)+1);
939 strcpy (new_arg, str);
940 if (confirm_changes)
941 fprintf(stderr,"### Adding argument %s at end\n", str);
942
943 if (arg_count == arg_array_size) {
944 /* expand array */
945 arg_array_size = arg_count + ARG_ARRAY_INCREMENT_SIZE;
946 arg_array = (char**) realloc (arg_array, arg_array_size);
947 }
948
949 arg_array[arg_count++] = new_arg;
950 }
951
952 void delete_arg(int pos) {
953 int i;
954
955 if (confirm_changes)
956 fprintf(stderr,"### Deleting argument %s\n",arg_array[pos]);
957
958 free (arg_array[pos]);
959
960 for (i=pos; i < arg_count; i++)
961 arg_array[i] = arg_array[i+1];
962
963 arg_count--;
964 }
965
966 /* Changing optimization levels is a common testing pattern --
967 we've got a special option that searches for and replaces anything
968 beginning with -O */
969 void replace_optimization_level (char *new_level) {
970 int i;
971 int optionFound = 0;
972 char *new_opt = malloc(strlen(new_opt)+3);
973 sprintf(new_opt, "-O%s",new_level);
974
975
976 for (i=0;i<arg_count;i++) {
977 if (strncmp(arg_array[i],"-O",2) == 0) {
978 replace_arg (new_opt, i);
979 optionFound = 1;
980 break;
981 }
982 }
983
984 if (optionFound == 0)
985 /* No optimization level? Add it! */
986 append_arg (new_opt);
987
988 free (new_opt);
989 }
990
991 /* Returns a NULL terminated string holding whatever was in the original
992 string at that point. This must be freed by the caller. */
993
994 char *arg_string(char *str, int begin, int len) {
995 char *new_str = malloc(len+1);
996 strncpy(new_str,&str[begin],len);
997 new_str[len] = '\0';
998 return new_str;
999 }
1000
1001 /* Given a search-and-replace string of the form
1002 s/x/y/
1003
1004 do search and replace on the arg list. Make sure to check that the
1005 string is sane -- that it has all the proper slashes that are necessary.
1006 The search string can be a regular expression, but the replace string
1007 must be a literal; the search must also be for a full argument, not for
1008 a chain of arguments. The result will be treated as a single argument.
1009
1010 Return true if success, false if bad failure.
1011 */
1012
1013 bool search_and_replace (char *str) {
1014 regex_t regexp_search_struct;
1015 int searchLen;
1016 int replaceLen;
1017 int i;
1018 int err;
1019
1020 char *searchStr;
1021 char *replaceStr;
1022 char *replacedStr;
1023 const int ERRSIZ = 512;
1024 char errbuf[ERRSIZ];
1025
1026
1027 if (str[0] != '/') {
1028 return false;
1029 }
1030
1031 searchLen = strcspn (str + 1, "/\0");
1032
1033 if (str[1 + searchLen] != '/')
1034 return false;
1035
1036 replaceLen = strcspn(str+1+searchLen+1, "/\0");
1037
1038 if (str[1 + searchLen + 1 +replaceLen] != '/')
1039 return false;
1040
1041 searchStr = arg_string(str, 1, searchLen);
1042 replaceStr = arg_string (str, 1 + searchLen + 1, replaceLen);
1043
1044 if ((err = regcomp(&regexp_search_struct, searchStr, REG_EXTENDED)) != 0) {
1045 regerror(err, &regexp_search_struct, errbuf, ERRSIZ);
1046 fprintf(stderr,"%s",errbuf);
1047 return false;
1048 }
1049
1050 for (i=0;i<arg_count;i++) {
1051 regmatch_t matches[5];
1052 if (regexec (&regexp_search_struct, arg_array[i],
1053 5, matches, 0) == 0) {
1054 if ((matches[0].rm_eo - matches[0].rm_so) == strlen (arg_array[i])) {
1055 /* Success! Change the string. */
1056 replace_arg(replaceStr,i);
1057 break;
1058 }
1059 }
1060 }
1061
1062 regfree (&regexp_search_struct);
1063 free (searchStr);
1064 free (replaceStr);
1065
1066 return true;
1067 }
1068
1069
1070 /* Given a string, return the argument number where the first match occurs. */
1071 int find_arg (char *str) {
1072 int i;
1073 int matchIndex = -1;
1074
1075 for (i=0;i<arg_count;i++) {
1076 if (strcmp(arg_array[i],str) == 0) {
1077 matchIndex = i;
1078 break;
1079 }
1080 }
1081
1082 return matchIndex;
1083 }
1084
1085 void rewrite_command_line (char *override_options_line, int *argc, char ***argv){
1086 int line_pos = 0;
1087
1088 read_args (*argc, *argv);
1089
1090 if (override_options_line[0] == '#')
1091 {
1092 confirm_changes = 0;
1093 line_pos++;
1094 }
1095
1096
1097 if (confirm_changes)
1098 fprintf (stderr, "### QA_OVERRIDE_GCC3_OPTIONS: %s\n",
1099 override_options_line);
1100
1101 /* Loop through all commands in the file */
1102
1103 while (override_options_line[line_pos] != '\0')
1104 {
1105 char first_char;
1106 char *searchStr;
1107 char *arg;
1108 int search_index;
1109 int arg_len;
1110
1111 /* Any spaces in between options don't count. */
1112 if (override_options_line[line_pos] == ' ')
1113 {
1114 line_pos++;
1115 continue;
1116 }
1117
1118 /* The first non-space character is the command. */
1119 first_char = override_options_line[line_pos];
1120 line_pos++;
1121 arg_len = strcspn(override_options_line+line_pos, " ");
1122
1123 switch (first_char) {
1124 case '+':
1125 /* Add an argument to the end of the arg list */
1126 arg = arg_string (override_options_line,
1127 line_pos,
1128 arg_len);
1129 append_arg (arg);
1130 free (arg);
1131 break;
1132
1133 case 'x':
1134 /* Delete a matching argument */
1135 searchStr = arg_string(override_options_line, line_pos, arg_len);
1136 if ((search_index = find_arg(searchStr)) != -1) {
1137 delete_arg(search_index);
1138 }
1139 free (searchStr);
1140 break;
1141
1142 case 'X':
1143 /* Delete a matching argument and the argument following. */
1144 searchStr = arg_string(override_options_line, line_pos, arg_len);
1145 if ((search_index = find_arg(searchStr)) != -1) {
1146 if (search_index >= arg_count -1) {
1147 if (confirm_changes)
1148 fprintf(stderr,"Not enough arguments to do X\n");
1149 } else {
1150 delete_arg(search_index); /* Delete the matching argument */
1151 delete_arg(search_index); /* Delete the following argument */
1152 }
1153 }
1154 free (searchStr);
1155 break;
1156
1157 case 'O':
1158 /* Change the optimization level to the specified value, and
1159 remove any optimization arguments. This is a separate command
1160 because we often want is to substitute our favorite
1161 optimization level for whatever the project normally wants.
1162 As we probably care about this a lot (for things like
1163 testing file sizes at different optimization levels) we
1164 make a special rewrite clause. */
1165 arg = arg_string (override_options_line, line_pos, arg_len);
1166 replace_optimization_level(arg);
1167 free (arg);
1168 break;
1169 case 's':
1170 /* Search for the regexp passed in, and replace a matching argument
1171 with the provided replacement string */
1172 searchStr = arg_string (override_options_line, line_pos, arg_len);
1173 search_and_replace (searchStr);
1174 free (searchStr);
1175 break;
1176
1177 default:
1178 fprintf(stderr,"### QA_OVERRIDE_GCC3_OPTIONS: invalid string (pos %d)\n",
1179 line_pos);
1180 break;
1181 }
1182 line_pos += arg_len;
1183 }
1184 *argc = arg_count;
1185 *argv = arg_array;
1186 }
1187
1188 /* Given a path to a file, potentially containing a directory name, return the
1189 number of characters at the end of the path that make up the filename part of
1190 the path. */
1191
1192 static int
1193 get_prog_name_len (const char *prog)
1194 {
1195 int result = 0;
1196 const char *progend = prog + strlen(prog);
1197 const char *progname = progend;
1198 while (progname != prog && !IS_DIR_SEPARATOR (progname[-1]))
1199 --progname;
1200 return progend-progname;
1201 }
1202
1203 /* Return true iff the path is an executable file and not a directory. */
1204
1205 static bool
1206 is_x_file (const char *path)
1207 {
1208 struct stat st;
1209 if (access (path, X_OK))
1210 return false;
1211 if (stat (path, &st) == -1)
1212 return false;
1213 if (S_ISDIR (st.st_mode))
1214 return false;
1215 return true;
1216 }
1217
1218 /* Given a FILENAME of an executable (for example "gcc") search the PATH
1219 environment variable to find out which directory it is in and return a fully
1220 qualified path to the executable.
1221 */
1222
1223 static const char *
1224 resolve_path_to_executable (const char *filename)
1225 {
1226 char path_buffer[2*PATH_MAX+1];
1227 char *PATH = getenv ("PATH");
1228 if (PATH == 0) return filename; /* PATH not set */
1229
1230 do {
1231 unsigned prefix_size;
1232 struct stat st;
1233 char *colon = strchr (PATH, ':');
1234
1235 /* If we didn't find a :, use the whole last chunk. */
1236 prefix_size = colon ? colon-PATH : strlen (PATH);
1237
1238 /* Form the full path. */
1239 memcpy (path_buffer, PATH, prefix_size);
1240 path_buffer[prefix_size] = '/';
1241 strcpy (path_buffer+prefix_size+1, filename);
1242
1243 /* Check to see if this file is executable, if so, return it. */
1244 if (is_x_file (path_buffer))
1245 return strdup (path_buffer);
1246 PATH = colon ? colon+1 : PATH+prefix_size;
1247 } while (PATH[0]);
1248
1249 return filename;
1250 }
1251
1252 /* If prog is a symlink, we want to rewrite prog to an absolute location,
1253 symlink_buffer contains the destination of the symlink. Glue these pieces
1254 together to form an absolute path. */
1255
1256 static const char *
1257 resolve_symlink (const char *prog, char *symlink_buffer,
1258 int argv_0_len, int prog_len)
1259 {
1260 /* If the link isn't to an absolute path, prefix it with the argv[0]
1261 directory. */
1262 if (!IS_ABSOLUTE_PATH (symlink_buffer))
1263 {
1264 int prefix_len = argv_0_len - prog_len;
1265 memmove (symlink_buffer+prefix_len, symlink_buffer,
1266 PATH_MAX-prefix_len+1);
1267 memcpy (symlink_buffer, prog, prefix_len);
1268 }
1269 return strdup(symlink_buffer);
1270 }
1271
1272 /* Main entry point. This is gcc driver driver!
1273 Interpret -arch flag from the list of input arguments. Invoke appropriate
1274 compiler driver. 'lipo' the results if more than one -arch is supplied. */
1275 int
1276 main (int argc, const char **argv)
1277 {
1278 size_t i;
1279 int l, pid, argv_0_len, prog_len;
1280 char *errmsg_fmt, *errmsg_arg;
1281 char *override_option_str = NULL;
1282 char path_buffer[2*PATH_MAX+1];
1283 int linklen;
1284
1285 total_argc = argc;
1286 prog_len = 0;
1287
1288 argv_0_len = strlen (argv[0]);
1289
1290 /* Get the progname, required by pexecute () and program location. */
1291 prog_len = get_prog_name_len (argv[0]);
1292
1293 /* If argv[0] is all program name (no slashes), search the PATH environment
1294 variable to get the fully resolved path to the executable. */
1295 if (prog_len == argv_0_len)
1296 {
1297 #ifdef DEBUG
1298 progname = argv[0] + argv_0_len - prog_len;
1299 fprintf (stderr,"%s: before PATH resolution, full progname = %s\n",
1300 argv[0]+argv_0_len-prog_len, argv[0]);
1301 #endif
1302 argv[0] = resolve_path_to_executable (argv[0]);
1303 prog_len = get_prog_name_len (argv[0]);
1304 argv_0_len = strlen(argv[0]);
1305 }
1306
1307 /* If argv[0] is a symbolic link, use the directory of the pointed-to file
1308 to find compiler components. */
1309 /* LLVM LOCAL: loop to follow multiple levels of links */
1310 while ((linklen = readlink (argv[0], path_buffer, PATH_MAX)) != -1)
1311 {
1312 /* readlink succeeds if argv[0] is a symlink. path_buffer now contains
1313 the file referenced. */
1314 path_buffer[linklen] = '\0';
1315 #ifdef DEBUG
1316 progname = argv[0] + argv_0_len - prog_len;
1317 fprintf (stderr, "%s: before symlink, full prog = %s target = %s\n",
1318 progname, argv[0], path_buffer);
1319 #endif
1320 argv[0] = resolve_symlink(argv[0], path_buffer, argv_0_len, prog_len);
1321 argv_0_len = strlen(argv[0]);
1322
1323 /* Get the progname, required by pexecute () and program location. */
1324 prog_len = get_prog_name_len (argv[0]);
1325
1326 #ifdef DEBUG
1327 progname = argv[0] + argv_0_len - prog_len;
1328 printf("%s: ARGV[0] after symlink = %s\n", progname, argv[0]);
1329 #endif
1330 }
1331
1332 progname = argv[0] + argv_0_len - prog_len;
1333
1334 /* Setup driver prefix. */
1335 prefix_len = argv_0_len - prog_len;
1336 curr_dir = (char *) malloc (sizeof (char) * (prefix_len + 1));
1337 strncpy (curr_dir, argv[0], prefix_len);
1338 curr_dir[prefix_len] = '\0';
1339 driver_exec_prefix = (argv[0], "/usr/bin", curr_dir);
1340
1341 #ifdef DEBUG
1342 fprintf (stderr,"%s: full progname = %s\n", progname, argv[0]);
1343 fprintf (stderr,"%s: progname = %s\n", progname, progname);
1344 fprintf (stderr,"%s: driver_exec_prefix = %s\n", progname, driver_exec_prefix);
1345 #endif
1346
1347 /* Before we get too far, rewrite the command line with any requested overrides */
1348 if ((override_option_str = getenv ("QA_OVERRIDE_GCC3_OPTIONS")) != NULL)
1349 rewrite_command_line(override_option_str, &argc, (char***)&argv);
1350
1351
1352
1353 initialize ();
1354
1355 /* Process arguments. Take appropriate actions when
1356 -arch, -c, -S, -E, -o is encountered. Find input file name. */
1357 for (i = 1; i < argc; i++)
1358 {
1359 if (!strcmp (argv[i], "-arch"))
1360 {
1361 if (i + 1 >= argc)
1362 abort ();
1363
1364 add_arch (argv[i+1]);
1365 i++;
1366 }
1367 else if (!strcmp (argv[i], "-c"))
1368 {
1369 new_argv[new_argc++] = argv[i];
1370 compile_only_request = 1;
1371 }
1372 else if (!strcmp (argv[i], "-S"))
1373 {
1374 new_argv[new_argc++] = argv[i];
1375 asm_output_request = 1;
1376 }
1377 else if (!strcmp (argv[i], "-E"))
1378 {
1379 new_argv[new_argc++] = argv[i];
1380 preprocessed_output_request = 1;
1381 }
1382 else if (!strcmp (argv[i], "-MD") || !strcmp (argv[i], "-MMD"))
1383 {
1384 new_argv[new_argc++] = argv[i];
1385 dash_capital_m_seen = 1;
1386 }
1387 else if (!strcmp (argv[i], "-m32"))
1388 {
1389 new_argv[new_argc++] = argv[i];
1390 dash_m32_seen = 1;
1391 }
1392 else if (!strcmp (argv[i], "-m64"))
1393 {
1394 new_argv[new_argc++] = argv[i];
1395 dash_m64_seen = 1;
1396 }
1397 else if (!strcmp (argv[i], "-dynamiclib"))
1398 {
1399 new_argv[new_argc++] = argv[i];
1400 dash_dynamiclib_seen = 1;
1401 }
1402 else if (!strcmp (argv[i], "-v"))
1403 {
1404 new_argv[new_argc++] = argv[i];
1405 verbose_flag = 1;
1406 }
1407 else if (!strcmp (argv[i], "-o"))
1408 {
1409 if (i + 1 >= argc)
1410 fatal ("argument to '-o' is missing");
1411
1412 output_filename = argv[i+1];
1413 i++;
1414 }
1415 else if ((! strcmp (argv[i], "-pass-exit-codes"))
1416 || (! strcmp (argv[i], "-print-search-dirs"))
1417 || (! strcmp (argv[i], "-print-libgcc-file-name"))
1418 || (! strncmp (argv[i], "-print-file-name=", 17))
1419 || (! strncmp (argv[i], "-print-prog-name=", 17))
1420 || (! strcmp (argv[i], "-print-multi-lib"))
1421 || (! strcmp (argv[i], "-print-multi-directory"))
1422 || (! strcmp (argv[i], "-print-multi-os-directory"))
1423 || (! strcmp (argv[i], "-ftarget-help"))
1424 || (! strcmp (argv[i], "-fhelp"))
1425 || (! strcmp (argv[i], "+e"))
1426 || (! strncmp (argv[i], "-Wa,",4))
1427 || (! strncmp (argv[i], "-Wp,",4))
1428 || (! strncmp (argv[i], "-Wl,",4))
1429 || (! strncmp (argv[i], "-l", 2))
1430 || (! strncmp (argv[i], "-weak-l", 7))
1431 || (! strncmp (argv[i], "-specs=", 7))
1432 || (! strcmp (argv[i], "-ObjC"))
1433 || (! strcmp (argv[i], "-fobjC"))
1434 || (! strcmp (argv[i], "-ObjC++"))
1435 || (! strcmp (argv[i], "-time"))
1436 || (! strcmp (argv[i], "-###"))
1437 || (! strcmp (argv[i], "-fconstant-cfstrings"))
1438 || (! strcmp (argv[i], "-fno-constant-cfstrings"))
1439 || (! strcmp (argv[i], "-static-libgcc"))
1440 || (! strcmp (argv[i], "-shared-libgcc"))
1441 || (! strcmp (argv[i], "-pipe"))
1442 )
1443 {
1444 new_argv[new_argc++] = argv[i];
1445 }
1446 else if (! strcmp (argv[i], "-save-temps")
1447 || ! strcmp (argv[i], "--save-temps"))
1448 {
1449 new_argv[new_argc++] = argv[i];
1450 save_temps_seen = 1;
1451 }
1452 else if ((! strcmp (argv[i], "-Xlinker"))
1453 || (! strcmp (argv[i], "-Xassembler"))
1454 || (! strcmp (argv[i], "-Xpreprocessor"))
1455 || (! strcmp (argv[i], "-l"))
1456 || (! strcmp (argv[i], "-weak_library"))
1457 || (! strcmp (argv[i], "-weak_framework"))
1458 || (! strcmp (argv[i], "-specs"))
1459 || (! strcmp (argv[i], "-framework"))
1460 )
1461 {
1462 new_argv[new_argc++] = argv[i];
1463 i++;
1464 new_argv[new_argc++] = argv[i];
1465 }
1466 else if (! strncmp (argv[i], "-Xarch_", 7))
1467 {
1468 arch_conditional[new_argc] = get_arch_name (argv[i] + 7);
1469 i++;
1470 new_argv[new_argc++] = argv[i];
1471 }
1472 else if (argv[i][0] == '-' && argv[i][1] != 0)
1473 {
1474 const char *p = &argv[i][1];
1475 int c = *p;
1476
1477 /* First copy this flag itself. */
1478 new_argv[new_argc++] = argv[i];
1479
1480 if (argv[i][1] == 'M')
1481 dash_capital_m_seen = 1;
1482
1483 /* Now copy this flag's arguments, if any, appropriately. */
1484 if ((SWITCH_TAKES_ARG (c) > (p[1] != 0))
1485 || WORD_SWITCH_TAKES_ARG (p))
1486 {
1487 int j = 0;
1488 int n_args = WORD_SWITCH_TAKES_ARG (p);
1489 if (n_args == 0)
1490 {
1491 /* Count only the option arguments in separate argv elements. */
1492 n_args = SWITCH_TAKES_ARG (c) - (p[1] != 0);
1493 }
1494 if (i + n_args >= argc)
1495 fatal ("argument to `-%s' is missing", p);
1496
1497
1498 while ( j < n_args)
1499 {
1500 i++;
1501 new_argv[new_argc++] = argv[i];
1502 j++;
1503 }
1504 }
1505
1506 }
1507 else
1508 {
1509 struct input_filename *ifn;
1510 new_argv[new_argc++] = argv[i];
1511 ifn = (struct input_filename *) malloc (sizeof (struct input_filename));
1512 ifn->name = argv[i];
1513 ifn->index = i;
1514 ifn->next = NULL;
1515 num_infiles++;
1516
1517 if (last_infile)
1518 last_infile->next = ifn;
1519 else
1520 in_files = ifn;
1521
1522 last_infile = ifn;
1523 }
1524 }
1525
1526 #if 0
1527 if (num_infiles == 0)
1528 fatal ("no input files");
1529 #endif
1530
1531 if (num_arches == 0)
1532 add_arch(get_arch_name(NULL));
1533
1534 if (num_arches > 1)
1535 {
1536 if (preprocessed_output_request
1537 || save_temps_seen
1538 || asm_output_request
1539 || dash_capital_m_seen)
1540 fatal ("-E, -S, -save-temps and -M options are not allowed with multiple -arch flags");
1541 }
1542 /* If -arch is not present OR Only one -arch <blah> is specified.
1543 Invoke appropriate compiler driver. FAT build is not required in this
1544 case. */
1545
1546 if (num_arches == 1)
1547 {
1548 int arch_specific_argc;
1549 const char **arch_specific_argv;
1550
1551 /* Find compiler driver based on -arch <foo> and add approriate
1552 -m* argument. */
1553 new_argv[0] = get_driver_name (get_arch_name (arches[0]));
1554 new_argc = new_argc + add_arch_options (0, new_argv, new_argc);
1555
1556 #ifdef DEBUG
1557 printf ("%s: invoking single driver name = %s\n", progname, new_argv[0]);
1558 #endif
1559
1560 /* Re insert output file name. */
1561 if (output_filename)
1562 {
1563 new_argv[new_argc++] = "-o";
1564 new_argv[new_argc++] = output_filename;
1565 }
1566
1567 /* Add the NULL. */
1568 new_argv[new_argc] = NULL;
1569
1570 arch_specific_argv =
1571 (const char **) malloc ((new_argc + 1) * sizeof (const char *));
1572 arch_specific_argc = filter_args_for_arch (new_argv,
1573 new_argc,
1574 arch_specific_argv,
1575 get_arch_name (arches[0]));
1576
1577 #ifdef DEBUG
1578 debug_command_line (arch_specific_argv, arch_specific_argc);
1579 #endif
1580
1581 pid = pexecute (arch_specific_argv[0], (char *const *)arch_specific_argv,
1582 progname, NULL, &errmsg_fmt, &errmsg_arg,
1583 PEXECUTE_SEARCH | PEXECUTE_ONE);
1584
1585 if (pid == -1)
1586 pfatal_pexecute (errmsg_fmt, errmsg_arg);
1587
1588 do_wait (pid, arch_specific_argv[0]);
1589 }
1590 else
1591 {
1592 /* Handle multiple -arch <blah>. */
1593
1594 /* If more than one input files are supplied but only one output filename
1595 is present then IMA will be used. */
1596 if (num_infiles > 1 && !compile_only_request)
1597 ima_is_used = 1;
1598
1599 /* The compiler and linker both want to know if we have multiple archs.
1600 The compiler for debug info emission and the linker for augmenting
1601 error and warning messages. */
1602 new_argv[new_argc++] = "-arch_multiple";
1603
1604
1605 /* If only one input file is specified OR IMA is used then expected output
1606 is one FAT binary. */
1607 if (num_infiles == 1 || ima_is_used)
1608 {
1609 const char *out_file;
1610
1611 /* Create output file name based on
1612 input filename, if required. */
1613 if (compile_only_request && !output_filename && num_infiles == 1)
1614 out_file = strip_path_and_suffix (in_files->name, ".o");
1615 else
1616 out_file = (output_filename ? output_filename : final_output);
1617
1618
1619 /* Linker wants to know name of output file using one extra arg. */
1620 if (!compile_only_request)
1621 {
1622 char *oname = (char *)(output_filename ? output_filename : final_output);
1623 char *n = malloc (sizeof (char) * (strlen (oname) + 5));
1624 strcpy (n, "-Wl,");
1625 strcat (n, oname);
1626 new_argv[new_argc++] = "-Wl,-final_output";
1627 new_argv[new_argc++] = n;
1628 }
1629
1630 /* Compile file(s) for each arch and lipo 'em together. */
1631 do_compile (new_argv, new_argc);
1632
1633 /* Make FAT binary by combining individual output files for each
1634 architecture, using 'lipo'. */
1635 do_lipo (0, out_file);
1636 }
1637 else
1638 {
1639 /* Multiple input files are present and IMA is not used.
1640 Which means need to generate multiple FAT files. */
1641 do_compile_separately ();
1642 do_lipo_separately ();
1643 }
1644 }
1645
1646 final_cleanup ();
1647 free (curr_dir);
1648 return greatest_status;
1649 }

llvm-admin@cs.uiuc.edu
ViewVC Help
Powered by ViewVC 1.1.5