1 /* APPLE LOCAL file driver driver */
3 /* Darwin driver program that handles -arch commands and invokes
4 appropriate compiler driver.
5 Copyright (C) 2004, 2005 Free Software Foundation, Inc.
7 This file is part of GCC.
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
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
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
30 #include <mach-o/arch.h>
32 #include <sys/types.h>
36 #include "libiberty.h"
37 #include "filenames.h"
40 Pay the price for including darwin.h. */
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. */
50 /* Include gcc.h for DEFAULT_SWITCH_TAKES_ARG and
51 DEFAULT_WORD_SWIATCH_TAKES_ARG. */
55 /* This program name. */
59 const char *driver_exec_prefix
;
61 /* driver prefix length. */
64 /* current working directory. */
67 /* Use if -o flag is absent. */
68 const char *final_output
= "a.out";
70 /* Variabless to track presence and/or absence of important command
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;
77 int dash_dynamiclib_seen
= 0;
79 int save_temps_seen
= 0;
80 int dash_m32_seen
= 0;
81 int dash_m64_seen
= 0;
83 /* Support at the max 10 arch. at a time. This is historical limit. */
86 /* Name of user supplied architectures. */
87 const char *arches
[MAX_ARCHES
];
90 static int num_arches
;
92 /* Input filenames. */
97 struct input_filename
*next
;
99 struct input_filename
*in_files
;
100 struct input_filename
*last_infile
;
102 static int num_infiles
;
104 /* User specified output file name. */
105 const char *output_filename
= NULL
;
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
;
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
116 const char *arch_name
;
117 const char *config_string
;
120 struct arch_config_guess_map arch_config_map
[] =
124 {"ppc64", "powerpc"},
135 /* List of interpreted command line flags. Supply this to gcc driver. */
136 const char **new_argv
;
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
;
143 /* Argument list for 'lipo'. */
144 const char **lipo_argv
;
146 /* Info about the sub process. Need one subprocess for each arch plus
147 additional one for 'lipo'. */
153 } commands
[MAX_ARCHES
+1];
155 /* total number of argc. */
156 static int total_argc
;
158 static int greatest_status
= 0;
159 static int signal_count
= 0;
161 #ifndef SWITCH_TAKES_ARG
162 #define SWITCH_TAKES_ARG(CHAR) DEFAULT_SWITCH_TAKES_ARG(CHAR)
165 #ifndef WORD_SWITCH_TAKES_ARG
166 #define WORD_SWITCH_TAKES_ARG(STR) DEFAULT_WORD_SWITCH_TAKES_ARG (STR)
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 **,
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
);
191 /* Find arch name for the given input string. If input name is NULL then local
192 arch name is used. */
195 get_arch_name (const char *name
)
198 const NXArchInfo
* all_info
;
200 struct arch_config_guess_map
*map
;
204 /* Find config name based on arch name. */
206 map
= arch_config_map
;
207 while (map
->arch_name
) {
208 if (!strcmp (map
->arch_name
, name
))
212 a_info
= (NXArchInfo
*) NXGetArchInfoFromName (name
);
214 a_info
= (NXArchInfo
*) NXGetLocalArchInfo();
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
;
228 fatal ("Invalid arch name : %s", name
);
230 all_info
= NXGetAllArchInfos();
233 fatal ("Unable to get architecture information");
235 /* Find first arch. that matches cputype. */
236 cputype
= a_info
->cputype
;
238 while (all_info
->name
)
240 if (all_info
->cputype
== cputype
)
246 return all_info
->name
;
249 /* Find driver name based on input arch name. */
252 get_driver_name (const char *arch_name
)
255 const char *config_name
;
258 struct arch_config_guess_map
*map
;
260 /* find config name based on arch name. */
262 map
= arch_config_map
;
263 while (map
->arch_name
)
265 if (!strcmp (map
->arch_name
, arch_name
))
267 config_name
= map
->config_string
;
274 fatal ("Unable to guess config name for arch %s", arch_name
);
276 len
= strlen (config_name
) + strlen (PDN
) + prefix_len
+ 1;
277 driver_name
= (char *) malloc (sizeof (char) * len
);
278 driver_name
[0] = '\0';
280 if (driver_exec_prefix
)
281 strcpy (driver_name
, driver_exec_prefix
);
282 strcat (driver_name
, config_name
);
283 strcat (driver_name
, PDN
);
288 /* Delete out_files. */
291 delete_out_files (void)
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
))
305 /* Put fatal error message on stderr and exit. */
308 fatal (const char *msgid
, ...)
312 va_start (ap
, msgid
);
314 fprintf (stderr
, "%s: ", progname
);
315 vfprintf (stderr
, msgid
, ap
);
317 fprintf (stderr
, "\n");
322 /* Print error message and exit. */
325 pfatal_pexecute (const char *errmsg_fmt
, const char *errmsg_arg
)
329 int save_errno
= errno
;
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
);
339 fprintf (stderr
,"%s: %s: %s\n", progname
, errmsg_fmt
, xstrerror (errno
));
346 debug_command_line (const char **debug_argv
, int debug_argc
)
350 fprintf (stderr
,"%s: debug_command_line\n", progname
);
351 fprintf (stderr
,"%s: arg count = %d\n", progname
, debug_argc
);
353 for (i
= 0; debug_argv
[i
]; i
++)
354 fprintf (stderr
,"%s: arg [%d] %s\n", progname
, i
, debug_argv
[i
]);
358 /* Strip directory name from the input file name and replace file name
362 strip_path_and_suffix (const char *full_name
, const char *new_suffix
)
367 if (!full_name
|| !new_suffix
)
370 /* Strip path name. */
371 p
= (char *)full_name
+ strlen (full_name
);
372 while (p
!= full_name
&& !IS_DIR_SEPARATOR (p
[-1]))
375 /* Now 'p' is a file name with suffix. */
376 name
= (char *) malloc (strlen (p
) + 1 + strlen (new_suffix
));
380 p
= name
+ strlen (name
);
381 while (p
!= name
&& *p
!= '.')
384 /* If did not reach at the beginning of name then '.' is found.
385 Replace '.' with NULL. */
389 strcat (name
, new_suffix
);
401 /* Let's count, how many additional arguments driver driver will supply
404 Each "-arch" "<blah>" is replaced by approriate "-mcpu=<blah>".
405 That leaves one additional arg space available.
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.
411 Driver driver may need to specify temp. output file name, say
412 "-o" "foobar". That needs two extra argments.
414 Sometimes linker wants one additional "-Wl,-arch_multiple".
416 Sometimes linker wants to see "-final_output" "outputname".
418 In the end, we may need five extra arguments, plus one extra
419 space for the NULL terminator. */
421 new_argv
= (const char **) malloc ((total_argc
+ 6) * sizeof (const char *));
425 arch_conditional
= (const char **) malloc ((total_argc
+ 6) * sizeof (const char *));
426 if (!arch_conditional
)
429 for (i
= 0; i
< total_argc
+ 6; i
++)
430 arch_conditional
[i
] = NULL
;
432 /* First slot, new_argv[0] is reserved for the driver name. */
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 *));
442 /* Need separate out_files for each arch, max is MAX_ARCHES.
443 Need separate out_files for each input file. */
445 out_files
= (const char **) malloc ((total_argc
* MAX_ARCHES
) * sizeof (const char *));
455 for (i
= 0; i
< (MAX_ARCHES
+ 1); i
++)
457 commands
[i
].prog
= NULL
;
458 commands
[i
].argv
= NULL
;
469 struct input_filename
*next
;
475 for (i
= 0, next
= in_files
;
476 i
< num_infiles
&& next
;
479 next
= in_files
->next
;
485 /* Wait for the process pid and return appropriate code. */
488 do_wait (int pid
, const char *prog
)
493 pid
= pwait (pid
, &status
, 0);
495 if (WIFSIGNALED (status
))
498 WEXITSTATUS (status
) > greatest_status
)
499 greatest_status
= WEXITSTATUS (status
);
502 else if (WIFEXITED (status
)
503 && WEXITSTATUS (status
) >= 1)
505 if (WEXITSTATUS (status
) > greatest_status
)
506 greatest_status
= WEXITSTATUS (status
);
513 /* Invoke 'lipo' and combine and all output files. */
516 do_lipo (int start_outfile_index
, const char *out_file
)
519 char *errmsg_fmt
, *errmsg_arg
;
521 /* Populate lipo arguments. */
522 lipo_argv
[0] = "lipo";
523 lipo_argv
[1] = "-create";
525 lipo_argv
[3] = out_file
;
527 /* Already 4 lipo arguments are set. Now add all lipo inputs. */
529 for (i
= 0; i
< num_arches
; i
++)
530 lipo_argv
[j
++] = out_files
[start_outfile_index
+ i
];
532 /* Add the NULL at the end. */
533 lipo_argv
[j
++] = NULL
;
536 debug_command_line (lipo_argv
, j
);
541 for (i
= 0; lipo_argv
[i
]; i
++)
542 fprintf (stderr
, "%s ", lipo_argv
[i
]);
543 fprintf (stderr
, "\n");
545 pid
= pexecute (lipo_argv
[0], (char *const *)lipo_argv
, progname
, NULL
, &errmsg_fmt
,
546 &errmsg_arg
, PEXECUTE_SEARCH
| PEXECUTE_ONE
);
549 pfatal_pexecute (errmsg_fmt
, errmsg_arg
);
551 do_wait (pid
, lipo_argv
[0]);
554 /* Invoke compiler for all architectures. */
557 do_compile (const char **current_argv
, int current_argc
)
559 char *errmsg_fmt
, *errmsg_arg
;
562 int dash_o_index
= current_argc
;
563 int of_index
= current_argc
+ 1;
564 int argc_count
= current_argc
+ 2;
566 const char **arch_specific_argv
;
568 int arch_specific_argc
;
570 while (index
< num_arches
)
572 int additional_arch_options
= 0;
574 current_argv
[0] = get_driver_name (get_arch_name (arches
[index
]));
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
];
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
;
587 current_argv
[argc_count
] = NULL
;
590 (const char **) malloc ((argc_count
+ 1) * sizeof (const char *));
592 arch_specific_argc
= filter_args_for_arch (current_argv
,
595 get_arch_name (arches
[index
]));
597 commands
[index
].prog
= arch_specific_argv
[0];
598 commands
[index
].argv
= arch_specific_argv
;
601 debug_command_line (arch_specific_argv
, arch_specific_argc
);
603 commands
[index
].pid
= pexecute (arch_specific_argv
[0],
604 (char *const *)arch_specific_argv
,
608 PEXECUTE_SEARCH
| PEXECUTE_ONE
);
610 if (commands
[index
].pid
== -1)
611 pfatal_pexecute (errmsg_fmt
, errmsg_arg
);
613 do_wait (commands
[index
].pid
, commands
[index
].prog
);
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
);
620 free (arch_specific_argv
);
624 /* Invoke compiler for each input file separately.
625 Construct command line for each invocation with one input file. */
628 do_compile_separately (void)
630 const char **new_new_argv
;
632 struct input_filename
*current_ifn
;
634 if (num_infiles
== 1 || ima_is_used
)
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 *));
644 for (current_ifn
= in_files
; current_ifn
&& current_ifn
->name
;
645 current_ifn
= current_ifn
->next
)
647 struct input_filename
*ifn
= in_files
;
650 bool ifn_found
= false;
652 for (i
= 1; i
< new_argc
; i
++)
654 if (ifn
&& ifn
->name
&& !strcmp (new_argv
[i
], ifn
->name
))
656 /* This argument is one of the input file. */
658 if (!strcmp (new_argv
[i
], current_ifn
->name
))
661 fatal ("file %s specified more than once on the command line", current_ifn
->name
);
663 /* If it is current input file name then add it in the new
665 new_new_argv
[new_new_argc
] = new_argv
[i
];
666 arch_conditional
[new_new_argc
] = arch_conditional
[i
];
670 /* This input file can not appear in
671 again on the command line so next time look for next input
677 /* This argument is not a input file name. Add it into new
679 new_new_argv
[new_new_argc
] = new_argv
[i
];
680 arch_conditional
[new_new_argc
] = arch_conditional
[i
];
685 /* OK now we have only one input file and all other arguments. */
686 do_compile (new_new_argv
, new_new_argc
);
690 /* Invoke 'lipo' on set of output files and create multile FAT binaries. */
693 do_lipo_separately (void)
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"));
704 /* Remove all options which are architecture-specific and are not for the
705 current architecture (arch). */
707 filter_args_for_arch (const char **orig_argv
, int orig_argc
,
708 const char **new_argv
, const char *arch
)
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
];
719 new_argv
[new_argc
] = NULL
;
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. */
730 add_arch_options (int index
, const char **current_argv
, int arch_index
)
734 /* We are adding 1 argument for selected arches. */
738 fprintf (stderr
, "%s: add_arch_options: %s\n", progname
, arches
[index
]);
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";
793 /* Remove the last option, which is arch option, added by
794 add_arch_options. Return how count of arguments removed. */
796 remove_arch_options (const char **current_argv
, int arch_index
)
799 fprintf (stderr
, "%s: Removing argument no %d\n", progname
, arch_index
);
802 current_argv
[arch_index
] = '\0';
805 debug_command_line (current_argv
, arch_index
);
811 /* Add new arch request. */
813 add_arch (const char *new_arch
)
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
++)
821 if (!strcmp (arches
[i
], new_arch
))
825 arches
[num_arches
] = new_arch
;
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.
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
847 Here's some examples:
849 s/precomp-trustfile=foo//
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.
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.
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.
876 int arg_array_size
=0;
878 int confirm_changes
= 1;
879 const int ARG_ARRAY_INCREMENT_SIZE
= 8;
882 /* Routines for the argument array. The argument array routines are
883 responsible for allocation and deallocation of all objects in the
886 void read_args (int argc
, char **argv
)
890 arg_array_size
= argc
+10;
892 arg_array
= (char**) malloc(sizeof(char*)*arg_array_size
);
894 for (i
=0;i
<argc
;i
++) {
895 arg_array
[i
] = malloc (strlen (argv
[i
])+1);
896 strcpy (arg_array
[i
], argv
[i
]);
900 /* Insert the argument before pos. */
901 void insert_arg(int pos
, char *arg_to_insert
)
904 char *newArg
= malloc (strlen (arg_to_insert
)+1);
905 strcpy(newArg
, arg_to_insert
);
907 if (arg_count
== arg_array_size
) {
909 arg_array_size
= arg_count
+ ARG_ARRAY_INCREMENT_SIZE
;
910 arg_array
= (char**) realloc (arg_array
, arg_array_size
);
913 for (i
= arg_count
; i
> pos
; i
--) {
914 arg_array
[i
+1] = arg_array
[i
];
917 arg_array
[pos
] = newArg
;
921 fprintf(stderr
,"### Adding argument %s at position %d\n",arg_to_insert
, pos
);
925 void replace_arg (char *str
, int pos
) {
926 char *newArg
= malloc(strlen(str
)+1);
930 fprintf (stderr
,"### Replacing %s with %s\n",arg_array
[pos
], str
);
932 free (arg_array
[pos
]);
933 arg_array
[pos
] = newArg
;
936 void append_arg (char *str
)
938 char *new_arg
= malloc (strlen (str
)+1);
939 strcpy (new_arg
, str
);
941 fprintf(stderr
,"### Adding argument %s at end\n", str
);
943 if (arg_count
== arg_array_size
) {
945 arg_array_size
= arg_count
+ ARG_ARRAY_INCREMENT_SIZE
;
946 arg_array
= (char**) realloc (arg_array
, arg_array_size
);
949 arg_array
[arg_count
++] = new_arg
;
952 void delete_arg(int pos
) {
956 fprintf(stderr
,"### Deleting argument %s\n",arg_array
[pos
]);
958 free (arg_array
[pos
]);
960 for (i
=pos
; i
< arg_count
; i
++)
961 arg_array
[i
] = arg_array
[i
+1];
966 /* Changing optimization levels is a common testing pattern --
967 we've got a special option that searches for and replaces anything
969 void replace_optimization_level (char *new_level
) {
972 char *new_opt
= malloc(strlen(new_opt
)+3);
973 sprintf(new_opt
, "-O%s",new_level
);
976 for (i
=0;i
<arg_count
;i
++) {
977 if (strncmp(arg_array
[i
],"-O",2) == 0) {
978 replace_arg (new_opt
, i
);
984 if (optionFound
== 0)
985 /* No optimization level? Add it! */
986 append_arg (new_opt
);
991 /* Returns a NULL terminated string holding whatever was in the original
992 string at that point. This must be freed by the caller. */
994 char *arg_string(char *str
, int begin
, int len
) {
995 char *new_str
= malloc(len
+1);
996 strncpy(new_str
,&str
[begin
],len
);
1001 /* Given a search-and-replace string of the form
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.
1010 Return true if success, false if bad failure.
1013 bool search_and_replace (char *str
) {
1014 regex_t regexp_search_struct
;
1023 const int ERRSIZ
= 512;
1024 char errbuf
[ERRSIZ
];
1027 if (str
[0] != '/') {
1031 searchLen
= strcspn (str
+ 1, "/\0");
1033 if (str
[1 + searchLen
] != '/')
1036 replaceLen
= strcspn(str
+1+searchLen
+1, "/\0");
1038 if (str
[1 + searchLen
+ 1 +replaceLen
] != '/')
1041 searchStr
= arg_string(str
, 1, searchLen
);
1042 replaceStr
= arg_string (str
, 1 + searchLen
+ 1, replaceLen
);
1044 if ((err
= regcomp(®exp_search_struct
, searchStr
, REG_EXTENDED
)) != 0) {
1045 regerror(err
, ®exp_search_struct
, errbuf
, ERRSIZ
);
1046 fprintf(stderr
,"%s",errbuf
);
1050 for (i
=0;i
<arg_count
;i
++) {
1051 regmatch_t matches
[5];
1052 if (regexec (®exp_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
);
1062 regfree (®exp_search_struct
);
1070 /* Given a string, return the argument number where the first match occurs. */
1071 int find_arg (char *str
) {
1073 int matchIndex
= -1;
1075 for (i
=0;i
<arg_count
;i
++) {
1076 if (strcmp(arg_array
[i
],str
) == 0) {
1085 void rewrite_command_line (char *override_options_line
, int *argc
, char ***argv
){
1088 read_args (*argc
, *argv
);
1090 if (override_options_line
[0] == '#')
1092 confirm_changes
= 0;
1097 if (confirm_changes
)
1098 fprintf (stderr
, "### QA_OVERRIDE_GCC3_OPTIONS: %s\n",
1099 override_options_line
);
1101 /* Loop through all commands in the file */
1103 while (override_options_line
[line_pos
] != '\0')
1111 /* Any spaces in between options don't count. */
1112 if (override_options_line
[line_pos
] == ' ')
1118 /* The first non-space character is the command. */
1119 first_char
= override_options_line
[line_pos
];
1121 arg_len
= strcspn(override_options_line
+line_pos
, " ");
1123 switch (first_char
) {
1125 /* Add an argument to the end of the arg list */
1126 arg
= arg_string (override_options_line
,
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
);
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");
1150 delete_arg(search_index
); /* Delete the matching argument */
1151 delete_arg(search_index
); /* Delete the following argument */
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
);
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
);
1178 fprintf(stderr
,"### QA_OVERRIDE_GCC3_OPTIONS: invalid string (pos %d)\n",
1182 line_pos
+= arg_len
;
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
1193 get_prog_name_len (const char *prog
)
1196 const char *progend
= prog
+ strlen(prog
);
1197 const char *progname
= progend
;
1198 while (progname
!= prog
&& !IS_DIR_SEPARATOR (progname
[-1]))
1200 return progend
-progname
;
1203 /* Return true iff the path is an executable file and not a directory. */
1206 is_x_file (const char *path
)
1209 if (access (path
, X_OK
))
1211 if (stat (path
, &st
) == -1)
1213 if (S_ISDIR (st
.st_mode
))
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.
1224 resolve_path_to_executable (const char *filename
)
1226 char path_buffer
[2*PATH_MAX
+1];
1227 char *PATH
= getenv ("PATH");
1228 if (PATH
== 0) return filename
; /* PATH not set */
1231 unsigned prefix_size
;
1233 char *colon
= strchr (PATH
, ':');
1235 /* If we didn't find a :, use the whole last chunk. */
1236 prefix_size
= colon
? colon
-PATH
: strlen (PATH
);
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
);
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
;
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. */
1257 resolve_symlink (const char *prog
, char *symlink_buffer
,
1258 int argv_0_len
, int prog_len
)
1260 /* If the link isn't to an absolute path, prefix it with the argv[0]
1262 if (!IS_ABSOLUTE_PATH (symlink_buffer
))
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
);
1269 return strdup(symlink_buffer
);
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. */
1276 main (int argc
, const char **argv
)
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];
1288 argv_0_len
= strlen (argv
[0]);
1290 /* Get the progname, required by pexecute () and program location. */
1291 prog_len
= get_prog_name_len (argv
[0]);
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
)
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]);
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]);
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)
1312 /* readlink succeeds if argv[0] is a symlink. path_buffer now contains
1313 the file referenced. */
1314 path_buffer
[linklen
] = '\0';
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
);
1320 argv
[0] = resolve_symlink(argv
[0], path_buffer
, argv_0_len
, prog_len
);
1321 argv_0_len
= strlen(argv
[0]);
1323 /* Get the progname, required by pexecute () and program location. */
1324 prog_len
= get_prog_name_len (argv
[0]);
1327 progname
= argv
[0] + argv_0_len
- prog_len
;
1328 printf("%s: ARGV[0] after symlink = %s\n", progname
, argv
[0]);
1332 progname
= argv
[0] + argv_0_len
- prog_len
;
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
);
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
);
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
);
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
++)
1359 if (!strcmp (argv
[i
], "-arch"))
1364 add_arch (argv
[i
+1]);
1367 else if (!strcmp (argv
[i
], "-c"))
1369 new_argv
[new_argc
++] = argv
[i
];
1370 compile_only_request
= 1;
1372 else if (!strcmp (argv
[i
], "-S"))
1374 new_argv
[new_argc
++] = argv
[i
];
1375 asm_output_request
= 1;
1377 else if (!strcmp (argv
[i
], "-E"))
1379 new_argv
[new_argc
++] = argv
[i
];
1380 preprocessed_output_request
= 1;
1382 else if (!strcmp (argv
[i
], "-MD") || !strcmp (argv
[i
], "-MMD"))
1384 new_argv
[new_argc
++] = argv
[i
];
1385 dash_capital_m_seen
= 1;
1387 else if (!strcmp (argv
[i
], "-m32"))
1389 new_argv
[new_argc
++] = argv
[i
];
1392 else if (!strcmp (argv
[i
], "-m64"))
1394 new_argv
[new_argc
++] = argv
[i
];
1397 else if (!strcmp (argv
[i
], "-dynamiclib"))
1399 new_argv
[new_argc
++] = argv
[i
];
1400 dash_dynamiclib_seen
= 1;
1402 else if (!strcmp (argv
[i
], "-v"))
1404 new_argv
[new_argc
++] = argv
[i
];
1407 else if (!strcmp (argv
[i
], "-o"))
1410 fatal ("argument to '-o' is missing");
1412 output_filename
= argv
[i
+1];
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"))
1444 new_argv
[new_argc
++] = argv
[i
];
1446 else if (! strcmp (argv
[i
], "-save-temps")
1447 || ! strcmp (argv
[i
], "--save-temps"))
1449 new_argv
[new_argc
++] = argv
[i
];
1450 save_temps_seen
= 1;
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"))
1462 new_argv
[new_argc
++] = argv
[i
];
1464 new_argv
[new_argc
++] = argv
[i
];
1466 else if (! strncmp (argv
[i
], "-Xarch_", 7))
1468 arch_conditional
[new_argc
] = get_arch_name (argv
[i
] + 7);
1470 new_argv
[new_argc
++] = argv
[i
];
1472 else if (argv
[i
][0] == '-' && argv
[i
][1] != 0)
1474 const char *p
= &argv
[i
][1];
1477 /* First copy this flag itself. */
1478 new_argv
[new_argc
++] = argv
[i
];
1480 if (argv
[i
][1] == 'M')
1481 dash_capital_m_seen
= 1;
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
))
1488 int n_args
= WORD_SWITCH_TAKES_ARG (p
);
1491 /* Count only the option arguments in separate argv elements. */
1492 n_args
= SWITCH_TAKES_ARG (c
) - (p
[1] != 0);
1494 if (i
+ n_args
>= argc
)
1495 fatal ("argument to `-%s' is missing", p
);
1501 new_argv
[new_argc
++] = argv
[i
];
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
];
1518 last_infile
->next
= ifn
;
1527 if (num_infiles
== 0)
1528 fatal ("no input files");
1531 if (num_arches
== 0)
1532 add_arch(get_arch_name(NULL
));
1536 if (preprocessed_output_request
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");
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
1546 if (num_arches
== 1)
1548 int arch_specific_argc
;
1549 const char **arch_specific_argv
;
1551 /* Find compiler driver based on -arch <foo> and add approriate
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
);
1557 printf ("%s: invoking single driver name = %s\n", progname
, new_argv
[0]);
1560 /* Re insert output file name. */
1561 if (output_filename
)
1563 new_argv
[new_argc
++] = "-o";
1564 new_argv
[new_argc
++] = output_filename
;
1568 new_argv
[new_argc
] = NULL
;
1570 arch_specific_argv
=
1571 (const char **) malloc ((new_argc
+ 1) * sizeof (const char *));
1572 arch_specific_argc
= filter_args_for_arch (new_argv
,
1575 get_arch_name (arches
[0]));
1578 debug_command_line (arch_specific_argv
, arch_specific_argc
);
1581 pid
= pexecute (arch_specific_argv
[0], (char *const *)arch_specific_argv
,
1582 progname
, NULL
, &errmsg_fmt
, &errmsg_arg
,
1583 PEXECUTE_SEARCH
| PEXECUTE_ONE
);
1586 pfatal_pexecute (errmsg_fmt
, errmsg_arg
);
1588 do_wait (pid
, arch_specific_argv
[0]);
1592 /* Handle multiple -arch <blah>. */
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
)
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";
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
)
1609 const char *out_file
;
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");
1616 out_file
= (output_filename
? output_filename
: final_output
);
1619 /* Linker wants to know name of output file using one extra arg. */
1620 if (!compile_only_request
)
1622 char *oname
= (char *)(output_filename
? output_filename
: final_output
);
1623 char *n
= malloc (sizeof (char) * (strlen (oname
) + 5));
1626 new_argv
[new_argc
++] = "-Wl,-final_output";
1627 new_argv
[new_argc
++] = n
;
1630 /* Compile file(s) for each arch and lipo 'em together. */
1631 do_compile (new_argv
, new_argc
);
1633 /* Make FAT binary by combining individual output files for each
1634 architecture, using 'lipo'. */
1635 do_lipo (0, out_file
);
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 ();
1648 return greatest_status
;