/* Additional functions for the GCC driver on Darwin native.
- Copyright (C) 2006, 2007 Free Software Foundation, Inc.
+ Copyright (C) 2006, 2007, 2008, 2010 Free Software Foundation, Inc.
Contributed by Apple Computer Inc.
This file is part of GCC.
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
-#ifndef CROSS_DIRECTORY_STRUCTURE
#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"
-#ifndef SWITCH_TAKES_ARG
-#define SWITCH_TAKES_ARG(CHAR) DEFAULT_SWITCH_TAKES_ARG(CHAR)
-#endif
-
-#ifndef WORD_SWITCH_TAKES_ARG
-#define WORD_SWITCH_TAKES_ARG(STR) DEFAULT_WORD_SWITCH_TAKES_ARG (STR)
-#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. */
-void
-darwin_default_min_version (int * argc_p, char *** argv_p)
+static void
+darwin_default_min_version (unsigned int *decoded_options_count,
+ struct cl_decoded_option **decoded_options)
{
- const int argc = *argc_p;
- char ** const argv = *argv_p;
- int i;
+ 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 };
char * version_pend;
int major_vers;
char minor_vers[6];
- static char new_flag[sizeof ("-mmacosx-version-min=10.0.0") + 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 has specified -b or -V at the start
- of the command-line. */
- if (argv[1][0] == '-'
- && (argv[1][1] == 'V' ||
- ((argv[1][1] == 'b') && (NULL != strchr(argv[1] + 2,'-')))))
- 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][0] == '-')
- {
- const char * const p = argv[i];
- if (strncmp (p, "-mno-macosx-version-min", 23) == 0
- || strncmp (p, "-mmacosx-version-min", 20) == 0)
- return;
-
- /* It doesn't count if it's an argument to a different switch. */
- if (p[0] == '-'
- && ((SWITCH_TAKES_ARG (p[1]) > (p[2] != 0))
- || WORD_SWITCH_TAKES_ARG (p + 1)))
- i++;
- }
+ if (argv[i].opt_index == OPT_mmacosx_version_min_)
+ return;
/* Retrieve the deployment target from the environment and insert
it as a flag. */
to ignore the environment variable, as if it was never set. */
&& macosx_deployment_target[0])
{
- ++*argc_p;
- *argv_p = XNEWVEC (char *, *argc_p);
- (*argv_p)[0] = argv[0];
- (*argv_p)[1] = concat ("-mmacosx-version-min=",
- macosx_deployment_target, NULL);
- memcpy (*argv_p + 2, argv + 1, (argc - 1) * sizeof (char *));
+ ++*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;
}
}
if (sysctl (osversion_name, ARRAY_SIZE (osversion_name), osversion,
&osversion_len, NULL, 0) == -1)
{
- fprintf (stderr, "sysctl for kern.osversion failed: %s\n",
- xstrerror (errno));
+ warning (0, "sysctl for kern.osversion failed: %m");
return;
}
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, "-mmacosx-version-min=10.%d", major_vers - 4);
+ sprintf (new_flag, "10.%d", major_vers - 4);
else
- sprintf (new_flag, "-mmacosx-version-min=10.%d.%s", major_vers - 4,
+ sprintf (new_flag, "10.%d.%s", major_vers - 4,
minor_vers);
/* Add the new flag. */
- ++*argc_p;
- *argv_p = XNEWVEC (char *, *argc_p);
- (*argv_p)[0] = argv[0];
- (*argv_p)[1] = new_flag;
- memcpy (*argv_p + 2, argv + 1, (argc - 1) * sizeof (char *));
+ ++*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;
parse_failed:
- fprintf (stderr, "couldn't understand kern.osversion `%.*s'\n",
+ warning (0, "couldn%'t understand kern.osversion %q.*s",
(int) osversion_len, osversion);
return;
}
#endif /* CROSS_DIRECTORY_STRUCTURE */
+
+/* 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;
+ }
+ }
+
+#ifndef CROSS_DIRECTORY_STRUCTURE
+ darwin_default_min_version (decoded_options_count, decoded_options);
+#endif
+}