123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222 |
- /* Additional functions for the GCC driver on Darwin native.
- Copyright (C) 2006-2015 Free Software Foundation, Inc.
- Contributed by Apple Computer Inc.
- This file is part of GCC.
- GCC is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3, or (at your option)
- any later version.
- GCC is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with GCC; see the file COPYING3. If not see
- <http://www.gnu.org/licenses/>. */
- #include "config.h"
- #include "system.h"
- #include "coretypes.h"
- #include "tm.h"
- #include "gcc.h"
- #include "opts.h"
- #ifndef CROSS_DIRECTORY_STRUCTURE
- #include <sys/sysctl.h>
- #include "xregex.h"
- static char *
- darwin_find_version_from_kernel (void)
- {
- char osversion[32];
- size_t osversion_len = sizeof (osversion) - 1;
- static int osversion_name[2] = { CTL_KERN, KERN_OSRELEASE };
- int major_vers;
- char minor_vers[6];
- char * version_p;
- char * version_pend;
- char * new_flag;
- /* Determine the version of the running OS. If we can't, warn user,
- and do nothing. */
- if (sysctl (osversion_name, ARRAY_SIZE (osversion_name), osversion,
- &osversion_len, NULL, 0) == -1)
- {
- warning (0, "sysctl for kern.osversion failed: %m");
- return NULL;
- }
- /* Try to parse the first two parts of the OS version number. Warn
- user and return if it doesn't make sense. */
- if (! ISDIGIT (osversion[0]))
- goto parse_failed;
- major_vers = osversion[0] - '0';
- version_p = osversion + 1;
- if (ISDIGIT (*version_p))
- major_vers = major_vers * 10 + (*version_p++ - '0');
- 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. */
- asprintf (&new_flag, "10.%d", major_vers - 4);
- else
- asprintf (&new_flag, "10.%d.%s", major_vers - 4, minor_vers);
- return new_flag;
- parse_failed:
- warning (0, "couldn%'t understand kern.osversion %q.*s",
- (int) osversion_len, osversion);
- 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 void
- darwin_default_min_version (unsigned int *decoded_options_count,
- struct cl_decoded_option **decoded_options)
- {
- const unsigned int argc = *decoded_options_count;
- struct cl_decoded_option *const argv = *decoded_options;
- unsigned int i;
- const char *new_flag;
- /* 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;
- }
- }
- #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 ();
- if (!new_flag)
- return;
- #else
- /* For cross-compilers, default to the target OS version. */
- new_flag = DEF_MIN_OSX_VERSION;
- #endif /* CROSS_DIRECTORY_STRUCTURE */
- /* 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;
- }
- /* 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
- specified. Handling these options in DRIVER_SELF_SPECS does not
- suffice because specs are too late to add linker inputs, and
- handling them in LINK_SPEC does not suffice because the linker will
- not be called if there are no other inputs. When native, also
- default the -mmacosx-version-min flag. */
- void
- darwin_driver_init (unsigned int *decoded_options_count,
- struct cl_decoded_option **decoded_options)
- {
- unsigned int i;
- for (i = 1; i < *decoded_options_count; i++)
- {
- if ((*decoded_options)[i].errors & CL_ERR_MISSING_ARG)
- continue;
- switch ((*decoded_options)[i].opt_index)
- {
- #if DARWIN_X86
- case OPT_arch:
- if (!strcmp ((*decoded_options)[i].arg, "i386"))
- generate_option (OPT_m32, NULL, 1, CL_DRIVER, &(*decoded_options)[i]);
- else if (!strcmp ((*decoded_options)[i].arg, "x86_64"))
- generate_option (OPT_m64, NULL, 1, CL_DRIVER, &(*decoded_options)[i]);
- break;
- #endif
- case OPT_filelist:
- case OPT_framework:
- ++*decoded_options_count;
- *decoded_options = XRESIZEVEC (struct cl_decoded_option,
- *decoded_options,
- *decoded_options_count);
- memmove (*decoded_options + i + 2,
- *decoded_options + i + 1,
- ((*decoded_options_count - i - 2)
- * sizeof (struct cl_decoded_option)));
- generate_option (OPT_Xlinker, (*decoded_options)[i].arg, 1,
- CL_DRIVER, &(*decoded_options)[i + 1]);
- generate_option (OPT_Xlinker,
- (*decoded_options)[i].canonical_option[0], 1,
- CL_DRIVER, &(*decoded_options)[i]);
- break;
- default:
- break;
- }
- }
- darwin_default_min_version (decoded_options_count, decoded_options);
- }
|