PR/56490
[official-gcc.git] / gcc / config / darwin-driver.c
blob41076002308fa7f8d0df62c37e34ded04d80149d
1 /* Additional functions for the GCC driver on Darwin native.
2 Copyright (C) 2006-2013 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 "system.h"
23 #include "coretypes.h"
24 #include "tm.h"
25 #include "gcc.h"
26 #include "opts.h"
28 #ifndef CROSS_DIRECTORY_STRUCTURE
29 #include <sys/sysctl.h>
30 #include "xregex.h"
32 static bool
33 darwin_find_version_from_kernel (char *new_flag)
35 char osversion[32];
36 size_t osversion_len = sizeof (osversion) - 1;
37 static int osversion_name[2] = { CTL_KERN, KERN_OSRELEASE };
38 int major_vers;
39 char minor_vers[6];
40 char * version_p;
41 char * version_pend;
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 false;
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 (major_vers > 4 + 9)
61 goto parse_failed;
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 sprintf (new_flag, "10.%d", major_vers - 4);
78 else
79 sprintf (new_flag, "10.%d.%s", major_vers - 4,
80 minor_vers);
82 return true;
84 parse_failed:
85 warning (0, "couldn%'t understand kern.osversion %q.*s",
86 (int) osversion_len, osversion);
87 return false;
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 void
102 darwin_default_min_version (unsigned int *decoded_options_count,
103 struct cl_decoded_option **decoded_options)
105 const unsigned int argc = *decoded_options_count;
106 struct cl_decoded_option *const argv = *decoded_options;
107 unsigned int i;
108 static char new_flag[sizeof ("10.0.0") + 6];
110 /* If the command-line is empty, just return. */
111 if (argc <= 1)
112 return;
114 /* Don't do this if the user specified -mmacosx-version-min= or
115 -mno-macosx-version-min. */
116 for (i = 1; i < argc; i++)
117 if (argv[i].opt_index == OPT_mmacosx_version_min_)
118 return;
120 /* Retrieve the deployment target from the environment and insert
121 it as a flag. */
123 const char * macosx_deployment_target;
124 macosx_deployment_target = getenv ("MACOSX_DEPLOYMENT_TARGET");
125 if (macosx_deployment_target
126 /* Apparently, an empty string for MACOSX_DEPLOYMENT_TARGET means
127 "use the default". Or, possibly "use 10.1". We choose
128 to ignore the environment variable, as if it was never set. */
129 && macosx_deployment_target[0])
131 ++*decoded_options_count;
132 *decoded_options = XNEWVEC (struct cl_decoded_option,
133 *decoded_options_count);
134 (*decoded_options)[0] = argv[0];
135 generate_option (OPT_mmacosx_version_min_, macosx_deployment_target,
136 1, CL_DRIVER, &(*decoded_options)[1]);
137 memcpy (*decoded_options + 2, argv + 1,
138 (argc - 1) * sizeof (struct cl_decoded_option));
139 return;
143 #ifndef CROSS_DIRECTORY_STRUCTURE
145 /* Try to find the version from the kernel, if we fail - we print a message
146 and give up. */
147 if (!darwin_find_version_from_kernel (new_flag))
148 return;
150 #else
152 /* For cross-compilers, default to the target OS version. */
154 strncpy (new_flag, DEF_MIN_OSX_VERSION, sizeof (new_flag));
156 #endif /* CROSS_DIRECTORY_STRUCTURE */
158 /* Add the new flag. */
159 ++*decoded_options_count;
160 *decoded_options = XNEWVEC (struct cl_decoded_option,
161 *decoded_options_count);
162 (*decoded_options)[0] = argv[0];
163 generate_option (OPT_mmacosx_version_min_, new_flag,
164 1, CL_DRIVER, &(*decoded_options)[1]);
165 memcpy (*decoded_options + 2, argv + 1,
166 (argc - 1) * sizeof (struct cl_decoded_option));
167 return;
171 /* Translate -filelist and -framework options in *DECODED_OPTIONS
172 (size *DECODED_OPTIONS_COUNT) to use -Xlinker so that they are
173 considered to be linker inputs in the case that no other inputs are
174 specified. Handling these options in DRIVER_SELF_SPECS does not
175 suffice because specs are too late to add linker inputs, and
176 handling them in LINK_SPEC does not suffice because the linker will
177 not be called if there are no other inputs. When native, also
178 default the -mmacosx-version-min flag. */
180 void
181 darwin_driver_init (unsigned int *decoded_options_count,
182 struct cl_decoded_option **decoded_options)
184 unsigned int i;
186 for (i = 1; i < *decoded_options_count; i++)
188 if ((*decoded_options)[i].errors & CL_ERR_MISSING_ARG)
189 continue;
190 switch ((*decoded_options)[i].opt_index)
192 #if DARWIN_X86
193 case OPT_arch:
194 if (!strcmp ((*decoded_options)[i].arg, "i386"))
195 generate_option (OPT_m32, NULL, 1, CL_DRIVER, &(*decoded_options)[i]);
196 else if (!strcmp ((*decoded_options)[i].arg, "x86_64"))
197 generate_option (OPT_m64, NULL, 1, CL_DRIVER, &(*decoded_options)[i]);
198 break;
199 #endif
201 case OPT_filelist:
202 case OPT_framework:
203 ++*decoded_options_count;
204 *decoded_options = XRESIZEVEC (struct cl_decoded_option,
205 *decoded_options,
206 *decoded_options_count);
207 memmove (*decoded_options + i + 2,
208 *decoded_options + i + 1,
209 ((*decoded_options_count - i - 2)
210 * sizeof (struct cl_decoded_option)));
211 generate_option (OPT_Xlinker, (*decoded_options)[i].arg, 1,
212 CL_DRIVER, &(*decoded_options)[i + 1]);
213 generate_option (OPT_Xlinker,
214 (*decoded_options)[i].canonical_option[0], 1,
215 CL_DRIVER, &(*decoded_options)[i]);
216 break;
218 default:
219 break;
223 darwin_default_min_version (decoded_options_count, decoded_options);