1 1.1 mrg /* Additional functions for the GCC driver on Darwin native. 2 1.1 mrg Copyright (C) 2006-2022 Free Software Foundation, Inc. 3 1.1 mrg Contributed by Apple Computer Inc. 4 1.1 mrg 5 1.1 mrg This file is part of GCC. 6 1.1 mrg 7 1.1 mrg GCC is free software; you can redistribute it and/or modify 8 1.1 mrg it under the terms of the GNU General Public License as published by 9 1.1 mrg the Free Software Foundation; either version 3, or (at your option) 10 1.1 mrg any later version. 11 1.1 mrg 12 1.1 mrg GCC is distributed in the hope that it will be useful, 13 1.1 mrg but WITHOUT ANY WARRANTY; without even the implied warranty of 14 1.1 mrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 1.1 mrg GNU General Public License for more details. 16 1.1 mrg 17 1.1 mrg You should have received a copy of the GNU General Public License 18 1.1 mrg along with GCC; see the file COPYING3. If not see 19 1.1 mrg <http://www.gnu.org/licenses/>. */ 20 1.1 mrg 21 1.1 mrg #include "config.h" 22 1.1 mrg #include "libiberty.h" 23 1.1 mrg #include "system.h" 24 1.1 mrg #include "coretypes.h" 25 1.1 mrg #include "tm.h" 26 1.1 mrg #include "opts.h" 27 1.1 mrg #include "diagnostic-core.h" 28 1.1 mrg 29 1.1 mrg /* Validate a version string (either given on the command line or, perhaps 30 1.1 mrg as MACOSX_DEPLOYMENT_TARGET). 31 1.1 mrg 32 1.1 mrg The specs %version-compare() function doesn't accept leading '0' on 33 1.1 mrg numbers so strip them out. Do sanity checking here too. 34 1.1 mrg 35 1.1 mrg Return: 36 1.1 mrg * original string means it was OK and we didn't want to change it. 37 1.1 mrg * new string means it was OK but we rewrote it to avoid possible format 38 1.1 mrg problems. 39 1.1 mrg * NULL means we didn't like what we saw. 40 1.1 mrg */ 41 1.1 mrg 42 1.1 mrg static const char * 43 1.1 mrg validate_macosx_version_min (const char *version_str) 44 1.1 mrg { 45 1.1 mrg size_t version_len; 46 1.1 mrg unsigned long major, minor = 0, tiny = 0; 47 1.1 mrg char *end; 48 1.1 mrg const char *old_version = version_str; 49 1.1 mrg bool need_rewrite = false; 50 1.1 mrg 51 1.1 mrg version_len = strlen (version_str); 52 1.1 mrg if (version_len < 2) /* The minimum would be 11 */ 53 1.1 mrg return NULL; 54 1.1 mrg 55 1.1 mrg /* Version string must consist of digits and periods only. */ 56 1.1 mrg if (strspn (version_str, "0123456789.") != version_len) 57 1.1 mrg return NULL; 58 1.1 mrg 59 1.1 mrg if (!ISDIGIT (version_str[0]) || !ISDIGIT (version_str[version_len - 1])) 60 1.1 mrg return NULL; 61 1.1 mrg 62 1.1 mrg if (version_str[0] == '0') 63 1.1 mrg need_rewrite = true; 64 1.1 mrg 65 1.1 mrg major = strtoul (version_str, &end, 10); 66 1.1 mrg 67 1.1 mrg /* macOS 10, 11, and 12 are known. clang accepts up to 99. */ 68 1.1 mrg if (major < 10 || major > 99) 69 1.1 mrg return NULL; 70 1.1 mrg 71 1.1 mrg /* Skip a separating period, if there's one. */ 72 1.1 mrg version_str = end + ((*end == '.') ? 1 : 0); 73 1.1 mrg 74 1.1 mrg if (major > 10 && *end != '\0' && !ISDIGIT (version_str[0])) 75 1.1 mrg /* For macOS 11+, we allow just the major number, but if the minor is 76 1.1 mrg there it must be numeric. */ 77 1.1 mrg return NULL; 78 1.1 mrg else if (major > 10 && *end == '\0') 79 1.1 mrg /* We will rewrite 11 => 11.0.0. */ 80 1.1 mrg need_rewrite = true; 81 1.1 mrg else if (major == 10 && (*end == '\0' || !ISDIGIT (version_str[0]))) 82 1.1 mrg /* Otherwise, minor version components must be present and numeric. */ 83 1.1 mrg return NULL; 84 1.1 mrg 85 1.1 mrg /* If we have one or more leading zeros on a component, then rewrite the 86 1.1 mrg version string. */ 87 1.1 mrg if (*end != '\0' && version_str[0] == '0' && version_str[1] != '\0' 88 1.1 mrg && version_str[1] != '.') 89 1.1 mrg need_rewrite = true; 90 1.1 mrg 91 1.1 mrg minor = strtoul (version_str, &end, 10); 92 1.1 mrg version_str = end + ((*end == '.') ? 1 : 0); 93 1.1 mrg if (minor > 99) 94 1.1 mrg return NULL; 95 1.1 mrg 96 1.1 mrg /* If 'tiny' is present it must be numeric. */ 97 1.1 mrg if (*end != '\0' && !ISDIGIT (version_str[0])) 98 1.1 mrg return NULL; 99 1.1 mrg 100 1.1 mrg /* If we have one or more leading zeros on a component, then rewrite the 101 1.1 mrg version string. */ 102 1.1 mrg if (*end != '\0' && version_str[0] == '0' 103 1.1 mrg && version_str[1] != '\0') 104 1.1 mrg need_rewrite = true; 105 1.1 mrg 106 1.1 mrg tiny = strtoul (version_str, &end, 10); 107 1.1 mrg if (tiny > 99) 108 1.1 mrg return NULL; 109 1.1 mrg 110 1.1 mrg /* Version string must contain no more than three tokens. */ 111 1.1 mrg if (*end != '\0') 112 1.1 mrg return NULL; 113 1.1 mrg 114 1.1 mrg if (need_rewrite) 115 1.1 mrg { 116 1.1 mrg char *new_version; 117 1.1 mrg asprintf (&new_version, "%2lu.%lu.%lu", major, minor, tiny); 118 1.1 mrg return new_version; 119 1.1 mrg } 120 1.1 mrg 121 1.1 mrg return old_version; 122 1.1 mrg } 123 1.1 mrg 124 1.1 mrg #ifndef CROSS_DIRECTORY_STRUCTURE 125 1.1 mrg #include <sys/sysctl.h> 126 1.1 mrg #include "xregex.h" 127 1.1 mrg 128 1.1 mrg /* Determine the version of the running OS. 129 1.1 mrg We only look at the first two components (ignoring the patch one) and 130 1.1 mrg report NN.MM.0 where NN is currently either 10 or 11 and MM is the OS 131 1.1 mrg minor release number. 132 1.1 mrg If we can't parse what the kernel gives us, warn the user, and do nothing. */ 133 1.1 mrg 134 1.1 mrg static char * 135 1.1 mrg darwin_find_version_from_kernel (void) 136 1.1 mrg { 137 1.1 mrg char osversion[32]; 138 1.1 mrg size_t osversion_len = sizeof (osversion) - 1; 139 1.1 mrg static int osversion_name[2] = { CTL_KERN, KERN_OSRELEASE }; 140 1.1 mrg int major_vers; 141 1.1 mrg char * version_p; 142 1.1 mrg char * new_flag; 143 1.1 mrg 144 1.1 mrg if (sysctl (osversion_name, ARRAY_SIZE (osversion_name), osversion, 145 1.1 mrg &osversion_len, NULL, 0) == -1) 146 1.1 mrg { 147 1.1 mrg warning (0, "%<sysctl%> for %<kern.osversion%> failed: %m"); 148 1.1 mrg return NULL; 149 1.1 mrg } 150 1.1 mrg 151 1.1 mrg /* Try to parse the first two parts of the OS version number. Warn 152 1.1 mrg user and return if it doesn't make sense. */ 153 1.1 mrg if (! ISDIGIT (osversion[0])) 154 1.1 mrg goto parse_failed; 155 1.1 mrg major_vers = osversion[0] - '0'; 156 1.1 mrg version_p = osversion + 1; 157 1.1 mrg if (ISDIGIT (*version_p)) 158 1.1 mrg major_vers = major_vers * 10 + (*version_p++ - '0'); 159 1.1 mrg if (*version_p++ != '.') 160 1.1 mrg goto parse_failed; 161 1.1 mrg 162 1.1 mrg /* Darwin20 sees a transition to macOS 11. In this, it seems that the 163 1.1 mrg mapping to macOS minor version and patch level is now always 0, 0 164 1.1 mrg (at least for macOS 11 and 12). */ 165 1.1 mrg if (major_vers >= 20) 166 1.1 mrg { 167 1.1 mrg /* Apple clang doesn't include the minor version or the patch level 168 1.1 mrg in the object file, nor does it pass it to ld */ 169 1.1 mrg asprintf (&new_flag, "%d.00.00", major_vers - 9); 170 1.1 mrg } 171 1.1 mrg else if (major_vers - 4 <= 4) 172 1.1 mrg /* On 10.4 and earlier, the old linker is used which does not 173 1.1 mrg support three-component system versions. 174 1.1 mrg FIXME: we should not assume this - a newer linker could be used. */ 175 1.1 mrg asprintf (&new_flag, "10.%d", major_vers - 4); 176 1.1 mrg else 177 1.1 mrg /* Although the newer linker supports three-component system 178 1.1 mrg versions, there's no guarantee that the minor version component 179 1.1 mrg of the kernel and the system are the same. Apple's clang always 180 1.1 mrg uses 0 as the minor version: do the same. */ 181 1.1 mrg asprintf (&new_flag, "10.%d.0", major_vers - 4); 182 1.1 mrg 183 1.1 mrg return new_flag; 184 1.1 mrg 185 1.1 mrg parse_failed: 186 1.1 mrg warning (0, "could not understand %<kern.osversion%> %q.*s", 187 1.1 mrg (int) osversion_len, osversion); 188 1.1 mrg return NULL; 189 1.1 mrg } 190 1.1 mrg #endif 191 1.1 mrg 192 1.1 mrg /* When running on a Darwin system and using that system's headers and 193 1.1 mrg libraries, default the -mmacosx-version-min flag to be the version 194 1.1 mrg of the system on which the compiler is running. 195 1.1 mrg 196 1.1 mrg When building cross or native cross compilers, default to the OSX 197 1.1 mrg version of the target (as provided by the most specific target header 198 1.1 mrg included in tm.h). This may be overidden by setting the flag explicitly 199 1.1 mrg (or by the MACOSX_DEPLOYMENT_TARGET environment). */ 200 1.1 mrg 201 1.1 mrg static const char * 202 1.1 mrg darwin_default_min_version (void) 203 1.1 mrg { 204 1.1 mrg /* Try to retrieve the deployment target from the environment. */ 205 1.1 mrg const char *new_flag = getenv ("MACOSX_DEPLOYMENT_TARGET"); 206 1.1 mrg 207 1.1 mrg /* Apparently, an empty string for MACOSX_DEPLOYMENT_TARGET means 208 1.1 mrg "use the default". Or, possibly "use 10.1". We choose 209 1.1 mrg to ignore the environment variable, as if it was never set. */ 210 1.1 mrg if (new_flag == NULL || new_flag[0] == 0) 211 1.1 mrg #ifndef CROSS_DIRECTORY_STRUCTURE 212 1.1 mrg /* Try to find the version from the kernel, if we fail - we print a 213 1.1 mrg message and give up. */ 214 1.1 mrg new_flag = darwin_find_version_from_kernel (); 215 1.1 mrg #else 216 1.1 mrg /* For cross-compilers, default to a minimum version determined by 217 1.1 mrg the configuration. */ 218 1.1 mrg new_flag = DEF_MIN_OSX_VERSION; 219 1.1 mrg #endif /* CROSS_DIRECTORY_STRUCTURE */ 220 1.1 mrg 221 1.1 mrg if (new_flag != NULL) 222 1.1 mrg { 223 1.1 mrg const char *checked = validate_macosx_version_min (new_flag); 224 1.1 mrg if (checked == NULL) 225 1.1 mrg { 226 1.1 mrg warning (0, "could not understand version %qs", new_flag); 227 1.1 mrg return NULL; 228 1.1 mrg } 229 1.1 mrg new_flag = xstrndup (checked, strlen (checked)); 230 1.1 mrg } 231 1.1 mrg return new_flag; 232 1.1 mrg } 233 1.1 mrg 234 1.1 mrg /* See if we can find the sysroot from the SDKROOT environment variable. */ 235 1.1 mrg 236 1.1 mrg static const char * 237 1.1 mrg maybe_get_sysroot_from_sdkroot () 238 1.1 mrg { 239 1.1 mrg const char *maybe_sysroot = getenv ("SDKROOT"); 240 1.1 mrg 241 1.1 mrg /* We'll use the same rules as the clang driver, for compatibility. 242 1.1 mrg 1) The path must be absolute 243 1.1 mrg 2) Ignore "/", that is the default anyway and we do not want the 244 1.1 mrg sysroot semantics to be applied to it. 245 1.1 mrg 3) It must exist (actually, we'll check it's readable too). */ 246 1.1 mrg 247 1.1 mrg if (maybe_sysroot == NULL 248 1.1 mrg || *maybe_sysroot != '/' 249 1.1 mrg || strlen (maybe_sysroot) == 1 250 1.1 mrg || access (maybe_sysroot, R_OK) == -1) 251 1.1 mrg return NULL; 252 1.1 mrg 253 1.1 mrg return xstrndup (maybe_sysroot, strlen (maybe_sysroot)); 254 1.1 mrg } 255 1.1 mrg 256 1.1 mrg /* Handle the deduction of m32/m64 from -arch flags and the interactions 257 1.1 mrg between them (i.e. try to warn a user who thinks that they have a driver 258 1.1 mrg that can produce multi-slice "FAT" outputs with more than one arch). 259 1.1 mrg Default the -mmacosx-version-min flag, which requires a system call on 260 1.1 mrg native hosts. */ 261 1.1 mrg 262 1.1 mrg void 263 1.1 mrg darwin_driver_init (unsigned int *decoded_options_count, 264 1.1 mrg struct cl_decoded_option **decoded_options) 265 1.1 mrg { 266 1.1 mrg unsigned int i; 267 1.1 mrg bool seenX86 = false; 268 1.1 mrg bool seenX86_64 = false; 269 1.1 mrg bool seenPPC = false; 270 1.1 mrg bool seenPPC64 = false; 271 1.1 mrg bool seenM32 = false; 272 1.1 mrg bool seenM64 = false; 273 1.1 mrg bool appendM32 = false; 274 1.1 mrg bool appendM64 = false; 275 1.1 mrg const char *vers_string = NULL; 276 1.1 mrg bool seen_version_min = false; 277 1.1 mrg bool seen_sysroot_p = false; 278 1.1 mrg bool noexport_p = true; 279 1.1 mrg 280 1.1 mrg for (i = 1; i < *decoded_options_count; i++) 281 1.1 mrg { 282 1.1 mrg if ((*decoded_options)[i].errors & CL_ERR_MISSING_ARG) 283 1.1 mrg continue; 284 1.1 mrg 285 1.1 mrg switch ((*decoded_options)[i].opt_index) 286 1.1 mrg { 287 1.1 mrg case OPT_arch: 288 1.1 mrg /* Support provision of a single -arch xxxx flag as a means of 289 1.1 mrg specifying the sub-target/multi-lib. Translate this into -m32/64 290 1.1 mrg as appropriate. */ 291 1.1 mrg if (!strcmp ((*decoded_options)[i].arg, "i386")) 292 1.1 mrg seenX86 = true; 293 1.1 mrg else if (!strcmp ((*decoded_options)[i].arg, "x86_64")) 294 1.1 mrg seenX86_64 = true; 295 1.1 mrg else if (!strcmp ((*decoded_options)[i].arg, "ppc")) 296 1.1 mrg seenPPC = true; 297 1.1 mrg else if (!strcmp ((*decoded_options)[i].arg, "ppc64")) 298 1.1 mrg seenPPC64 = true; 299 1.1 mrg else 300 1.1 mrg error ("this compiler does not support %qs", 301 1.1 mrg (*decoded_options)[i].arg); 302 1.1 mrg /* Now we've examined it, drop the -arch arg. */ 303 1.1 mrg if (*decoded_options_count > i) { 304 1.1 mrg memmove (*decoded_options + i, 305 1.1 mrg *decoded_options + i + 1, 306 1.1 mrg ((*decoded_options_count - i - 1) 307 1.1 mrg * sizeof (struct cl_decoded_option))); 308 1.1 mrg } 309 1.1 mrg --i; 310 1.1 mrg --*decoded_options_count; 311 1.1 mrg break; 312 1.1 mrg 313 1.1 mrg case OPT_m32: 314 1.1 mrg seenM32 = true; 315 1.1 mrg break; 316 1.1 mrg 317 1.1 mrg case OPT_m64: 318 1.1 mrg seenM64 = true; 319 1.1 mrg break; 320 1.1 mrg 321 1.1 mrg case OPT_mmacosx_version_min_: 322 1.1 mrg seen_version_min = true; 323 1.1 mrg vers_string = 324 1.1 mrg validate_macosx_version_min ((*decoded_options)[i].arg); 325 1.1 mrg if (vers_string == NULL) 326 1.1 mrg warning (0, "%qs is not valid for %<-mmacosx-version-min%>", 327 1.1 mrg (*decoded_options)[i].arg); 328 1.1 mrg else if (vers_string == (*decoded_options)[i].arg) 329 1.1 mrg vers_string = xstrndup ((*decoded_options)[i].arg, 32); 330 1.1 mrg /* Now we've examined it, and verified/re-written, put it to 331 1.1 mrg one side and append later. */ 332 1.1 mrg if (*decoded_options_count > i) { 333 1.1 mrg memmove (*decoded_options + i, 334 1.1 mrg *decoded_options + i + 1, 335 1.1 mrg ((*decoded_options_count - i - 1) 336 1.1 mrg * sizeof (struct cl_decoded_option))); 337 1.1 mrg } 338 1.1 mrg --i; 339 1.1 mrg --*decoded_options_count; 340 1.1 mrg break; 341 1.1 mrg 342 1.1 mrg case OPT__sysroot_: 343 1.1 mrg case OPT_isysroot: 344 1.1 mrg seen_sysroot_p = true; 345 1.1 mrg break; 346 1.1 mrg 347 1.1 mrg case OPT_Xlinker: 348 1.1 mrg case OPT_Wl_: 349 1.1 mrg gcc_checking_assert ((*decoded_options)[i].arg); 350 1.1 mrg if (startswith ((*decoded_options)[i].arg, "-exported_symbol")) 351 1.1 mrg noexport_p = false; 352 1.1 mrg break; 353 1.1 mrg 354 1.1 mrg default: 355 1.1 mrg break; 356 1.1 mrg } 357 1.1 mrg } 358 1.1 mrg 359 1.1 mrg /* Turn -arch xxxx into the appropriate -m32/-m64 flag. 360 1.1 mrg If the User tried to specify multiple arch flags (which is possible with 361 1.1 mrg some Darwin compilers) warn that this mode is not supported by this 362 1.1 mrg compiler. We take arch specifiers that agree with the default multilib 363 1.1 mrg as the first choice and reject others. */ 364 1.1 mrg /* TODO: determine if these warnings would better be errors. */ 365 1.1 mrg #if DARWIN_X86 366 1.1 mrg if (seenPPC || seenPPC64) 367 1.1 mrg warning (0, "this compiler does not support PowerPC" 368 1.1 mrg " (%<-arch%> option ignored)"); 369 1.1 mrg if (seenX86) 370 1.1 mrg { 371 1.1 mrg if (seenX86_64 || seenM64) 372 1.1 mrg { 373 1.1 mrg const char *op = (seenX86_64? "-arch x86_64": "-m64"); 374 1.1 mrg warning (0, "%qs conflicts with %<-arch i386%> (%qs ignored)", 375 1.1 mrg op, op); 376 1.1 mrg } 377 1.1 mrg if (! seenM32) /* Add -m32 if the User didn't. */ 378 1.1 mrg appendM32 = true; 379 1.1 mrg } 380 1.1 mrg else if (seenX86_64) 381 1.1 mrg { 382 1.1 mrg if (seenM32) 383 1.1 mrg warning (0, "%<-m32%> conflicts with %<-arch x86_64%>" 384 1.1 mrg " (%<-m32%> ignored)"); 385 1.1 mrg if (! seenM64) /* Add -m64 if the User didn't. */ 386 1.1 mrg appendM64 = true; 387 1.1 mrg } 388 1.1 mrg #elif DARWIN_PPC 389 1.1 mrg if (seenX86 || seenX86_64) 390 1.1 mrg warning (0, "this compiler does not support x86" 391 1.1 mrg " (%<-arch%> option ignored)"); 392 1.1 mrg if (seenPPC) 393 1.1 mrg { 394 1.1 mrg if (seenPPC64 || seenM64) 395 1.1 mrg { 396 1.1 mrg const char *op = (seenPPC64? "-arch ppc64": "-m64"); 397 1.1 mrg warning (0, "%qs conflicts with %<-arch ppc%> (%qs ignored)", 398 1.1 mrg op, op); 399 1.1 mrg } 400 1.1 mrg if (! seenM32) /* Add -m32 if the User didn't. */ 401 1.1 mrg appendM32 = true; 402 1.1 mrg } 403 1.1 mrg else if (seenPPC64) 404 1.1 mrg { 405 1.1 mrg if (seenM32) 406 1.1 mrg warning (0, "%<-m32%> conflicts with %<-arch ppc64%>" 407 1.1 mrg " (%<-m32%> ignored)"); 408 1.1 mrg if (! seenM64) /* Add -m64 if the User didn't. */ 409 1.1 mrg appendM64 = true; 410 1.1 mrg } 411 1.1 mrg #endif 412 1.1 mrg 413 1.1 mrg /* If there is nothing else on the command line, do not add sysroot etc. */ 414 1.1 mrg if (*decoded_options_count <= 1) 415 1.1 mrg return; 416 1.1 mrg 417 1.1 mrg if (appendM32 || appendM64) 418 1.1 mrg { 419 1.1 mrg ++*decoded_options_count; 420 1.1 mrg *decoded_options = XRESIZEVEC (struct cl_decoded_option, 421 1.1 mrg *decoded_options, 422 1.1 mrg *decoded_options_count); 423 1.1 mrg generate_option (appendM32 ? OPT_m32 : OPT_m64, NULL, 1, CL_DRIVER, 424 1.1 mrg &(*decoded_options)[*decoded_options_count - 1]); 425 1.1 mrg } 426 1.1 mrg 427 1.1 mrg if (!seen_sysroot_p) 428 1.1 mrg { 429 1.1 mrg /* We will pick up an SDKROOT if we didn't specify a sysroot and treat 430 1.1 mrg it as overriding any configure-time --with-sysroot. */ 431 1.1 mrg const char *sdkroot = maybe_get_sysroot_from_sdkroot (); 432 1.1 mrg if (sdkroot) 433 1.1 mrg { 434 1.1 mrg ++*decoded_options_count; 435 1.1 mrg *decoded_options = XRESIZEVEC (struct cl_decoded_option, 436 1.1 mrg *decoded_options, 437 1.1 mrg *decoded_options_count); 438 1.1 mrg generate_option (OPT__sysroot_, sdkroot, 1, CL_DRIVER, 439 1.1 mrg &(*decoded_options)[*decoded_options_count - 1]); 440 1.1 mrg } 441 1.1 mrg } 442 1.1 mrg 443 1.1 mrg /* We will need to know the OS X version we're trying to build for here 444 1.1 mrg so that we can figure out the mechanism and source for the sysroot to 445 1.1 mrg be used. */ 446 1.1 mrg if (!seen_version_min) 447 1.1 mrg /* Not set by the User, try to figure it out. */ 448 1.1 mrg vers_string = darwin_default_min_version (); 449 1.1 mrg 450 1.1 mrg /* Create and push a cleaned up version, plus the major version for 451 1.1 mrg assemblers and other cases that need it. */ 452 1.1 mrg if (vers_string != NULL) 453 1.1 mrg { 454 1.1 mrg ++*decoded_options_count; 455 1.1 mrg *decoded_options = XRESIZEVEC (struct cl_decoded_option, 456 1.1 mrg *decoded_options, 457 1.1 mrg *decoded_options_count); 458 1.1 mrg generate_option (OPT_mmacosx_version_min_, vers_string, 1, CL_DRIVER, 459 1.1 mrg &(*decoded_options)[*decoded_options_count - 1]); 460 1.1 mrg 461 1.1 mrg char *asm_major = NULL; 462 1.1 mrg const char *first_period = strchr(vers_string, '.'); 463 1.1 mrg if (first_period != NULL) 464 1.1 mrg { 465 1.1 mrg const char *second_period = strchr(first_period+1, '.'); 466 1.1 mrg if (second_period != NULL) 467 1.1 mrg asm_major = xstrndup (vers_string, second_period-vers_string); 468 1.1 mrg else 469 1.1 mrg asm_major = xstrdup (vers_string); 470 1.1 mrg } 471 1.1 mrg /* Else we appear to have a weird macosx version with no major number. 472 1.1 mrg Punt on this for now. */ 473 1.1 mrg if (asm_major != NULL) 474 1.1 mrg { 475 1.1 mrg ++*decoded_options_count; 476 1.1 mrg *decoded_options = XRESIZEVEC (struct cl_decoded_option, 477 1.1 mrg *decoded_options, 478 1.1 mrg *decoded_options_count); 479 1.1 mrg generate_option (OPT_asm_macosx_version_min_, asm_major, 1, CL_DRIVER, 480 1.1 mrg &(*decoded_options)[*decoded_options_count - 1]); 481 1.1 mrg } 482 1.1 mrg } 483 1.1 mrg 484 1.1 mrg if (noexport_p) 485 1.1 mrg { 486 1.1 mrg ++*decoded_options_count; 487 1.1 mrg *decoded_options = XRESIZEVEC (struct cl_decoded_option, 488 1.1 mrg *decoded_options, 489 1.1 mrg *decoded_options_count); 490 1.1 mrg generate_option (OPT_nodefaultexport, NULL, 1, CL_DRIVER, 491 1.1 mrg &(*decoded_options)[*decoded_options_count - 1]); 492 1.1 mrg } 493 1.1 mrg } 494