1 /* Additional functions for the GCC driver on Darwin native.
2 Copyright (C) 2006-2016 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 asprintf (&new_flag
, "10.%d", major_vers
- 4);
79 asprintf (&new_flag
, "10.%d.%s", major_vers
- 4, minor_vers
);
84 warning (0, "couldn%'t understand kern.osversion %q.*s",
85 (int) osversion_len
, osversion
);
91 /* When running on a Darwin system and using that system's headers and
92 libraries, default the -mmacosx-version-min flag to be the version
93 of the system on which the compiler is running.
95 When building cross or native cross compilers, default to the OSX
96 version of the target (as provided by the most specific target header
97 included in tm.h). This may be overidden by setting the flag explicitly
98 (or by the MACOSX_DEPLOYMENT_TARGET environment). */
101 darwin_default_min_version (void)
103 /* Try to retrieve the deployment target from the environment. */
104 const char *new_flag
= getenv ("MACOSX_DEPLOYMENT_TARGET");
106 /* Apparently, an empty string for MACOSX_DEPLOYMENT_TARGET means
107 "use the default". Or, possibly "use 10.1". We choose
108 to ignore the environment variable, as if it was never set. */
109 if (new_flag
== NULL
|| new_flag
[0] == 0)
110 #ifndef CROSS_DIRECTORY_STRUCTURE
111 /* Try to find the version from the kernel, if we fail - we print a
112 message and give up. */
113 new_flag
= darwin_find_version_from_kernel ();
115 /* For cross-compilers, default to a minimum version determined by
116 the configuration. */
117 new_flag
= DEF_MIN_OSX_VERSION
;
118 #endif /* CROSS_DIRECTORY_STRUCTURE */
120 if (new_flag
!= NULL
)
122 size_t len
= strlen (new_flag
);
123 if (len
> 128) { /* Arbitrary limit, number should be like xx.yy.zz */
124 warning (0, "couldn%'t understand version %s\n", new_flag
);
127 new_flag
= xstrndup (new_flag
, len
);
132 /* Translate -filelist and -framework options in *DECODED_OPTIONS
133 (size *DECODED_OPTIONS_COUNT) to use -Xlinker so that they are
134 considered to be linker inputs in the case that no other inputs are
135 specified. Handling these options in DRIVER_SELF_SPECS does not
136 suffice because specs are too late to add linker inputs, and
137 handling them in LINK_SPEC does not suffice because the linker will
138 not be called if there are no other inputs. When native, also
139 default the -mmacosx-version-min flag. */
142 darwin_driver_init (unsigned int *decoded_options_count
,
143 struct cl_decoded_option
**decoded_options
)
146 bool seenX86
= false;
147 bool seenX86_64
= false;
148 bool seenPPC
= false;
149 bool seenPPC64
= false;
150 bool seenM32
= false;
151 bool seenM64
= false;
152 bool appendM32
= false;
153 bool appendM64
= false;
154 const char *vers_string
= NULL
;
155 bool seen_version_min
= false;
157 for (i
= 1; i
< *decoded_options_count
; i
++)
159 if ((*decoded_options
)[i
].errors
& CL_ERR_MISSING_ARG
)
162 switch ((*decoded_options
)[i
].opt_index
)
165 /* Support provision of a single -arch xxxx flag as a means of
166 specifying the sub-target/multi-lib. Translate this into -m32/64
168 if (!strcmp ((*decoded_options
)[i
].arg
, "i386"))
170 else if (!strcmp ((*decoded_options
)[i
].arg
, "x86_64"))
172 else if (!strcmp ((*decoded_options
)[i
].arg
, "ppc"))
174 else if (!strcmp ((*decoded_options
)[i
].arg
, "ppc64"))
177 error ("this compiler does not support %s",
178 (*decoded_options
)[i
].arg
);
179 /* Now we've examined it, drop the -arch arg. */
180 if (*decoded_options_count
> i
) {
181 memmove (*decoded_options
+ i
,
182 *decoded_options
+ i
+ 1,
183 ((*decoded_options_count
- i
)
184 * sizeof (struct cl_decoded_option
)));
187 --*decoded_options_count
;
200 ++*decoded_options_count
;
201 *decoded_options
= XRESIZEVEC (struct cl_decoded_option
,
203 *decoded_options_count
);
204 memmove (*decoded_options
+ i
+ 2,
205 *decoded_options
+ i
+ 1,
206 ((*decoded_options_count
- i
- 2)
207 * sizeof (struct cl_decoded_option
)));
208 generate_option (OPT_Xlinker
, (*decoded_options
)[i
].arg
, 1,
209 CL_DRIVER
, &(*decoded_options
)[i
+ 1]);
210 generate_option (OPT_Xlinker
,
211 (*decoded_options
)[i
].canonical_option
[0], 1,
212 CL_DRIVER
, &(*decoded_options
)[i
]);
215 case OPT_mmacosx_version_min_
:
216 seen_version_min
= true;
217 vers_string
= xstrndup ((*decoded_options
)[i
].arg
, 32);
224 /* Turn -arch xxxx into the appropriate -m32/-m64 flag.
225 If the User tried to specify multiple arch flags (which is possible with
226 some Darwin compilers) warn that this mode is not supported by this
227 compiler (and ignore the arch flags, which means that the default multi-
228 lib will be generated). */
229 /* TODO: determine if these warnings would better be errors. */
231 if (seenPPC
|| seenPPC64
)
232 warning (0, "this compiler does not support PowerPC (arch flags ignored)");
235 if (seenX86_64
|| seenM64
)
236 warning (0, "%s conflicts with i386 (arch flags ignored)",
237 (seenX86_64
? "x86_64": "m64"));
238 else if (! seenM32
) /* Add -m32 if the User didn't. */
243 if (seenX86
|| seenM32
)
244 warning (0, "%s conflicts with x86_64 (arch flags ignored)",
245 (seenX86
? "i386": "m32"));
246 else if (! seenM64
) /* Add -m64 if the User didn't. */
250 if (seenX86
|| seenX86_64
)
251 warning (0, "this compiler does not support X86 (arch flags ignored)");
254 if (seenPPC64
|| seenM64
)
255 warning (0, "%s conflicts with ppc (arch flags ignored)",
256 (seenPPC64
? "ppc64": "m64"));
257 else if (! seenM32
) /* Add -m32 if the User didn't. */
262 if (seenPPC
|| seenM32
)
263 warning (0, "%s conflicts with ppc64 (arch flags ignored)",
264 (seenPPC
? "ppc": "m32"));
265 else if (! seenM64
) /* Add -m64 if the User didn't. */
270 if (appendM32
|| appendM64
)
272 ++*decoded_options_count
;
273 *decoded_options
= XRESIZEVEC (struct cl_decoded_option
,
275 *decoded_options_count
);
276 generate_option (appendM32
? OPT_m32
: OPT_m64
, NULL
, 1, CL_DRIVER
,
277 &(*decoded_options
)[*decoded_options_count
- 1]);
280 /* We will need to know the OS X version we're trying to build for here
281 so that we can figure out the mechanism and source for the sysroot to
283 if (! seen_version_min
&& *decoded_options_count
> 1)
285 /* Not set by the User, try to figure it out. */
286 vers_string
= darwin_default_min_version ();
287 if (vers_string
!= NULL
)
289 ++*decoded_options_count
;
290 *decoded_options
= XRESIZEVEC (struct cl_decoded_option
,
292 *decoded_options_count
);
293 generate_option (OPT_mmacosx_version_min_
, vers_string
, 1, CL_DRIVER
,
294 &(*decoded_options
)[*decoded_options_count
- 1]);