gcc/ChangeLog:
[official-gcc.git] / gcc / config / darwin-driver.c
blobe3ed79d14dd115a216e0a6ed56c0e348228936d6
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 minor_vers[6];
41 char * version_p;
42 char * version_pend;
43 char * new_flag;
45 /* Determine the version of the running OS. If we can't, warn user,
46 and do nothing. */
47 if (sysctl (osversion_name, ARRAY_SIZE (osversion_name), osversion,
48 &osversion_len, NULL, 0) == -1)
50 warning (0, "sysctl for kern.osversion failed: %m");
51 return NULL;
54 /* Try to parse the first two parts of the OS version number. Warn
55 user and return if it doesn't make sense. */
56 if (! ISDIGIT (osversion[0]))
57 goto parse_failed;
58 major_vers = osversion[0] - '0';
59 version_p = osversion + 1;
60 if (ISDIGIT (*version_p))
61 major_vers = major_vers * 10 + (*version_p++ - '0');
62 if (*version_p++ != '.')
63 goto parse_failed;
64 version_pend = strchr(version_p, '.');
65 if (!version_pend)
66 goto parse_failed;
67 if (! ISDIGIT (*version_p))
68 goto parse_failed;
69 strncpy(minor_vers, version_p, version_pend - version_p);
70 minor_vers[version_pend - version_p] = '\0';
72 /* The major kernel version number is 4 plus the second OS version
73 component. */
74 if (major_vers - 4 <= 4)
75 /* On 10.4 and earlier, the old linker is used which does not
76 support three-component system versions.
77 FIXME: we should not assume this - a newer linker could be used. */
78 asprintf (&new_flag, "10.%d", major_vers - 4);
79 else
80 asprintf (&new_flag, "10.%d.%s", major_vers - 4, minor_vers);
82 return new_flag;
84 parse_failed:
85 warning (0, "couldn%'t understand kern.osversion %q.*s",
86 (int) osversion_len, osversion);
87 return NULL;
90 #endif
92 /* When running on a Darwin system and using that system's headers and
93 libraries, default the -mmacosx-version-min flag to be the version
94 of the system on which the compiler is running.
96 When building cross or native cross compilers, default to the OSX
97 version of the target (as provided by the most specific target header
98 included in tm.h). This may be overidden by setting the flag explicitly
99 (or by the MACOSX_DEPLOYMENT_TARGET environment). */
101 static const char *
102 darwin_default_min_version (void)
104 /* Try to retrieve the deployment target from the environment. */
105 const char *new_flag = getenv ("MACOSX_DEPLOYMENT_TARGET");
107 /* Apparently, an empty string for MACOSX_DEPLOYMENT_TARGET means
108 "use the default". Or, possibly "use 10.1". We choose
109 to ignore the environment variable, as if it was never set. */
110 if (new_flag == NULL || new_flag[0] == 0)
111 #ifndef CROSS_DIRECTORY_STRUCTURE
112 /* Try to find the version from the kernel, if we fail - we print a
113 message and give up. */
114 new_flag = darwin_find_version_from_kernel ();
115 #else
116 /* For cross-compilers, default to a minimum version determined by
117 the configuration. */
118 new_flag = DEF_MIN_OSX_VERSION;
119 #endif /* CROSS_DIRECTORY_STRUCTURE */
121 if (new_flag != NULL)
123 size_t len = strlen (new_flag);
124 if (len > 128) { /* Arbitrary limit, number should be like xx.yy.zz */
125 warning (0, "couldn%'t understand version %s\n", new_flag);
126 return NULL;
128 new_flag = xstrndup (new_flag, len);
130 return new_flag;
133 /* Translate -filelist and -framework options in *DECODED_OPTIONS
134 (size *DECODED_OPTIONS_COUNT) to use -Xlinker so that they are
135 considered to be linker inputs in the case that no other inputs are
136 specified. Handling these options in DRIVER_SELF_SPECS does not
137 suffice because specs are too late to add linker inputs, and
138 handling them in LINK_SPEC does not suffice because the linker will
139 not be called if there are no other inputs. When native, also
140 default the -mmacosx-version-min flag. */
142 void
143 darwin_driver_init (unsigned int *decoded_options_count,
144 struct cl_decoded_option **decoded_options)
146 unsigned int i;
147 bool seenX86 = false;
148 bool seenX86_64 = false;
149 bool seenPPC = false;
150 bool seenPPC64 = false;
151 bool seenM32 = false;
152 bool seenM64 = false;
153 bool appendM32 = false;
154 bool appendM64 = false;
155 const char *vers_string = NULL;
156 bool seen_version_min = false;
158 for (i = 1; i < *decoded_options_count; i++)
160 if ((*decoded_options)[i].errors & CL_ERR_MISSING_ARG)
161 continue;
163 switch ((*decoded_options)[i].opt_index)
165 case OPT_arch:
166 /* Support provision of a single -arch xxxx flag as a means of
167 specifying the sub-target/multi-lib. Translate this into -m32/64
168 as appropriate. */
169 if (!strcmp ((*decoded_options)[i].arg, "i386"))
170 seenX86 = true;
171 else if (!strcmp ((*decoded_options)[i].arg, "x86_64"))
172 seenX86_64 = true;
173 else if (!strcmp ((*decoded_options)[i].arg, "ppc"))
174 seenPPC = true;
175 else if (!strcmp ((*decoded_options)[i].arg, "ppc64"))
176 seenPPC64 = true;
177 else
178 error ("this compiler does not support %s",
179 (*decoded_options)[i].arg);
180 /* Now we've examined it, drop the -arch arg. */
181 if (*decoded_options_count > i) {
182 memmove (*decoded_options + i,
183 *decoded_options + i + 1,
184 ((*decoded_options_count - i)
185 * sizeof (struct cl_decoded_option)));
187 --i;
188 --*decoded_options_count;
189 break;
191 case OPT_m32:
192 seenM32 = true;
193 break;
195 case OPT_m64:
196 seenM64 = true;
197 break;
199 case OPT_filelist:
200 case OPT_framework:
201 ++*decoded_options_count;
202 *decoded_options = XRESIZEVEC (struct cl_decoded_option,
203 *decoded_options,
204 *decoded_options_count);
205 memmove (*decoded_options + i + 2,
206 *decoded_options + i + 1,
207 ((*decoded_options_count - i - 2)
208 * sizeof (struct cl_decoded_option)));
209 generate_option (OPT_Xlinker, (*decoded_options)[i].arg, 1,
210 CL_DRIVER, &(*decoded_options)[i + 1]);
211 generate_option (OPT_Xlinker,
212 (*decoded_options)[i].canonical_option[0], 1,
213 CL_DRIVER, &(*decoded_options)[i]);
214 break;
216 case OPT_mmacosx_version_min_:
217 seen_version_min = true;
218 vers_string = xstrndup ((*decoded_options)[i].arg, 32);
220 default:
221 break;
225 /* Turn -arch xxxx into the appropriate -m32/-m64 flag.
226 If the User tried to specify multiple arch flags (which is possible with
227 some Darwin compilers) warn that this mode is not supported by this
228 compiler (and ignore the arch flags, which means that the default multi-
229 lib will be generated). */
230 /* TODO: determine if these warnings would better be errors. */
231 #if DARWIN_X86
232 if (seenPPC || seenPPC64)
233 warning (0, "this compiler does not support PowerPC (arch flags ignored)");
234 if (seenX86)
236 if (seenX86_64 || seenM64)
237 warning (0, "%s conflicts with i386 (arch flags ignored)",
238 (seenX86_64? "x86_64": "m64"));
239 else if (! seenM32) /* Add -m32 if the User didn't. */
240 appendM32 = true;
242 else if (seenX86_64)
244 if (seenX86 || seenM32)
245 warning (0, "%s conflicts with x86_64 (arch flags ignored)",
246 (seenX86? "i386": "m32"));
247 else if (! seenM64) /* Add -m64 if the User didn't. */
248 appendM64 = true;
250 #elif DARWIN_PPC
251 if (seenX86 || seenX86_64)
252 warning (0, "this compiler does not support X86 (arch flags ignored)");
253 if (seenPPC)
255 if (seenPPC64 || seenM64)
256 warning (0, "%s conflicts with ppc (arch flags ignored)",
257 (seenPPC64? "ppc64": "m64"));
258 else if (! seenM32) /* Add -m32 if the User didn't. */
259 appendM32 = true;
261 else if (seenPPC64)
263 if (seenPPC || seenM32)
264 warning (0, "%s conflicts with ppc64 (arch flags ignored)",
265 (seenPPC? "ppc": "m32"));
266 else if (! seenM64) /* Add -m64 if the User didn't. */
267 appendM64 = true;
269 #endif
271 if (appendM32 || appendM64)
273 ++*decoded_options_count;
274 *decoded_options = XRESIZEVEC (struct cl_decoded_option,
275 *decoded_options,
276 *decoded_options_count);
277 generate_option (appendM32 ? OPT_m32 : OPT_m64, NULL, 1, CL_DRIVER,
278 &(*decoded_options)[*decoded_options_count - 1]);
281 /* We will need to know the OS X version we're trying to build for here
282 so that we can figure out the mechanism and source for the sysroot to
283 be used. */
284 if (! seen_version_min && *decoded_options_count > 1)
286 /* Not set by the User, try to figure it out. */
287 vers_string = darwin_default_min_version ();
288 if (vers_string != NULL)
290 ++*decoded_options_count;
291 *decoded_options = XRESIZEVEC (struct cl_decoded_option,
292 *decoded_options,
293 *decoded_options_count);
294 generate_option (OPT_mmacosx_version_min_, vers_string, 1, CL_DRIVER,
295 &(*decoded_options)[*decoded_options_count - 1]);
298 /* Create and push the major version for assemblers that need it. */
299 if (vers_string != NULL)
301 char *asm_major = NULL;
302 const char *first_period = strchr(vers_string, '.');
303 if (first_period != NULL)
305 const char *second_period = strchr(first_period+1, '.');
306 if (second_period != NULL)
307 asm_major = xstrndup (vers_string, second_period-vers_string);
308 else
309 asm_major = xstrdup (vers_string);
311 /* Else we appear to have a weird macosx version with no major number.
312 Punt on this for now. */
313 if (asm_major != NULL)
315 ++*decoded_options_count;
316 *decoded_options = XRESIZEVEC (struct cl_decoded_option,
317 *decoded_options,
318 *decoded_options_count);
319 generate_option (OPT_asm_macosx_version_min_, asm_major, 1, CL_DRIVER,
320 &(*decoded_options)[*decoded_options_count - 1]);