Example #1
0
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;
      }
  }
Example #2
0
void
lang_specific_driver (cl_decoded_option **in_decoded_options,
		      unsigned int *in_decoded_options_count,
		      int *in_added_libraries)
{
  int i, j;

  /* If nonzero, the user gave us the `-p' or `-pg' flag.  */
  int saw_profile_flag = 0;

  /* Used by -debuglib */
  int saw_debug_flag = 0;

  /* What do with libgphobos:
     -1 means we should not link in libgphobos
     0  means we should link in libgphobos if it is needed
     1  means libgphobos is needed and should be linked in.
     2  means libgphobos is needed and should be linked statically.  */
  int library = 0;

  /* If nonzero, use the standard D runtime library when linking with
     standard libraries. */
  int phobos = 1;

  /* The number of arguments being added to what's in argv, other than
     libraries.  We use this to track the number of times we've inserted
     -xd/-xnone.  */
  int added = 0;

  /* The new argument list will be contained in this.  */
  cl_decoded_option *new_decoded_options;

  /* "-lm" or "-lmath" if it appears on the command line.  */
  const cl_decoded_option *saw_math = 0;

  /* "-lpthread" if it appears on the command line.  */
  const cl_decoded_option *saw_thread = 0;

  /* "-lrt" if it appears on the command line.  */
  const cl_decoded_option *saw_time = 0;

  /* "-lc" if it appears on the command line.  */
  const cl_decoded_option *saw_libc = 0;

  /* "-lstdc++" if it appears on the command line.  */
  const cl_decoded_option *saw_libcxx = 0;

  /* An array used to flag each argument that needs a bit set for
     DSOURCE, MATHLIB, WITHTHREAD, WITHLIBC or WITHLIBCXX.  */
  int *args;

  /* Whether we need the C++ STD library.  */
  int need_stdcxx = 0;

  /* By default, we throw on the math library if we have one.  */
  int need_math = (MATH_LIBRARY[0] != '\0');

  /* Whether we need the thread library.  */
  int need_thread = (THREAD_LIBRARY[0] != '\0');

  /* By default, we throw on the time library if we have one.  */
  int need_time = (TIME_LIBRARY[0] != '\0');

  /* True if we saw -static. */
  int static_link = 0;

  /* True if we should add -shared-libgcc to the command-line.  */
  int shared_libgcc = 1;

  /* The total number of arguments with the new stuff.  */
  int argc;

  /* The argument list.  */
  cl_decoded_option *decoded_options;

  /* What default library to use instead of phobos */
  const char *defaultlib = NULL;

  /* What debug library to use instead of phobos */
  const char *debuglib = NULL;

  /* The number of libraries added in.  */
  int added_libraries;

  /* The total number of arguments with the new stuff.  */
  int num_args = 1;

  /* "-fonly" if it appears on the command line.  */
  const char *only_source_option = 0;

  /* Whether the -o option was used.  */
  int saw_opt_o = 0;

  /* The first input file with an extension of .d.  */
  const char *first_d_file = NULL;

  argc = *in_decoded_options_count;
  decoded_options = *in_decoded_options;
  added_libraries = *in_added_libraries;

  args = XCNEWVEC (int, argc);

  for (i = 1; i < argc; i++)
    {
      const char *arg = decoded_options[i].arg;

      switch (decoded_options[i].opt_index)
	{
	case OPT_nostdlib:
	case OPT_nodefaultlibs:
	  library = -1;
	  break;

	case OPT_nophoboslib:
	  added = 1; // force argument rebuild
	  phobos = 0;
	  args[i] |= SKIPOPT;
	  break;

	case OPT_defaultlib_:
	  added = 1;
	  phobos = 0;
	  args[i] |= SKIPOPT;
	  if (defaultlib != NULL)
	    free (CONST_CAST (char *, defaultlib));
	  if (arg == NULL)
	    error ("missing argument to 'defaultlib=' option");
	  else
	    {
	      defaultlib = XNEWVEC (char, strlen (arg));
	      strcpy (CONST_CAST (char *, defaultlib), arg);
	    }
	  break;

	case OPT_debuglib_:
	  added = 1;
	  phobos = 0;
	  args[i] |= SKIPOPT;
	  if (debuglib != NULL)
	    free (CONST_CAST (char *, debuglib));
	  if (arg == NULL)
	    error ("missing argument to 'debuglib=' option");
	  else
	    {
	      debuglib = XNEWVEC (char, strlen (arg));
	      strcpy (CONST_CAST (char *, debuglib), arg);
	    }
	  break;

	case OPT_l:
	  if ((strcmp (arg, LIBSTDCXX) == 0)
	      || (strcmp (arg, LIBSTDCXX_PROFILE) == 0))
	    {
	      args[i] |= WITHLIBCXX;
	      need_stdcxx = 0;
	    }
	  else if ((strcmp (arg, MATH_LIBRARY) == 0)
		   || (strcmp (arg, MATH_LIBRARY_PROFILE) == 0))
	    {
	      args[i] |= MATHLIB;
	      need_math = 0;
	    }
	  else if (strcmp (arg, THREAD_LIBRARY) == 0)
	    {
	      args[i] |= WITHTHREAD;
	      need_thread = 0;
	    }
	  else if (strcmp (arg, TIME_LIBRARY) == 0)
	    {
	      args[i] |= TIMELIB;
	      need_time = 0;
	    }
	  else if (strcmp (arg, "c") == 0)
	    args[i] |= WITHLIBC;
	  else
	    /* Unrecognized libraries (e.g. -ltango) may require libphobos.  */
	    library = (library == 0) ? 1 : library;
	  break;

	case OPT_pg:
	case OPT_p:
	  saw_profile_flag++;
	  break;

	case OPT_g:
	  saw_debug_flag = 1;

	case OPT_v:
	  /* If they only gave us `-v', don't try to link in libphobos.  */
	  if (argc == 2)
	    library = 0;
	  break;

	case OPT_x:
	  if (library == 0
	      && (strcmp (arg, "d") == 0))
	    library = 1;
	  break;

	case OPT_Xlinker:
	case OPT_Wl_:
	  /* Arguments that go directly to the linker might be .o files
	     or something, and so might cause libphobos to be needed.  */
	  if (library == 0)
	    library = 1;
	  break;

	case OPT_c:
	case OPT_S:
	case OPT_E:
	case OPT_M:
	case OPT_MM:
	case OPT_fsyntax_only:
	  /* Don't specify libaries if we won't link, since that would
	     cause a warning.  */
	  library = -1;
	  break;

	case OPT_o:
	  saw_opt_o = 1;
	  break;

	case OPT_static:
	  static_link = 1;
	  break;

	case OPT_static_libgcc:
	  shared_libgcc = 0;
	  break;

	case OPT_static_libphobos:
	  library = library >= 0 ? 2 : library;
	  args[i] |= SKIPOPT;
	  break;

	case OPT_fonly_:
	  args[i] |= SKIPOPT;
	  only_source_option = decoded_options[i].orig_option_with_args_text;

	  if (arg != NULL)
	    {
	      int len = strlen (only_source_option);
	      if (len <= 2 || only_source_option[len-1] != 'd'
		  || only_source_option[len-2] != '.')
		only_source_option = concat (only_source_option, ".d", NULL);
	    }
	  break;

	case OPT_SPECIAL_input_file:
	    {
	      int len;

	      if (arg[0] == '\0' || arg[1] == '\0')
		continue;

	      len = strlen (arg);
	      /* Record that this is a D source file.  */
	      if (len <= 2 || strcmp (arg + len - 2, ".d") == 0)
		{
		  if (first_d_file == NULL)
		    first_d_file = arg;

		  args[i] |= DSOURCE;
		}

	      /* If we don't know that this is a interface file, we might
		 need to be link against libphobos library.  */
	      if (library == 0)
		{
		  if (len <= 3 || strcmp (arg + len - 3, ".di") != 0)
		    library = 1;
		}

	      /* If this is a C++ source file, we'll need to link
		 against libstdc++ library.  */
	      if ((len <= 3 || strcmp (arg + len - 3, ".cc") == 0)
		  || (len <= 4 || strcmp (arg + len - 4, ".cpp") == 0)
		  || (len <= 4 || strcmp (arg + len - 4, ".c++") == 0))
		need_stdcxx = 1;

	      break;
	    }
	}
    }

  /* If we know we don't have to do anything, bail now.  */
  if (!added && library <= 0 && !only_source_option)
    {
      free (args);
      return;
    }

  /* There's no point adding -shared-libgcc if we don't have a shared
     libgcc.  */
#ifndef ENABLE_SHARED_LIBGCC
  shared_libgcc = 0;
#endif

  /* Make sure to have room for the trailing NULL argument.  */
  /* There is one extra argument added here for the runtime
     library: -lgphobos.  The -pthread argument is added by
     setting need_thread. */
  num_args = argc + added + need_math + shared_libgcc + (library > 0) * 5 + 2;
  new_decoded_options = XNEWVEC (cl_decoded_option, num_args);

  i = 0;
  j = 0;

  /* Copy the 0th argument, i.e., the name of the program itself.  */
  new_decoded_options[j++] = decoded_options[i++];

  /* NOTE: We start at 1 now, not 0.  */
  while (i < argc)
    {
      if (args[i] & SKIPOPT)
	{
	  ++i;
	  continue;
	}

      new_decoded_options[j] = decoded_options[i];

      /* Make sure -lphobos is before the math library, since libphobos
	 itself uses those math routines.  */
      if (!saw_math && (args[i] & MATHLIB) && library > 0)
	{
	  --j;
	  saw_math = &decoded_options[i];
	}

      if (!saw_thread && (args[i] & WITHTHREAD) && library > 0)
	{
	  --j;
	  saw_thread = &decoded_options[i];
	}

      if (!saw_time && (args[i] & TIMELIB) && library > 0)
	{
	  --j;
	  saw_time = &decoded_options[i];
	}

      if (!saw_libc && (args[i] & WITHLIBC) && library > 0)
	{
	  --j;
	  saw_libc = &decoded_options[i];
	}

      if (!saw_libcxx && (args[i] & WITHLIBCXX) && library > 0)
	{
	  --j;
	  saw_libcxx = &decoded_options[i];
	}

      if (args[i] & DSOURCE)
	{
	  if (only_source_option)
	    --j;
	}

      i++;
      j++;
    }

  if (only_source_option)
    {
      const char *only_source_arg = only_source_option + 7;
      generate_option (OPT_fonly_, only_source_arg, 1, CL_DRIVER,
		       &new_decoded_options[j]);
      j++;

      generate_option_input_file (only_source_arg,
				  &new_decoded_options[j++]);
    }

  /* If we are not linking, add a -o option.  This is because we need
     the driver to pass all .d files to cc1d.  Without a -o option the
     driver will invoke cc1d separately for each input file.  */
  if (library < 0 && first_d_file != NULL && !saw_opt_o)
    {
      const char *base;
      int baselen;
      int alen;
      char *out;

      base = lbasename (first_d_file);
      baselen = strlen (base) - 2;
      alen = baselen + 3;
      out = XNEWVEC (char, alen);
      memcpy (out, base, baselen);
      /* The driver will convert .o to some other suffix if appropriate.  */
      out[baselen] = '.';
      out[baselen + 1] = 'o';
      out[baselen + 2] = '\0';
      generate_option (OPT_o, out, 1, CL_DRIVER,
		       &new_decoded_options[j]);
      j++;
    }

  /* Add `-lgphobos' if we haven't already done so.  */
  if (library > 0 && phobos)
    {
#ifdef HAVE_LD_STATIC_DYNAMIC
      if (library > 1 && !static_link)
	{
	  generate_option (OPT_Wl_, LD_STATIC_OPTION, 1, CL_DRIVER,
			   &new_decoded_options[j]);
	  j++;
	}
#endif

      generate_option (OPT_l, saw_profile_flag ? LIBPHOBOS_PROFILE : LIBPHOBOS, 1,
		       CL_DRIVER, &new_decoded_options[j]);
      added_libraries++;
      j++;
      generate_option (OPT_l, saw_profile_flag ? LIBDRUNTIME_PROFILE : LIBDRUNTIME, 1,
		       CL_DRIVER, &new_decoded_options[j]);
      added_libraries++;
      j++;

#ifdef HAVE_LD_STATIC_DYNAMIC
      if (library > 1 && !static_link)
	{
	  generate_option (OPT_Wl_, LD_DYNAMIC_OPTION, 1, CL_DRIVER,
			   &new_decoded_options[j]);
	  j++;
	}
#endif
    }
  else if (saw_debug_flag && debuglib)
    {
      generate_option (OPT_l, debuglib, 1, CL_DRIVER,
		       &new_decoded_options[j++]);
      added_libraries++;
    }
  else if (defaultlib)
    {
      generate_option (OPT_l, defaultlib, 1, CL_DRIVER,
		       &new_decoded_options[j++]);
      added_libraries++;
    }

  if (saw_libcxx)
    new_decoded_options[j++] = *saw_libcxx;
  else if (library > 0 && need_stdcxx)
    {
      generate_option (OPT_l,
		       (saw_profile_flag
			? LIBSTDCXX_PROFILE
			: LIBSTDCXX),
		       1, CL_DRIVER, &new_decoded_options[j++]);
      added_libraries++;
    }

  if (saw_math)
    new_decoded_options[j++] = *saw_math;
  else if (library > 0 && need_math)
    {
      generate_option (OPT_l,
		       (saw_profile_flag
			? MATH_LIBRARY_PROFILE
			: MATH_LIBRARY),
		       1, CL_DRIVER, &new_decoded_options[j++]);
      added_libraries++;
    }

  if (saw_thread)
    new_decoded_options[j++] = *saw_thread;
  else if (library > 0 && need_thread)
    {
      generate_option (OPT_l, THREAD_LIBRARY, 1, CL_DRIVER,
		       &new_decoded_options[j++]);
      added_libraries++;
    }

  if (saw_time)
    new_decoded_options[j++] = *saw_time;
  else if (library > 0 && need_time)
    {
      generate_option (OPT_l, TIME_LIBRARY, 1, CL_DRIVER,
		       &new_decoded_options[j++]);
      added_libraries++;
    }

  if (saw_libc)
    new_decoded_options[j++] = *saw_libc;

  if (shared_libgcc && !static_link)
    {
      generate_option (OPT_shared_libgcc, NULL, 1, CL_DRIVER,
		       &new_decoded_options[j++]);
    }

  *in_decoded_options_count = j;
  *in_decoded_options = new_decoded_options;
  *in_added_libraries = added_libraries;
}
Example #3
0
void
lang_specific_driver (struct cl_decoded_option **in_decoded_options,
		      unsigned int *in_decoded_options_count,
		      int *in_added_libraries)
{
  unsigned int i, j;

  /* If true, the user gave us the `-p' or `-pg' flag.  */
  bool saw_profile_flag = false;

  /* This is a tristate:
     -1 means we should not link in libgo
     0  means we should link in libgo if it is needed
     1  means libgo is needed and should be linked in.
     2  means libgo is needed and should be linked statically.  */
  int library = 0;

  /* The new argument list will be contained in this.  */
  struct cl_decoded_option *new_decoded_options;

  /* "-lm" or "-lmath" if it appears on the command line.  */
  const struct cl_decoded_option *saw_math = 0;

  /* "-lpthread" if it appears on the command line.  */
  const struct cl_decoded_option *saw_thread = 0;

  /* "-lc" if it appears on the command line.  */
  const struct cl_decoded_option *saw_libc = 0;

  /* An array used to flag each argument that needs a bit set for
     LANGSPEC, MATHLIB, or WITHLIBC.  */
  int *args;

  /* Whether we need the thread library.  */
  int need_thread = 0;

  /* By default, we throw on the math library if we have one.  */
  int need_math = (MATH_LIBRARY[0] != '\0');

  /* True if we saw -static.  */
  int static_link = 0;

  /* True if we should add -shared-libgcc to the command-line.  */
  int shared_libgcc = 1;

  /* The total number of arguments with the new stuff.  */
  unsigned int argc;

  /* The argument list.  */
  struct cl_decoded_option *decoded_options;

  /* The number of libraries added in.  */
  int added_libraries;

  /* The total number of arguments with the new stuff.  */
  int num_args = 1;

  /* Whether the -o option was used.  */
  bool saw_opt_o = false;

  /* Whether the -c option was used.  Also used for -E, -fsyntax-only,
     in general anything which implies only compilation and not
     linking.  */
  bool saw_opt_c = false;

  /* Whether the -S option was used.  */
  bool saw_opt_S = false;

  /* The first input file with an extension of .go.  */
  const char *first_go_file = NULL;  

  argc = *in_decoded_options_count;
  decoded_options = *in_decoded_options;
  added_libraries = *in_added_libraries;

  args = XCNEWVEC (int, argc);

  for (i = 1; i < argc; i++)
    {
      const char *arg = decoded_options[i].arg;

      switch (decoded_options[i].opt_index)
	{
	case OPT_nostdlib:
	case OPT_nodefaultlibs:
	  library = -1;
	  break;

	case OPT_l:
	  if (strcmp (arg, MATH_LIBRARY) == 0)
	    {
	      args[i] |= MATHLIB;
	      need_math = 0;
	    }
	  else if (strcmp (arg, THREAD_LIBRARY) == 0)
	    args[i] |= THREADLIB;
	  else if (strcmp (arg, "c") == 0)
	    args[i] |= WITHLIBC;
	  else
	    /* Unrecognized libraries (e.g. -lfoo) may require libgo.  */
	    library = (library == 0) ? 1 : library;
	  break;

	case OPT_pg:
	case OPT_p:
	  saw_profile_flag = true;
	  break;

	case OPT_x:
	  if (library == 0 && strcmp (arg, "go") == 0)
	    library = 1;
	  break;

	case OPT_Xlinker:
	case OPT_Wl_:
	  /* Arguments that go directly to the linker might be .o files,
	     or something, and so might cause libgo to be needed.  */
	  if (library == 0)
	    library = 1;
	  break;

	case OPT_c:
	case OPT_E:
	case OPT_M:
	case OPT_MM:
	case OPT_fsyntax_only:
	  /* Don't specify libraries if we won't link, since that would
	     cause a warning.  */
	  saw_opt_c = true;
	  library = -1;
	  break;

	case OPT_S:
	  saw_opt_S = true;
	  library = -1;
	  break;

	case OPT_o:
	  saw_opt_o = true;
	  break;

	case OPT_static:
	  static_link = 1;
	  break;

	case OPT_static_libgcc:
	  shared_libgcc = 0;
	  break;

	case OPT_static_libgo:
	  library = library >= 0 ? 2 : library;
	  args[i] |= SKIPOPT;
	  break;

	case OPT_SPECIAL_input_file:
	  if (library == 0)
	    library = 1;

	  if (first_go_file == NULL)
	    {
	      int len;

	      len = strlen (arg);
	      if (len > 3 && strcmp (arg + len - 3, ".go") == 0)
		first_go_file = arg;
	    }

	  break;
	}
    }

  /* There's no point adding -shared-libgcc if we don't have a shared
     libgcc.  */
#ifndef ENABLE_SHARED_LIBGCC
  shared_libgcc = 0;
#endif

  /* Make sure to have room for the trailing NULL argument.  */
  num_args = argc + need_math + shared_libgcc + (library > 0) * 5 + 10;
  new_decoded_options = XNEWVEC (struct cl_decoded_option, num_args);

  i = 0;
  j = 0;

  /* Copy the 0th argument, i.e., the name of the program itself.  */
  new_decoded_options[j++] = decoded_options[i++];

  /* If we are linking, pass -fsplit-stack if it is supported.  */
#ifdef TARGET_CAN_SPLIT_STACK
  if (library >= 0)
    {
      generate_option (OPT_fsplit_stack, NULL, 1, CL_DRIVER,
		       &new_decoded_options[j]);
      j++;
    }
#endif

  /* NOTE: We start at 1 now, not 0.  */
  while (i < argc)
    {
      new_decoded_options[j] = decoded_options[i];

      /* Make sure -lgo is before the math library, since libgo itself
	 uses those math routines.  */
      if (!saw_math && (args[i] & MATHLIB) && library > 0)
	{
	  --j;
	  saw_math = &decoded_options[i];
	}

      if (!saw_thread && (args[i] & THREADLIB) && library > 0)
	{
	  --j;
	  saw_thread = &decoded_options[i];
	}

      if (!saw_libc && (args[i] & WITHLIBC) && library > 0)
	{
	  --j;
	  saw_libc = &decoded_options[i];
	}

      if ((args[i] & SKIPOPT) != 0)
	--j;

      i++;
      j++;
    }

  /* If we didn't see a -o option, add one.  This is because we need
     the driver to pass all .go files to go1.  Without a -o option the
     driver will invoke go1 separately for each input file.  FIXME:
     This should probably use some other interface to force the driver
     to set combine_inputs.  */
  if (first_go_file != NULL && !saw_opt_o)
    {
      if (saw_opt_c || saw_opt_S)
	{
	  const char *base;
	  int baselen;
	  int alen;
	  char *out;

	  base = lbasename (first_go_file);
	  baselen = strlen (base) - 3;
	  alen = baselen + 3;
	  out = XNEWVEC (char, alen);
	  memcpy (out, base, baselen);
	  /* The driver will convert .o to some other suffix (e.g.,
	     .obj) if appropriate.  */
	  out[baselen] = '.';
	  if (saw_opt_S)
	    out[baselen + 1] = 's';
	  else
	    out[baselen + 1] = 'o';
	  out[baselen + 2] = '\0';
	  generate_option (OPT_o, out, 1, CL_DRIVER,
			   &new_decoded_options[j]);
	}
      else
	generate_option (OPT_o, "a.out", 1, CL_DRIVER,
			 &new_decoded_options[j]);
      j++;
    }
Example #4
0
void
darwin_driver_init (unsigned int *decoded_options_count,
		    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;
	  *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;

	case OPT_mmacosx_version_min_:
	  seen_version_min = true;
	  vers_string = xstrndup ((*decoded_options)[i].arg, 32);

	default:
	  break;
	}
    }

  /* 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]);
    }
Example #5
0
void
lang_specific_driver (struct cl_decoded_option **in_decoded_options,
		      unsigned int *in_decoded_options_count,
		      int *in_added_libraries)
{
  unsigned int i, j;

  /* If nonzero, the user gave us the `-p' or `-pg' flag.  */
  int saw_profile_flag = 0;

  /* What do with libstdc++:
     -1 means we should not link in libstdc++
     0  means we should link in libstdc++ if it is needed
     1  means libstdc++ is needed and should be linked in.
     2  means libstdc++ is needed and should be linked statically.  */
  int library = 0;

  /* The number of arguments being added to what's in argv, other than
     libraries.  We use this to track the number of times we've inserted
     -xc++/-xnone.  */
  int added = 0;

  /* The new argument list will be contained in this.  */
  struct cl_decoded_option *new_decoded_options;

  /* Nonzero if we saw a `-xfoo' language specification on the
     command line.  Used to avoid adding our own -xc++ if the user
     already gave a language for the file.  */
  int saw_speclang = 0;

  /* "-lm" or "-lmath" if it appears on the command line.  */
  const struct cl_decoded_option *saw_math = NULL;

  /* "-lrt" or eqivalent if it appears on the command line.  */
  const struct cl_decoded_option *saw_time = NULL;

  /* "-lc" if it appears on the command line.  */
  const struct cl_decoded_option *saw_libc = NULL;

  /* An array used to flag each argument that needs a bit set for
     LANGSPEC, MATHLIB, TIMELIB, or WITHLIBC.  */
  int *args;

  /* By default, we throw on the math library if we have one.  */
  int need_math = (MATH_LIBRARY[0] != '\0');

  /* By default, we throw on the time library if we have one.  */
  int need_time = (TIME_LIBRARY[0] != '\0');

  /* True if we saw -static.  */
  int static_link = 0;

  /* True if we should add -shared-libgcc to the command-line.  */
  int shared_libgcc = 1;

  /* The total number of arguments with the new stuff.  */
  unsigned int argc;

  /* The argument list.  */
  struct cl_decoded_option *decoded_options;

  /* The number of libraries added in.  */
  int added_libraries;

  /* The total number of arguments with the new stuff.  */
  unsigned int num_args = 1;

  argc = *in_decoded_options_count;
  decoded_options = *in_decoded_options;
  added_libraries = *in_added_libraries;

  args = XCNEWVEC (int, argc);

  for (i = 1; i < argc; i++)
    {
      const char *arg = decoded_options[i].arg;
      if (decoded_options[i].errors & CL_ERR_MISSING_ARG)
	continue; /* Avoid examining arguments of options missing them.  */

      switch (decoded_options[i].opt_index)
	{
	case OPT_nostdlib:
	case OPT_nodefaultlibs:
	  library = -1;
	  break;

	case OPT_l:
	  if (strcmp (arg, MATH_LIBRARY) == 0)
	    {
	      args[i] |= MATHLIB;
	      need_math = 0;
	    }
	  else if (strcmp (arg, TIME_LIBRARY) == 0)
	    {
	      args[i] |= TIMELIB;
	      need_time = 0;
	    }
	  else if (strcmp (arg, "c") == 0)
	    args[i] |= WITHLIBC;
	  else
	    /* Unrecognized libraries (e.g. -lfoo) may require libstdc++.  */
	    library = (library == 0) ? 1 : library;
	  break;

	case OPT_pg:
	case OPT_p:
	  saw_profile_flag++;
	  break;

	case OPT_x:
	  if (library == 0
	      && (strcmp (arg, "c++") == 0
		  || strcmp (arg, "c++-cpp-output") == 0
		  || strcmp (arg, "objective-c++") == 0
		  || strcmp (arg, "objective-c++-cpp-output") == 0))
	    library = 1;
		
	  saw_speclang = 1;
	  break;

	case OPT_Xlinker:
	case OPT_Wl_:
	  /* Arguments that go directly to the linker might be .o files,
	     or something, and so might cause libstdc++ to be needed.  */
	  if (library == 0)
	    library = 1;
	  break;

	case OPT_c:
	case OPT_S:
	case OPT_E:
	case OPT_M:
	case OPT_MM:
	case OPT_fsyntax_only:
	  /* Don't specify libraries if we won't link, since that would
	     cause a warning.  */
	  library = -1;
	  break;

	case OPT_static:
	  static_link = 1;
	  break;

	case OPT_static_libgcc:
	  shared_libgcc = 0;
	  break;

	case OPT_static_libstdc__:
	  library = library >= 0 ? 2 : library;
	  args[i] |= SKIPOPT;
	  break;

	case OPT_SPECIAL_input_file:
	  {
	    int len;

	    /* We don't do this anymore, since we don't get them with minus
	       signs on them.  */
	    if (arg[0] == '\0' || arg[1] == '\0')
	      continue;

	    if (saw_speclang)
	      {
		saw_speclang = 0;
		continue;
	      }

	    /* If the filename ends in .[chi], put options around it.
	       But not if a specified -x option is currently active.  */
	    len = strlen (arg);
	    if (len > 2
		&& (arg[len - 1] == 'c'
		    || arg[len - 1] == 'i'
		    || arg[len - 1] == 'h')
		&& arg[len - 2] == '.')
	      {
		args[i] |= LANGSPEC;
		added += 2;
	      }

	    /* If we don't know that this is a header file, we might
	       need to be linking in the libraries.  */
	    if (library == 0)
	      {
		if ((len <= 2 || strcmp (arg + (len - 2), ".H") != 0)
		    && (len <= 2 || strcmp (arg + (len - 2), ".h") != 0)
		    && (len <= 4 || strcmp (arg + (len - 4), ".hpp") != 0)
		    && (len <= 3 || strcmp (arg + (len - 3), ".hp") != 0)
		    && (len <= 4 || strcmp (arg + (len - 4), ".hxx") != 0)
		    && (len <= 4 || strcmp (arg + (len - 4), ".h++") != 0)
		    && (len <= 4 || strcmp (arg + (len - 4), ".HPP") != 0)
		    && (len <= 4 || strcmp (arg + (len - 4), ".tcc") != 0)
		    && (len <= 3 || strcmp (arg + (len - 3), ".hh") != 0))
		  library = 1;
	      }
	  }
	  break;
	}
    }

  /* There's no point adding -shared-libgcc if we don't have a shared
     libgcc.  */
#ifndef ENABLE_SHARED_LIBGCC
  shared_libgcc = 0;
#endif

  /* Add one for shared_libgcc or extra static library.  */
  num_args = argc + added + need_math + (library > 0) * 4 + 1;
  new_decoded_options = XNEWVEC (struct cl_decoded_option, num_args);

  i = 0;
  j = 0;

  /* Copy the 0th argument, i.e., the name of the program itself.  */
  new_decoded_options[j++] = decoded_options[i++];

  /* NOTE: We start at 1 now, not 0.  */
  while (i < argc)
    {
      new_decoded_options[j] = decoded_options[i];

      /* Make sure -lstdc++ is before the math library, since libstdc++
	 itself uses those math routines.  */
      if (!saw_math && (args[i] & MATHLIB) && library > 0)
	{
	  --j;
	  saw_math = &decoded_options[i];
	}

      if (!saw_time && (args[i] & TIMELIB) && library > 0)
	{
	  --j;
	  saw_time = &decoded_options[i];
	}

      if (!saw_libc && (args[i] & WITHLIBC) && library > 0)
	{
	  --j;
	  saw_libc = &decoded_options[i];
	}

      /* Wrap foo.[chi] files in a language specification to
	 force the gcc compiler driver to run cc1plus on them.  */
      if (args[i] & LANGSPEC)
	{
	  const char *arg = decoded_options[i].arg;
	  int len = strlen (arg);
	  switch (arg[len - 1])
	    {
	    case 'c':
	      generate_option (OPT_x, "c++", 1, CL_DRIVER,
			       &new_decoded_options[j++]);
	      break;
	    case 'i':
	      generate_option (OPT_x, "c++-cpp-output", 1, CL_DRIVER,
			       &new_decoded_options[j++]);
	      break;
	    case 'h':
	      generate_option (OPT_x, "c++-header", 1, CL_DRIVER,
			       &new_decoded_options[j++]);
	      break;
	    default:
	      gcc_unreachable ();
	    }
	  new_decoded_options[j++] = decoded_options[i];
	  generate_option (OPT_x, "none", 1, CL_DRIVER,
			   &new_decoded_options[j]);
	}

      if ((args[i] & SKIPOPT) != 0)
	--j;

      i++;
      j++;
    }

  /* Add `-lstdc++' if we haven't already done so.  */
  if (library > 0)
    {
#ifdef HAVE_LD_STATIC_DYNAMIC
      if (library > 1 && !static_link)
	{
	  generate_option (OPT_Wl_, LD_STATIC_OPTION, 1, CL_DRIVER,
			   &new_decoded_options[j]);
	  j++;
	}
#endif
      generate_option (OPT_l,
		       saw_profile_flag ? LIBSTDCXX_PROFILE : LIBSTDCXX, 1,
		       CL_DRIVER, &new_decoded_options[j]);
      added_libraries++;
      j++;
      /* Add target-dependent static library, if necessary.  */
      if ((static_link || library > 1) && LIBSTDCXX_STATIC != NULL)
	{
	  generate_option (OPT_l, LIBSTDCXX_STATIC, 1,
			   CL_DRIVER, &new_decoded_options[j]);
	  added_libraries++;
	  j++;
	}
#ifdef HAVE_LD_STATIC_DYNAMIC
      if (library > 1 && !static_link)
	{
	  generate_option (OPT_Wl_, LD_DYNAMIC_OPTION, 1, CL_DRIVER,
			   &new_decoded_options[j]);
	  j++;
	}
#endif
    }
  if (saw_math)
    new_decoded_options[j++] = *saw_math;
  else if (library > 0 && need_math)
    {
      generate_option (OPT_l,
		       saw_profile_flag ? MATH_LIBRARY_PROFILE : MATH_LIBRARY,
		       1, CL_DRIVER, &new_decoded_options[j]);
      added_libraries++;
      j++;
    }
  if (saw_time)
    new_decoded_options[j++] = *saw_time;
  else if (library > 0 && need_time)
    {
      generate_option (OPT_l, TIME_LIBRARY, 1, CL_DRIVER,
		       &new_decoded_options[j]);
      added_libraries++;
      j++;
    }
  if (saw_libc)
    new_decoded_options[j++] = *saw_libc;
  if (shared_libgcc && !static_link)
    generate_option (OPT_shared_libgcc, NULL, 1, CL_DRIVER,
		     &new_decoded_options[j++]);

  *in_decoded_options_count = j;
  *in_decoded_options = new_decoded_options;
  *in_added_libraries = added_libraries;
}