Home | History | Annotate | Line # | Download | only in config
darwin-driver.cc revision 1.1
      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