Mercurial > hg > CbC > CbC_gcc
diff gcc/config/darwin-driver.c @ 111:04ced10e8804
gcc 7
author | kono |
---|---|
date | Fri, 27 Oct 2017 22:46:09 +0900 |
parents | f6334be47118 |
children | 84e7813d76e9 |
line wrap: on
line diff
--- a/gcc/config/darwin-driver.c Sun Aug 21 07:07:55 2011 +0900 +++ b/gcc/config/darwin-driver.c Fri Oct 27 22:46:09 2017 +0900 @@ -1,5 +1,5 @@ /* Additional functions for the GCC driver on Darwin native. - Copyright (C) 2006, 2007, 2008, 2010 Free Software Foundation, Inc. + Copyright (C) 2006-2017 Free Software Foundation, Inc. Contributed by Apple Computer Inc. This file is part of GCC. @@ -19,68 +19,26 @@ <http://www.gnu.org/licenses/>. */ #include "config.h" +#include "libiberty.h" #include "system.h" #include "coretypes.h" #include "tm.h" -#include "gcc.h" #include "opts.h" +#include "diagnostic-core.h" #ifndef CROSS_DIRECTORY_STRUCTURE #include <sys/sysctl.h> #include "xregex.h" -/* When running on a Darwin system and using that system's headers and - libraries, default the -mmacosx-version-min flag to be the version - of the system on which the compiler is running. */ - -static void -darwin_default_min_version (unsigned int *decoded_options_count, - struct cl_decoded_option **decoded_options) +static char * +darwin_find_version_from_kernel (void) { - const unsigned int argc = *decoded_options_count; - struct cl_decoded_option *const argv = *decoded_options; - unsigned int i; char osversion[32]; size_t osversion_len = sizeof (osversion) - 1; static int osversion_name[2] = { CTL_KERN, KERN_OSRELEASE }; + int major_vers; char * version_p; - char * version_pend; - int major_vers; - char minor_vers[6]; - static char new_flag[sizeof ("10.0.0") + 6]; - - /* If the command-line is empty, just return. */ - if (argc <= 1) - return; - - /* Don't do this if the user specified -mmacosx-version-min= or - -mno-macosx-version-min. */ - for (i = 1; i < argc; i++) - if (argv[i].opt_index == OPT_mmacosx_version_min_) - return; - - /* Retrieve the deployment target from the environment and insert - it as a flag. */ - { - const char * macosx_deployment_target; - macosx_deployment_target = getenv ("MACOSX_DEPLOYMENT_TARGET"); - if (macosx_deployment_target - /* Apparently, an empty string for MACOSX_DEPLOYMENT_TARGET means - "use the default". Or, possibly "use 10.1". We choose - to ignore the environment variable, as if it was never set. */ - && macosx_deployment_target[0]) - { - ++*decoded_options_count; - *decoded_options = XNEWVEC (struct cl_decoded_option, - *decoded_options_count); - (*decoded_options)[0] = argv[0]; - generate_option (OPT_mmacosx_version_min_, macosx_deployment_target, - 1, CL_DRIVER, &(*decoded_options)[1]); - memcpy (*decoded_options + 2, argv + 1, - (argc - 1) * sizeof (struct cl_decoded_option)); - return; - } - } + char * new_flag; /* Determine the version of the running OS. If we can't, warn user, and do nothing. */ @@ -88,7 +46,7 @@ &osversion_len, NULL, 0) == -1) { warning (0, "sysctl for kern.osversion failed: %m"); - return; + return NULL; } /* Try to parse the first two parts of the OS version number. Warn @@ -99,47 +57,73 @@ version_p = osversion + 1; if (ISDIGIT (*version_p)) major_vers = major_vers * 10 + (*version_p++ - '0'); - if (major_vers > 4 + 9) - goto parse_failed; if (*version_p++ != '.') goto parse_failed; - version_pend = strchr(version_p, '.'); - if (!version_pend) - goto parse_failed; - if (! ISDIGIT (*version_p)) - goto parse_failed; - strncpy(minor_vers, version_p, version_pend - version_p); - minor_vers[version_pend - version_p] = '\0'; /* The major kernel version number is 4 plus the second OS version component. */ if (major_vers - 4 <= 4) /* On 10.4 and earlier, the old linker is used which does not - support three-component system versions. */ - sprintf (new_flag, "10.%d", major_vers - 4); + support three-component system versions. + FIXME: we should not assume this - a newer linker could be used. */ + asprintf (&new_flag, "10.%d", major_vers - 4); else - sprintf (new_flag, "10.%d.%s", major_vers - 4, - minor_vers); + /* Although the newer linker supports three-component system + versions, there's no guarantee that the minor version component + of the kernel and the system are the same. Apple's clang always + uses 0 as the minor version: do the same. */ + asprintf (&new_flag, "10.%d.0", major_vers - 4); - /* Add the new flag. */ - ++*decoded_options_count; - *decoded_options = XNEWVEC (struct cl_decoded_option, - *decoded_options_count); - (*decoded_options)[0] = argv[0]; - generate_option (OPT_mmacosx_version_min_, new_flag, - 1, CL_DRIVER, &(*decoded_options)[1]); - memcpy (*decoded_options + 2, argv + 1, - (argc - 1) * sizeof (struct cl_decoded_option)); - return; - + return new_flag; + parse_failed: warning (0, "couldn%'t understand kern.osversion %q.*s", (int) osversion_len, osversion); - return; + return NULL; } +#endif +/* When running on a Darwin system and using that system's headers and + libraries, default the -mmacosx-version-min flag to be the version + of the system on which the compiler is running. + + When building cross or native cross compilers, default to the OSX + version of the target (as provided by the most specific target header + included in tm.h). This may be overidden by setting the flag explicitly + (or by the MACOSX_DEPLOYMENT_TARGET environment). */ + +static const char * +darwin_default_min_version (void) +{ + /* Try to retrieve the deployment target from the environment. */ + const char *new_flag = getenv ("MACOSX_DEPLOYMENT_TARGET"); + + /* Apparently, an empty string for MACOSX_DEPLOYMENT_TARGET means + "use the default". Or, possibly "use 10.1". We choose + to ignore the environment variable, as if it was never set. */ + if (new_flag == NULL || new_flag[0] == 0) +#ifndef CROSS_DIRECTORY_STRUCTURE + /* Try to find the version from the kernel, if we fail - we print a + message and give up. */ + new_flag = darwin_find_version_from_kernel (); +#else + /* For cross-compilers, default to a minimum version determined by + the configuration. */ + new_flag = DEF_MIN_OSX_VERSION; #endif /* CROSS_DIRECTORY_STRUCTURE */ + if (new_flag != NULL) + { + size_t len = strlen (new_flag); + if (len > 128) { /* Arbitrary limit, number should be like xx.yy.zz */ + warning (0, "couldn%'t understand version %s\n", new_flag); + return NULL; + } + new_flag = xstrndup (new_flag, len); + } + return new_flag; +} + /* Translate -filelist and -framework options in *DECODED_OPTIONS (size *DECODED_OPTIONS_COUNT) to use -Xlinker so that they are considered to be linker inputs in the case that no other inputs are @@ -154,13 +138,58 @@ struct cl_decoded_option **decoded_options) { unsigned int i; + bool seenX86 = false; + bool seenX86_64 = false; + bool seenPPC = false; + bool seenPPC64 = false; + bool seenM32 = false; + bool seenM64 = false; + bool appendM32 = false; + bool appendM64 = false; + const char *vers_string = NULL; + bool seen_version_min = false; for (i = 1; i < *decoded_options_count; i++) { if ((*decoded_options)[i].errors & CL_ERR_MISSING_ARG) continue; + switch ((*decoded_options)[i].opt_index) { + case OPT_arch: + /* Support provision of a single -arch xxxx flag as a means of + specifying the sub-target/multi-lib. Translate this into -m32/64 + as appropriate. */ + if (!strcmp ((*decoded_options)[i].arg, "i386")) + seenX86 = true; + else if (!strcmp ((*decoded_options)[i].arg, "x86_64")) + seenX86_64 = true; + else if (!strcmp ((*decoded_options)[i].arg, "ppc")) + seenPPC = true; + else if (!strcmp ((*decoded_options)[i].arg, "ppc64")) + seenPPC64 = true; + else + error ("this compiler does not support %s", + (*decoded_options)[i].arg); + /* Now we've examined it, drop the -arch arg. */ + if (*decoded_options_count > i) { + memmove (*decoded_options + i, + *decoded_options + i + 1, + ((*decoded_options_count - i) + * sizeof (struct cl_decoded_option))); + } + --i; + --*decoded_options_count; + break; + + case OPT_m32: + seenM32 = true; + break; + + case OPT_m64: + seenM64 = true; + break; + case OPT_filelist: case OPT_framework: ++*decoded_options_count; @@ -178,12 +207,111 @@ CL_DRIVER, &(*decoded_options)[i]); break; + case OPT_mmacosx_version_min_: + seen_version_min = true; + vers_string = xstrndup ((*decoded_options)[i].arg, 32); + default: break; } } -#ifndef CROSS_DIRECTORY_STRUCTURE - darwin_default_min_version (decoded_options_count, decoded_options); + /* Turn -arch xxxx into the appropriate -m32/-m64 flag. + If the User tried to specify multiple arch flags (which is possible with + some Darwin compilers) warn that this mode is not supported by this + compiler (and ignore the arch flags, which means that the default multi- + lib will be generated). */ + /* TODO: determine if these warnings would better be errors. */ +#if DARWIN_X86 + if (seenPPC || seenPPC64) + warning (0, "this compiler does not support PowerPC (arch flags ignored)"); + if (seenX86) + { + if (seenX86_64 || seenM64) + warning (0, "%s conflicts with i386 (arch flags ignored)", + (seenX86_64? "x86_64": "m64")); + else if (! seenM32) /* Add -m32 if the User didn't. */ + appendM32 = true; + } + else if (seenX86_64) + { + if (seenX86 || seenM32) + warning (0, "%s conflicts with x86_64 (arch flags ignored)", + (seenX86? "i386": "m32")); + else if (! seenM64) /* Add -m64 if the User didn't. */ + appendM64 = true; + } +#elif DARWIN_PPC + if (seenX86 || seenX86_64) + warning (0, "this compiler does not support X86 (arch flags ignored)"); + if (seenPPC) + { + if (seenPPC64 || seenM64) + warning (0, "%s conflicts with ppc (arch flags ignored)", + (seenPPC64? "ppc64": "m64")); + else if (! seenM32) /* Add -m32 if the User didn't. */ + appendM32 = true; + } + else if (seenPPC64) + { + if (seenPPC || seenM32) + warning (0, "%s conflicts with ppc64 (arch flags ignored)", + (seenPPC? "ppc": "m32")); + else if (! seenM64) /* Add -m64 if the User didn't. */ + appendM64 = true; + } #endif + + if (appendM32 || appendM64) + { + ++*decoded_options_count; + *decoded_options = XRESIZEVEC (struct cl_decoded_option, + *decoded_options, + *decoded_options_count); + generate_option (appendM32 ? OPT_m32 : OPT_m64, NULL, 1, CL_DRIVER, + &(*decoded_options)[*decoded_options_count - 1]); + } + + /* We will need to know the OS X version we're trying to build for here + so that we can figure out the mechanism and source for the sysroot to + be used. */ + if (! seen_version_min && *decoded_options_count > 1) + { + /* Not set by the User, try to figure it out. */ + vers_string = darwin_default_min_version (); + if (vers_string != NULL) + { + ++*decoded_options_count; + *decoded_options = XRESIZEVEC (struct cl_decoded_option, + *decoded_options, + *decoded_options_count); + generate_option (OPT_mmacosx_version_min_, vers_string, 1, CL_DRIVER, + &(*decoded_options)[*decoded_options_count - 1]); + } + } + /* Create and push the major version for assemblers that need it. */ + if (vers_string != NULL) + { + char *asm_major = NULL; + const char *first_period = strchr(vers_string, '.'); + if (first_period != NULL) + { + const char *second_period = strchr(first_period+1, '.'); + if (second_period != NULL) + asm_major = xstrndup (vers_string, second_period-vers_string); + else + asm_major = xstrdup (vers_string); + } + /* Else we appear to have a weird macosx version with no major number. + Punt on this for now. */ + if (asm_major != NULL) + { + ++*decoded_options_count; + *decoded_options = XRESIZEVEC (struct cl_decoded_option, + *decoded_options, + *decoded_options_count); + generate_option (OPT_asm_macosx_version_min_, asm_major, 1, CL_DRIVER, + &(*decoded_options)[*decoded_options_count - 1]); + } + } }