OSDN Git Service

gcc/
[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 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
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
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).  */
100
101 static void
102 darwin_default_min_version (unsigned int *decoded_options_count,
103                             struct cl_decoded_option **decoded_options)
104 {
105   const unsigned int argc = *decoded_options_count;
106   struct cl_decoded_option *const argv = *decoded_options;
107   unsigned int i;
108   static char new_flag[sizeof ("10.0.0") + 6];
109
110   /* If the command-line is empty, just return.  */
111   if (argc <= 1)
112     return;
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++)
117     if (argv[i].opt_index == OPT_mmacosx_version_min_)
118       return;
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       {
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,
138                 (argc - 1) * sizeof (struct cl_decoded_option));
139         return;
140       }
141   }
142
143 #ifndef CROSS_DIRECTORY_STRUCTURE
144
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 */
157
158   /* Add the new flag.  */
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,
166           (argc - 1) * sizeof (struct cl_decoded_option));
167   return;
168   
169 }
170
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         {
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
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
223   darwin_default_min_version (decoded_options_count, decoded_options);
224 }