OSDN Git Service

PR target/46880
[pf3gnuchains/gcc-fork.git] / gcc / config / darwin-driver.c
1 /* Additional functions for the GCC driver on Darwin native.
2    Copyright (C) 2006, 2007, 2008, 2010 Free Software Foundation, Inc.
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
9 the Free Software Foundation; either version 3, or (at your option)
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
18 along with GCC; see the file COPYING3.  If not see
19 <http://www.gnu.org/licenses/>.  */
20
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "tm.h"
25 #include "gcc.h"
26 #include "opts.h"
27
28 #ifndef CROSS_DIRECTORY_STRUCTURE
29 #include <sys/sysctl.h>
30 #include "xregex.h"
31
32 /* When running on a Darwin system and using that system's headers and
33    libraries, default the -mmacosx-version-min flag to be the version
34    of the system on which the compiler is running.  */
35
36 static void
37 darwin_default_min_version (unsigned int *decoded_options_count,
38                             struct cl_decoded_option **decoded_options)
39 {
40   const unsigned int argc = *decoded_options_count;
41   struct cl_decoded_option *const argv = *decoded_options;
42   unsigned int i;
43   char osversion[32];
44   size_t osversion_len = sizeof (osversion) - 1;
45   static int osversion_name[2] = { CTL_KERN, KERN_OSRELEASE };
46   char * version_p;
47   char * version_pend;
48   int major_vers;
49   char minor_vers[6];
50   static char new_flag[sizeof ("10.0.0") + 6];
51
52   /* If the command-line is empty, just return.  */
53   if (argc <= 1)
54     return;
55   
56   /* Don't do this if the user specified -mmacosx-version-min= or
57      -mno-macosx-version-min.  */
58   for (i = 1; i < argc; i++)
59     if (argv[i].opt_index == OPT_mmacosx_version_min_)
60       return;
61
62   /* Retrieve the deployment target from the environment and insert
63      it as a flag.  */
64   {
65     const char * macosx_deployment_target;
66     macosx_deployment_target = getenv ("MACOSX_DEPLOYMENT_TARGET");
67     if (macosx_deployment_target
68         /* Apparently, an empty string for MACOSX_DEPLOYMENT_TARGET means
69            "use the default".  Or, possibly "use 10.1".  We choose
70            to ignore the environment variable, as if it was never set.  */
71         && macosx_deployment_target[0])
72       {
73         ++*decoded_options_count;
74         *decoded_options = XNEWVEC (struct cl_decoded_option,
75                                     *decoded_options_count);
76         (*decoded_options)[0] = argv[0];
77         generate_option (OPT_mmacosx_version_min_, macosx_deployment_target,
78                          1, CL_DRIVER, &(*decoded_options)[1]);
79         memcpy (*decoded_options + 2, argv + 1,
80                 (argc - 1) * sizeof (struct cl_decoded_option));
81         return;
82       }
83   }
84
85   /* Determine the version of the running OS.  If we can't, warn user,
86      and do nothing.  */
87   if (sysctl (osversion_name, ARRAY_SIZE (osversion_name), osversion,
88               &osversion_len, NULL, 0) == -1)
89     {
90       warning (0, "sysctl for kern.osversion failed: %m");
91       return;
92     }
93
94   /* Try to parse the first two parts of the OS version number.  Warn
95      user and return if it doesn't make sense.  */
96   if (! ISDIGIT (osversion[0]))
97     goto parse_failed;
98   major_vers = osversion[0] - '0';
99   version_p = osversion + 1;
100   if (ISDIGIT (*version_p))
101     major_vers = major_vers * 10 + (*version_p++ - '0');
102   if (major_vers > 4 + 9)
103     goto parse_failed;
104   if (*version_p++ != '.')
105     goto parse_failed;
106   version_pend = strchr(version_p, '.');
107   if (!version_pend)
108     goto parse_failed;
109   if (! ISDIGIT (*version_p))
110     goto parse_failed;
111   strncpy(minor_vers, version_p, version_pend - version_p);
112   minor_vers[version_pend - version_p] = '\0';
113   
114   /* The major kernel version number is 4 plus the second OS version
115      component.  */
116   if (major_vers - 4 <= 4)
117     /* On 10.4 and earlier, the old linker is used which does not
118        support three-component system versions.  */
119     sprintf (new_flag, "10.%d", major_vers - 4);
120   else
121     sprintf (new_flag, "10.%d.%s", major_vers - 4,
122              minor_vers);
123
124   /* Add the new flag.  */
125   ++*decoded_options_count;
126   *decoded_options = XNEWVEC (struct cl_decoded_option,
127                               *decoded_options_count);
128   (*decoded_options)[0] = argv[0];
129   generate_option (OPT_mmacosx_version_min_, new_flag,
130                    1, CL_DRIVER, &(*decoded_options)[1]);
131   memcpy (*decoded_options + 2, argv + 1,
132           (argc - 1) * sizeof (struct cl_decoded_option));
133   return;
134   
135  parse_failed:
136   warning (0, "couldn%'t understand kern.osversion %q.*s",
137            (int) osversion_len, osversion);
138   return;
139 }
140
141 #endif /* CROSS_DIRECTORY_STRUCTURE */
142
143 /* Translate -filelist and -framework options in *DECODED_OPTIONS
144    (size *DECODED_OPTIONS_COUNT) to use -Xlinker so that they are
145    considered to be linker inputs in the case that no other inputs are
146    specified.  Handling these options in DRIVER_SELF_SPECS does not
147    suffice because specs are too late to add linker inputs, and
148    handling them in LINK_SPEC does not suffice because the linker will
149    not be called if there are no other inputs.  When native, also
150    default the -mmacosx-version-min flag.  */
151
152 void
153 darwin_driver_init (unsigned int *decoded_options_count,
154                     struct cl_decoded_option **decoded_options)
155 {
156   unsigned int i;
157
158   for (i = 1; i < *decoded_options_count; i++)
159     {
160       if ((*decoded_options)[i].errors & CL_ERR_MISSING_ARG)
161         continue;
162       switch ((*decoded_options)[i].opt_index)
163         {
164         case OPT_filelist:
165         case OPT_framework:
166           ++*decoded_options_count;
167           *decoded_options = XRESIZEVEC (struct cl_decoded_option,
168                                          *decoded_options,
169                                          *decoded_options_count);
170           memmove (*decoded_options + i + 2,
171                    *decoded_options + i + 1,
172                    ((*decoded_options_count - i - 2)
173                     * sizeof (struct cl_decoded_option)));
174           generate_option (OPT_Xlinker, (*decoded_options)[i].arg, 1,
175                            CL_DRIVER, &(*decoded_options)[i + 1]);
176           generate_option (OPT_Xlinker,
177                            (*decoded_options)[i].canonical_option[0], 1,
178                            CL_DRIVER, &(*decoded_options)[i]);
179           break;
180
181         default:
182           break;
183         }
184     }
185
186 #ifndef CROSS_DIRECTORY_STRUCTURE
187   darwin_default_min_version (decoded_options_count, decoded_options);
188 #endif
189 }