PR rtl-optimization/82913
[official-gcc.git] / gcc / config / darwin-driver.c
blob0348b40322589aec2b56a01a7be520d2cf20dd36
1 /* Additional functions for the GCC driver on Darwin native.
2 Copyright (C) 2006-2017 Free Software Foundation, Inc.
3 Contributed by Apple Computer Inc.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
10 any later version.
12 GCC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
21 #include "config.h"
22 #include "libiberty.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "opts.h"
27 #include "diagnostic-core.h"
29 #ifndef CROSS_DIRECTORY_STRUCTURE
30 #include <sys/sysctl.h>
31 #include "xregex.h"
33 static char *
34 darwin_find_version_from_kernel (void)
36 char osversion[32];
37 size_t osversion_len = sizeof (osversion) - 1;
38 static int osversion_name[2] = { CTL_KERN, KERN_OSRELEASE };
39 int major_vers;
40 char * version_p;
41 char * new_flag;
43 /* Determine the version of the running OS. If we can't, warn user,
44 and do nothing. */
45 if (sysctl (osversion_name, ARRAY_SIZE (osversion_name), osversion,
46 &osversion_len, NULL, 0) == -1)
48 warning (0, "sysctl for kern.osversion failed: %m");
49 return NULL;
52 /* Try to parse the first two parts of the OS version number. Warn
53 user and return if it doesn't make sense. */
54 if (! ISDIGIT (osversion[0]))
55 goto parse_failed;
56 major_vers = osversion[0] - '0';
57 version_p = osversion + 1;
58 if (ISDIGIT (*version_p))
59 major_vers = major_vers * 10 + (*version_p++ - '0');
60 if (*version_p++ != '.')
61 goto parse_failed;
63 /* The major kernel version number is 4 plus the second OS version
64 component. */
65 if (major_vers - 4 <= 4)
66 /* On 10.4 and earlier, the old linker is used which does not
67 support three-component system versions.
68 FIXME: we should not assume this - a newer linker could be used. */
69 asprintf (&new_flag, "10.%d", major_vers - 4);
70 else
71 /* Although the newer linker supports three-component system
72 versions, there's no guarantee that the minor version component
73 of the kernel and the system are the same. Apple's clang always
74 uses 0 as the minor version: do the same. */
75 asprintf (&new_flag, "10.%d.0", major_vers - 4);
77 return new_flag;
79 parse_failed:
80 warning (0, "couldn%'t understand kern.osversion %q.*s",
81 (int) osversion_len, osversion);
82 return NULL;
84 #endif
86 /* When running on a Darwin system and using that system's headers and
87 libraries, default the -mmacosx-version-min flag to be the version
88 of the system on which the compiler is running.
90 When building cross or native cross compilers, default to the OSX
91 version of the target (as provided by the most specific target header
92 included in tm.h). This may be overidden by setting the flag explicitly
93 (or by the MACOSX_DEPLOYMENT_TARGET environment). */
95 static const char *
96 darwin_default_min_version (void)
98 /* Try to retrieve the deployment target from the environment. */
99 const char *new_flag = getenv ("MACOSX_DEPLOYMENT_TARGET");
101 /* Apparently, an empty string for MACOSX_DEPLOYMENT_TARGET means
102 "use the default". Or, possibly "use 10.1". We choose
103 to ignore the environment variable, as if it was never set. */
104 if (new_flag == NULL || new_flag[0] == 0)
105 #ifndef CROSS_DIRECTORY_STRUCTURE
106 /* Try to find the version from the kernel, if we fail - we print a
107 message and give up. */
108 new_flag = darwin_find_version_from_kernel ();
109 #else
110 /* For cross-compilers, default to a minimum version determined by
111 the configuration. */
112 new_flag = DEF_MIN_OSX_VERSION;
113 #endif /* CROSS_DIRECTORY_STRUCTURE */
115 if (new_flag != NULL)
117 size_t len = strlen (new_flag);
118 if (len > 128) { /* Arbitrary limit, number should be like xx.yy.zz */
119 warning (0, "couldn%'t understand version %s\n", new_flag);
120 return NULL;
122 new_flag = xstrndup (new_flag, len);
124 return new_flag;
127 /* Translate -filelist and -framework options in *DECODED_OPTIONS
128 (size *DECODED_OPTIONS_COUNT) to use -Xlinker so that they are
129 considered to be linker inputs in the case that no other inputs are
130 specified. Handling these options in DRIVER_SELF_SPECS does not
131 suffice because specs are too late to add linker inputs, and
132 handling them in LINK_SPEC does not suffice because the linker will
133 not be called if there are no other inputs. When native, also
134 default the -mmacosx-version-min flag. */
136 void
137 darwin_driver_init (unsigned int *decoded_options_count,
138 struct cl_decoded_option **decoded_options)
140 unsigned int i;
141 bool seenX86 = false;
142 bool seenX86_64 = false;
143 bool seenPPC = false;
144 bool seenPPC64 = false;
145 bool seenM32 = false;
146 bool seenM64 = false;
147 bool appendM32 = false;
148 bool appendM64 = false;
149 const char *vers_string = NULL;
150 bool seen_version_min = false;
152 for (i = 1; i < *decoded_options_count; i++)
154 if ((*decoded_options)[i].errors & CL_ERR_MISSING_ARG)
155 continue;
157 switch ((*decoded_options)[i].opt_index)
159 case OPT_arch:
160 /* Support provision of a single -arch xxxx flag as a means of
161 specifying the sub-target/multi-lib. Translate this into -m32/64
162 as appropriate. */
163 if (!strcmp ((*decoded_options)[i].arg, "i386"))
164 seenX86 = true;
165 else if (!strcmp ((*decoded_options)[i].arg, "x86_64"))
166 seenX86_64 = true;
167 else if (!strcmp ((*decoded_options)[i].arg, "ppc"))
168 seenPPC = true;
169 else if (!strcmp ((*decoded_options)[i].arg, "ppc64"))
170 seenPPC64 = true;
171 else
172 error ("this compiler does not support %s",
173 (*decoded_options)[i].arg);
174 /* Now we've examined it, drop the -arch arg. */
175 if (*decoded_options_count > i) {
176 memmove (*decoded_options + i,
177 *decoded_options + i + 1,
178 ((*decoded_options_count - i)
179 * sizeof (struct cl_decoded_option)));
181 --i;
182 --*decoded_options_count;
183 break;
185 case OPT_m32:
186 seenM32 = true;
187 break;
189 case OPT_m64:
190 seenM64 = true;
191 break;
193 case OPT_filelist:
194 case OPT_framework:
195 ++*decoded_options_count;
196 *decoded_options = XRESIZEVEC (struct cl_decoded_option,
197 *decoded_options,
198 *decoded_options_count);
199 memmove (*decoded_options + i + 2,
200 *decoded_options + i + 1,
201 ((*decoded_options_count - i - 2)
202 * sizeof (struct cl_decoded_option)));
203 generate_option (OPT_Xlinker, (*decoded_options)[i].arg, 1,
204 CL_DRIVER, &(*decoded_options)[i + 1]);
205 generate_option (OPT_Xlinker,
206 (*decoded_options)[i].canonical_option[0], 1,
207 CL_DRIVER, &(*decoded_options)[i]);
208 break;
210 case OPT_mmacosx_version_min_:
211 seen_version_min = true;
212 vers_string = xstrndup ((*decoded_options)[i].arg, 32);
214 default:
215 break;
219 /* Turn -arch xxxx into the appropriate -m32/-m64 flag.
220 If the User tried to specify multiple arch flags (which is possible with
221 some Darwin compilers) warn that this mode is not supported by this
222 compiler (and ignore the arch flags, which means that the default multi-
223 lib will be generated). */
224 /* TODO: determine if these warnings would better be errors. */
225 #if DARWIN_X86
226 if (seenPPC || seenPPC64)
227 warning (0, "this compiler does not support PowerPC (arch flags ignored)");
228 if (seenX86)
230 if (seenX86_64 || seenM64)
231 warning (0, "%s conflicts with i386 (arch flags ignored)",
232 (seenX86_64? "x86_64": "m64"));
233 else if (! seenM32) /* Add -m32 if the User didn't. */
234 appendM32 = true;
236 else if (seenX86_64)
238 if (seenX86 || seenM32)
239 warning (0, "%s conflicts with x86_64 (arch flags ignored)",
240 (seenX86? "i386": "m32"));
241 else if (! seenM64) /* Add -m64 if the User didn't. */
242 appendM64 = true;
244 #elif DARWIN_PPC
245 if (seenX86 || seenX86_64)
246 warning (0, "this compiler does not support X86 (arch flags ignored)");
247 if (seenPPC)
249 if (seenPPC64 || seenM64)
250 warning (0, "%s conflicts with ppc (arch flags ignored)",
251 (seenPPC64? "ppc64": "m64"));
252 else if (! seenM32) /* Add -m32 if the User didn't. */
253 appendM32 = true;
255 else if (seenPPC64)
257 if (seenPPC || seenM32)
258 warning (0, "%s conflicts with ppc64 (arch flags ignored)",
259 (seenPPC? "ppc": "m32"));
260 else if (! seenM64) /* Add -m64 if the User didn't. */
261 appendM64 = true;
263 #endif
265 if (appendM32 || appendM64)
267 ++*decoded_options_count;
268 *decoded_options = XRESIZEVEC (struct cl_decoded_option,
269 *decoded_options,
270 *decoded_options_count);
271 generate_option (appendM32 ? OPT_m32 : OPT_m64, NULL, 1, CL_DRIVER,
272 &(*decoded_options)[*decoded_options_count - 1]);
275 /* We will need to know the OS X version we're trying to build for here
276 so that we can figure out the mechanism and source for the sysroot to
277 be used. */
278 if (! seen_version_min && *decoded_options_count > 1)
280 /* Not set by the User, try to figure it out. */
281 vers_string = darwin_default_min_version ();
282 if (vers_string != NULL)
284 ++*decoded_options_count;
285 *decoded_options = XRESIZEVEC (struct cl_decoded_option,
286 *decoded_options,
287 *decoded_options_count);
288 generate_option (OPT_mmacosx_version_min_, vers_string, 1, CL_DRIVER,
289 &(*decoded_options)[*decoded_options_count - 1]);
292 /* Create and push the major version for assemblers that need it. */
293 if (vers_string != NULL)
295 char *asm_major = NULL;
296 const char *first_period = strchr(vers_string, '.');
297 if (first_period != NULL)
299 const char *second_period = strchr(first_period+1, '.');
300 if (second_period != NULL)
301 asm_major = xstrndup (vers_string, second_period-vers_string);
302 else
303 asm_major = xstrdup (vers_string);
305 /* Else we appear to have a weird macosx version with no major number.
306 Punt on this for now. */
307 if (asm_major != NULL)
309 ++*decoded_options_count;
310 *decoded_options = XRESIZEVEC (struct cl_decoded_option,
311 *decoded_options,
312 *decoded_options_count);
313 generate_option (OPT_asm_macosx_version_min_, asm_major, 1, CL_DRIVER,
314 &(*decoded_options)[*decoded_options_count - 1]);