1/* Additional functions for the GCC driver on Darwin native. 2 Copyright (C) 2006-2015 Free Software Foundation, Inc. 3 Contributed by Apple Computer Inc. 4 5This file is part of GCC. 6 7GCC is free software; you can redistribute it and/or modify 8it under the terms of the GNU General Public License as published by 9the Free Software Foundation; either version 3, or (at your option) 10any later version. 11 12GCC is distributed in the hope that it will be useful, 13but WITHOUT ANY WARRANTY; without even the implied warranty of 14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15GNU General Public License for more details. 16 17You should have received a copy of the GNU General Public License 18along 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 32static char * 33darwin_find_version_from_kernel (void) 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 char * new_flag; 43 44 /* Determine the version of the running OS. If we can't, warn user, 45 and do nothing. */ 46 if (sysctl (osversion_name, ARRAY_SIZE (osversion_name), osversion, 47 &osversion_len, NULL, 0) == -1) 48 { 49 warning (0, "sysctl for kern.osversion failed: %m"); 50 return NULL; 51 } 52 53 /* Try to parse the first two parts of the OS version number. Warn 54 user and return if it doesn't make sense. */ 55 if (! ISDIGIT (osversion[0])) 56 goto parse_failed; 57 major_vers = osversion[0] - '0'; 58 version_p = osversion + 1; 59 if (ISDIGIT (*version_p)) 60 major_vers = major_vers * 10 + (*version_p++ - '0'); 61 if (*version_p++ != '.') 62 goto parse_failed; 63 version_pend = strchr(version_p, '.'); 64 if (!version_pend) 65 goto parse_failed; 66 if (! ISDIGIT (*version_p)) 67 goto parse_failed; 68 strncpy(minor_vers, version_p, version_pend - version_p); 69 minor_vers[version_pend - version_p] = '\0'; 70 71 /* The major kernel version number is 4 plus the second OS version 72 component. */ 73 if (major_vers - 4 <= 4) 74 /* On 10.4 and earlier, the old linker is used which does not 75 support three-component system versions. */ 76 asprintf (&new_flag, "10.%d", major_vers - 4); 77 else 78 asprintf (&new_flag, "10.%d.%s", major_vers - 4, minor_vers); 79 80 return new_flag; 81 82 parse_failed: 83 warning (0, "couldn%'t understand kern.osversion %q.*s", 84 (int) osversion_len, osversion); 85 return NULL; 86} 87 88#endif 89 90/* When running on a Darwin system and using that system's headers and 91 libraries, default the -mmacosx-version-min flag to be the version 92 of the system on which the compiler is running. 93 94 When building cross or native cross compilers, default to the OSX 95 version of the target (as provided by the most specific target header 96 included in tm.h). This may be overidden by setting the flag explicitly 97 (or by the MACOSX_DEPLOYMENT_TARGET environment). */ 98 99static void 100darwin_default_min_version (unsigned int *decoded_options_count, 101 struct cl_decoded_option **decoded_options) 102{ 103 const unsigned int argc = *decoded_options_count; 104 struct cl_decoded_option *const argv = *decoded_options; 105 unsigned int i; 106 const char *new_flag; 107 108 /* If the command-line is empty, just return. */ 109 if (argc <= 1) 110 return; 111 112 /* Don't do this if the user specified -mmacosx-version-min= or 113 -mno-macosx-version-min. */ 114 for (i = 1; i < argc; i++) 115 if (argv[i].opt_index == OPT_mmacosx_version_min_) 116 return; 117 118 /* Retrieve the deployment target from the environment and insert 119 it as a flag. */ 120 { 121 const char * macosx_deployment_target; 122 macosx_deployment_target = getenv ("MACOSX_DEPLOYMENT_TARGET"); 123 if (macosx_deployment_target 124 /* Apparently, an empty string for MACOSX_DEPLOYMENT_TARGET means 125 "use the default". Or, possibly "use 10.1". We choose 126 to ignore the environment variable, as if it was never set. */ 127 && macosx_deployment_target[0]) 128 { 129 ++*decoded_options_count; 130 *decoded_options = XNEWVEC (struct cl_decoded_option, 131 *decoded_options_count); 132 (*decoded_options)[0] = argv[0]; 133 generate_option (OPT_mmacosx_version_min_, macosx_deployment_target, 134 1, CL_DRIVER, &(*decoded_options)[1]); 135 memcpy (*decoded_options + 2, argv + 1, 136 (argc - 1) * sizeof (struct cl_decoded_option)); 137 return; 138 } 139 } 140 141#ifndef CROSS_DIRECTORY_STRUCTURE 142 143 /* Try to find the version from the kernel, if we fail - we print a message 144 and give up. */ 145 new_flag = darwin_find_version_from_kernel (); 146 if (!new_flag) 147 return; 148 149#else 150 151 /* For cross-compilers, default to the target OS version. */ 152 new_flag = DEF_MIN_OSX_VERSION; 153 154#endif /* CROSS_DIRECTORY_STRUCTURE */ 155 156 /* Add the new flag. */ 157 ++*decoded_options_count; 158 *decoded_options = XNEWVEC (struct cl_decoded_option, 159 *decoded_options_count); 160 (*decoded_options)[0] = argv[0]; 161 generate_option (OPT_mmacosx_version_min_, new_flag, 162 1, CL_DRIVER, &(*decoded_options)[1]); 163 memcpy (*decoded_options + 2, argv + 1, 164 (argc - 1) * sizeof (struct cl_decoded_option)); 165 return; 166} 167 168/* Translate -filelist and -framework options in *DECODED_OPTIONS 169 (size *DECODED_OPTIONS_COUNT) to use -Xlinker so that they are 170 considered to be linker inputs in the case that no other inputs are 171 specified. Handling these options in DRIVER_SELF_SPECS does not 172 suffice because specs are too late to add linker inputs, and 173 handling them in LINK_SPEC does not suffice because the linker will 174 not be called if there are no other inputs. When native, also 175 default the -mmacosx-version-min flag. */ 176 177void 178darwin_driver_init (unsigned int *decoded_options_count, 179 struct cl_decoded_option **decoded_options) 180{ 181 unsigned int i; 182 183 for (i = 1; i < *decoded_options_count; i++) 184 { 185 if ((*decoded_options)[i].errors & CL_ERR_MISSING_ARG) 186 continue; 187 switch ((*decoded_options)[i].opt_index) 188 { 189#if DARWIN_X86 190 case OPT_arch: 191 if (!strcmp ((*decoded_options)[i].arg, "i386")) 192 generate_option (OPT_m32, NULL, 1, CL_DRIVER, &(*decoded_options)[i]); 193 else if (!strcmp ((*decoded_options)[i].arg, "x86_64")) 194 generate_option (OPT_m64, NULL, 1, CL_DRIVER, &(*decoded_options)[i]); 195 break; 196#endif 197 198 case OPT_filelist: 199 case OPT_framework: 200 ++*decoded_options_count; 201 *decoded_options = XRESIZEVEC (struct cl_decoded_option, 202 *decoded_options, 203 *decoded_options_count); 204 memmove (*decoded_options + i + 2, 205 *decoded_options + i + 1, 206 ((*decoded_options_count - i - 2) 207 * sizeof (struct cl_decoded_option))); 208 generate_option (OPT_Xlinker, (*decoded_options)[i].arg, 1, 209 CL_DRIVER, &(*decoded_options)[i + 1]); 210 generate_option (OPT_Xlinker, 211 (*decoded_options)[i].canonical_option[0], 1, 212 CL_DRIVER, &(*decoded_options)[i]); 213 break; 214 215 default: 216 break; 217 } 218 } 219 220 darwin_default_min_version (decoded_options_count, decoded_options); 221} 222