]>
Commit | Line | Data |
---|---|---|
a9540fb6 | 1 | /* Additional functions for the GCC driver on Darwin native. |
71e45bc2 | 2 | Copyright (C) 2006, 2007, 2008, 2010, 2011 Free Software Foundation, Inc. |
a9540fb6 | 3 | Contributed by Apple Computer Inc. |
4 | ||
5 | This file is part of GCC. | |
6 | ||
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 | |
038d1e19 | 9 | the Free Software Foundation; either version 3, or (at your option) |
a9540fb6 | 10 | any later version. |
11 | ||
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. | |
16 | ||
17 | You should have received a copy of the GNU General Public License | |
038d1e19 | 18 | along with GCC; see the file COPYING3. If not see |
19 | <http://www.gnu.org/licenses/>. */ | |
a9540fb6 | 20 | |
a9540fb6 | 21 | #include "config.h" |
22 | #include "system.h" | |
23 | #include "coretypes.h" | |
24 | #include "tm.h" | |
25 | #include "gcc.h" | |
e62df35b | 26 | #include "opts.h" |
2c2747c3 | 27 | |
28 | #ifndef CROSS_DIRECTORY_STRUCTURE | |
a9540fb6 | 29 | #include <sys/sysctl.h> |
30 | #include "xregex.h" | |
31 | ||
05171267 | 32 | static bool |
33 | darwin_find_version_from_kernel (char *new_flag) | |
34 | { | |
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 | ||
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) | |
47 | { | |
48 | warning (0, "sysctl for kern.osversion failed: %m"); | |
49 | return false; | |
50 | } | |
51 | ||
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'; | |
71 | ||
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); | |
81 | ||
82 | return true; | |
83 | ||
84 | parse_failed: | |
85 | warning (0, "couldn%'t understand kern.osversion %q.*s", | |
86 | (int) osversion_len, osversion); | |
87 | return false; | |
88 | } | |
89 | ||
90 | #endif | |
91 | ||
a9540fb6 | 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 | |
05171267 | 94 | of the system on which the compiler is running. |
95 | ||
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). */ | |
a9540fb6 | 100 | |
2c2747c3 | 101 | static void |
e62df35b | 102 | darwin_default_min_version (unsigned int *decoded_options_count, |
103 | struct cl_decoded_option **decoded_options) | |
a9540fb6 | 104 | { |
e62df35b | 105 | const unsigned int argc = *decoded_options_count; |
106 | struct cl_decoded_option *const argv = *decoded_options; | |
107 | unsigned int i; | |
e62df35b | 108 | static char new_flag[sizeof ("10.0.0") + 6]; |
a9540fb6 | 109 | |
110 | /* If the command-line is empty, just return. */ | |
111 | if (argc <= 1) | |
112 | return; | |
a9540fb6 | 113 | |
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++) | |
e62df35b | 117 | if (argv[i].opt_index == OPT_mmacosx_version_min_) |
118 | return; | |
a9540fb6 | 119 | |
120 | /* Retrieve the deployment target from the environment and insert | |
121 | it as a flag. */ | |
122 | { | |
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]) | |
130 | { | |
e62df35b | 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, | |
1ddf4bfd | 138 | (argc - 1) * sizeof (struct cl_decoded_option)); |
a9540fb6 | 139 | return; |
140 | } | |
141 | } | |
142 | ||
05171267 | 143 | #ifndef CROSS_DIRECTORY_STRUCTURE |
a9540fb6 | 144 | |
05171267 | 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; | |
149 | ||
150 | #else | |
151 | ||
152 | /* For cross-compilers, default to the target OS version. */ | |
153 | ||
154 | strncpy (new_flag, DEF_MIN_OSX_VERSION, sizeof (new_flag)); | |
155 | ||
156 | #endif /* CROSS_DIRECTORY_STRUCTURE */ | |
a9540fb6 | 157 | |
158 | /* Add the new flag. */ | |
e62df35b | 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, | |
1ddf4bfd | 166 | (argc - 1) * sizeof (struct cl_decoded_option)); |
a9540fb6 | 167 | return; |
168 | ||
a9540fb6 | 169 | } |
170 | ||
2c2747c3 | 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. */ | |
179 | ||
180 | void | |
181 | darwin_driver_init (unsigned int *decoded_options_count, | |
182 | struct cl_decoded_option **decoded_options) | |
183 | { | |
184 | unsigned int i; | |
185 | ||
186 | for (i = 1; i < *decoded_options_count; i++) | |
187 | { | |
188 | if ((*decoded_options)[i].errors & CL_ERR_MISSING_ARG) | |
189 | continue; | |
190 | switch ((*decoded_options)[i].opt_index) | |
191 | { | |
22db0e0c | 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 | |
200 | ||
2c2747c3 | 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; | |
217 | ||
218 | default: | |
219 | break; | |
220 | } | |
221 | } | |
222 | ||
2c2747c3 | 223 | darwin_default_min_version (decoded_options_count, decoded_options); |
2c2747c3 | 224 | } |