* xvasprintf.c: New file.
[official-gcc.git] / gcc / config / darwin-driver.c
blob541e10bc098b49bf97aa74db262a6a79c952c994
1 /* Additional functions for the GCC driver on Darwin native.
2 Copyright (C) 2006-2014 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 char *
33 darwin_find_version_from_kernel (void)
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;
42 char * new_flag;
44 /* Determine the version of the running OS. If we can't, warn user,
45 and do nothing. */
46 if (sysctl (osversion_name, ARRAY_SIZE (osversion_name), osversion,
47 &osversion_len, NULL, 0) == -1)
49 warning (0, "sysctl for kern.osversion failed: %m");
50 return NULL;
53 /* Try to parse the first two parts of the OS version number. Warn
54 user and return if it doesn't make sense. */
55 if (! ISDIGIT (osversion[0]))
56 goto parse_failed;
57 major_vers = osversion[0] - '0';
58 version_p = osversion + 1;
59 if (ISDIGIT (*version_p))
60 major_vers = major_vers * 10 + (*version_p++ - '0');
61 if (*version_p++ != '.')
62 goto parse_failed;
63 version_pend = strchr(version_p, '.');
64 if (!version_pend)
65 goto parse_failed;
66 if (! ISDIGIT (*version_p))
67 goto parse_failed;
68 strncpy(minor_vers, version_p, version_pend - version_p);
69 minor_vers[version_pend - version_p] = '\0';
71 /* The major kernel version number is 4 plus the second OS version
72 component. */
73 if (major_vers - 4 <= 4)
74 /* On 10.4 and earlier, the old linker is used which does not
75 support three-component system versions. */
76 asprintf (&new_flag, "10.%d", major_vers - 4);
77 else
78 asprintf (&new_flag, "10.%d.%s", major_vers - 4, minor_vers);
80 return new_flag;
82 parse_failed:
83 warning (0, "couldn%'t understand kern.osversion %q.*s",
84 (int) osversion_len, osversion);
85 return NULL;
88 #endif
90 /* When running on a Darwin system and using that system's headers and
91 libraries, default the -mmacosx-version-min flag to be the version
92 of the system on which the compiler is running.
94 When building cross or native cross compilers, default to the OSX
95 version of the target (as provided by the most specific target header
96 included in tm.h). This may be overidden by setting the flag explicitly
97 (or by the MACOSX_DEPLOYMENT_TARGET environment). */
99 static void
100 darwin_default_min_version (unsigned int *decoded_options_count,
101 struct cl_decoded_option **decoded_options)
103 const unsigned int argc = *decoded_options_count;
104 struct cl_decoded_option *const argv = *decoded_options;
105 unsigned int i;
106 const char *new_flag;
108 /* If the command-line is empty, just return. */
109 if (argc <= 1)
110 return;
112 /* Don't do this if the user specified -mmacosx-version-min= or
113 -mno-macosx-version-min. */
114 for (i = 1; i < argc; i++)
115 if (argv[i].opt_index == OPT_mmacosx_version_min_)
116 return;
118 /* Retrieve the deployment target from the environment and insert
119 it as a flag. */
121 const char * macosx_deployment_target;
122 macosx_deployment_target = getenv ("MACOSX_DEPLOYMENT_TARGET");
123 if (macosx_deployment_target
124 /* Apparently, an empty string for MACOSX_DEPLOYMENT_TARGET means
125 "use the default". Or, possibly "use 10.1". We choose
126 to ignore the environment variable, as if it was never set. */
127 && macosx_deployment_target[0])
129 ++*decoded_options_count;
130 *decoded_options = XNEWVEC (struct cl_decoded_option,
131 *decoded_options_count);
132 (*decoded_options)[0] = argv[0];
133 generate_option (OPT_mmacosx_version_min_, macosx_deployment_target,
134 1, CL_DRIVER, &(*decoded_options)[1]);
135 memcpy (*decoded_options + 2, argv + 1,
136 (argc - 1) * sizeof (struct cl_decoded_option));
137 return;
141 #ifndef CROSS_DIRECTORY_STRUCTURE
143 /* Try to find the version from the kernel, if we fail - we print a message
144 and give up. */
145 new_flag = darwin_find_version_from_kernel ();
146 if (!new_flag)
147 return;
149 #else
151 /* For cross-compilers, default to the target OS version. */
152 new_flag = DEF_MIN_OSX_VERSION;
154 #endif /* CROSS_DIRECTORY_STRUCTURE */
156 /* Add the new flag. */
157 ++*decoded_options_count;
158 *decoded_options = XNEWVEC (struct cl_decoded_option,
159 *decoded_options_count);
160 (*decoded_options)[0] = argv[0];
161 generate_option (OPT_mmacosx_version_min_, new_flag,
162 1, CL_DRIVER, &(*decoded_options)[1]);
163 memcpy (*decoded_options + 2, argv + 1,
164 (argc - 1) * sizeof (struct cl_decoded_option));
165 return;
168 /* Translate -filelist and -framework options in *DECODED_OPTIONS
169 (size *DECODED_OPTIONS_COUNT) to use -Xlinker so that they are
170 considered to be linker inputs in the case that no other inputs are
171 specified. Handling these options in DRIVER_SELF_SPECS does not
172 suffice because specs are too late to add linker inputs, and
173 handling them in LINK_SPEC does not suffice because the linker will
174 not be called if there are no other inputs. When native, also
175 default the -mmacosx-version-min flag. */
177 void
178 darwin_driver_init (unsigned int *decoded_options_count,
179 struct cl_decoded_option **decoded_options)
181 unsigned int i;
183 for (i = 1; i < *decoded_options_count; i++)
185 if ((*decoded_options)[i].errors & CL_ERR_MISSING_ARG)
186 continue;
187 switch ((*decoded_options)[i].opt_index)
189 #if DARWIN_X86
190 case OPT_arch:
191 if (!strcmp ((*decoded_options)[i].arg, "i386"))
192 generate_option (OPT_m32, NULL, 1, CL_DRIVER, &(*decoded_options)[i]);
193 else if (!strcmp ((*decoded_options)[i].arg, "x86_64"))
194 generate_option (OPT_m64, NULL, 1, CL_DRIVER, &(*decoded_options)[i]);
195 break;
196 #endif
198 case OPT_filelist:
199 case OPT_framework:
200 ++*decoded_options_count;
201 *decoded_options = XRESIZEVEC (struct cl_decoded_option,
202 *decoded_options,
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]);
213 break;
215 default:
216 break;
220 darwin_default_min_version (decoded_options_count, decoded_options);