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)
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/>. */
22 #include "libiberty.h"
24 #include "coretypes.h"
27 #include "diagnostic-core.h"
29 #ifndef CROSS_DIRECTORY_STRUCTURE
30 #include <sys/sysctl.h>
34 darwin_find_version_from_kernel (void)
37 size_t osversion_len
= sizeof (osversion
) - 1;
38 static int osversion_name
[2] = { CTL_KERN
, KERN_OSRELEASE
};
45 /* Determine the version of the running OS. If we can't, warn user,
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");
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]))
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
++ != '.')
64 version_pend
= strchr(version_p
, '.');
67 if (! ISDIGIT (*version_p
))
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
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);
80 asprintf (&new_flag
, "10.%d.%s", major_vers
- 4, minor_vers
);
85 warning (0, "couldn%'t understand kern.osversion %q.*s",
86 (int) osversion_len
, osversion
);
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). */
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 ();
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
);
128 new_flag
= xstrndup (new_flag
, len
);
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. */
143 darwin_driver_init (unsigned int *decoded_options_count
,
144 struct cl_decoded_option
**decoded_options
)
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
)
163 switch ((*decoded_options
)[i
].opt_index
)
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
169 if (!strcmp ((*decoded_options
)[i
].arg
, "i386"))
171 else if (!strcmp ((*decoded_options
)[i
].arg
, "x86_64"))
173 else if (!strcmp ((*decoded_options
)[i
].arg
, "ppc"))
175 else if (!strcmp ((*decoded_options
)[i
].arg
, "ppc64"))
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
)));
188 --*decoded_options_count
;
201 ++*decoded_options_count
;
202 *decoded_options
= XRESIZEVEC (struct cl_decoded_option
,
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
]);
216 case OPT_mmacosx_version_min_
:
217 seen_version_min
= true;
218 vers_string
= xstrndup ((*decoded_options
)[i
].arg
, 32);
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. */
232 if (seenPPC
|| seenPPC64
)
233 warning (0, "this compiler does not support PowerPC (arch flags ignored)");
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. */
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. */
251 if (seenX86
|| seenX86_64
)
252 warning (0, "this compiler does not support X86 (arch flags ignored)");
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. */
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. */
271 if (appendM32
|| appendM64
)
273 ++*decoded_options_count
;
274 *decoded_options
= XRESIZEVEC (struct cl_decoded_option
,
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
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
,
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
);
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
,
318 *decoded_options_count
);
319 generate_option (OPT_asm_macosx_version_min_
, asm_major
, 1, CL_DRIVER
,
320 &(*decoded_options
)[*decoded_options_count
- 1]);