OSDN Git Service

PR c++/29043
[pf3gnuchains/gcc-fork.git] / gcc / cp / g++spec.c
index 2f452ee..2853088 100644 (file)
@@ -1,12 +1,12 @@
 /* Specific flags and argument handling of the C++ front end.
-   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
-   Free Software Foundation, Inc.
+   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+   2007, 2008, 2009 Free Software Foundation, 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 2, or (at your option)
+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,
@@ -15,9 +15,8 @@ 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 COPYING.  If not, write to
-the Free Software Foundation, 51 Franklin Street, Fifth Floor,
-Boston, MA 02110-1301, USA.  */
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
 
 #include "config.h"
 #include "system.h"
@@ -31,6 +30,8 @@ Boston, MA 02110-1301, USA.  */
 #define MATHLIB                (1<<2)
 /* This bit is set if they did `-lc'.  */
 #define WITHLIBC       (1<<3)
+/* Skip this option.  */
+#define SKIPOPT                (1<<4)
 
 #ifndef MATH_LIBRARY
 #define MATH_LIBRARY "-lm"
@@ -45,6 +46,9 @@ Boston, MA 02110-1301, USA.  */
 #ifndef LIBSTDCXX_PROFILE
 #define LIBSTDCXX_PROFILE LIBSTDCXX
 #endif
+#ifndef LIBSTDCXX_STATIC
+#define LIBSTDCXX_STATIC NULL
+#endif
 
 void
 lang_specific_driver (int *in_argc, const char *const **in_argv,
@@ -55,13 +59,11 @@ lang_specific_driver (int *in_argc, const char *const **in_argv,
   /* If nonzero, the user gave us the `-p' or `-pg' flag.  */
   int saw_profile_flag = 0;
 
-  /* If nonzero, the user gave us the `-v' flag.  */
-  int saw_verbose_flag = 0;
-
-  /* This is a tristate:
+  /* 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.  */
+     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
@@ -94,6 +96,9 @@ lang_specific_driver (int *in_argc, const char *const **in_argv,
   /* 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;
 
@@ -145,8 +150,6 @@ lang_specific_driver (int *in_argc, const char *const **in_argv,
            args[i] |= WITHLIBC;
          else if (strcmp (argv[i], "-pg") == 0 || strcmp (argv[i], "-p") == 0)
            saw_profile_flag++;
-         else if (strcmp (argv[i], "-v") == 0)
-           saw_verbose_flag = 1;
          else if (strncmp (argv[i], "-x", 2) == 0)
            {
              const char * arg;
@@ -198,9 +201,15 @@ lang_specific_driver (int *in_argc, const char *const **in_argv,
                 cause a warning.  */
              library = -1;
            }
-         else if (strcmp (argv[i], "-static-libgcc") == 0
-                  || strcmp (argv[i], "-static") == 0)
+         else if (strcmp (argv[i], "-static") == 0)
+           static_link = 1;
+         else if (strcmp (argv[i], "-static-libgcc") == 0)
            shared_libgcc = 0;
+         else if (strcmp (argv[i], "-static-libstdc++") == 0)
+           {
+             library = library >= 0 ? 2 : library;
+             args[i] |= SKIPOPT;
+           }
          else if (DEFAULT_WORD_SWITCH_TAKES_ARG (&argv[i][1]))
            i++;
          else
@@ -236,6 +245,12 @@ lang_specific_driver (int *in_argc, const char *const **in_argv,
            {
              if ((len <= 2 || strcmp (argv[i] + (len - 2), ".H") != 0)
                  && (len <= 2 || strcmp (argv[i] + (len - 2), ".h") != 0)
+                 && (len <= 4 || strcmp (argv[i] + (len - 4), ".hpp") != 0)
+                 && (len <= 3 || strcmp (argv[i] + (len - 3), ".hp") != 0)
+                 && (len <= 4 || strcmp (argv[i] + (len - 4), ".hxx") != 0)
+                 && (len <= 4 || strcmp (argv[i] + (len - 4), ".h++") != 0)
+                 && (len <= 4 || strcmp (argv[i] + (len - 4), ".HPP") != 0)
+                 && (len <= 4 || strcmp (argv[i] + (len - 4), ".tcc") != 0)
                  && (len <= 3 || strcmp (argv[i] + (len - 3), ".hh") != 0))
                library = 1;
            }
@@ -251,8 +266,9 @@ lang_specific_driver (int *in_argc, const char *const **in_argv,
   shared_libgcc = 0;
 #endif
 
-  /* Make sure to have room for the trailing NULL argument.  */
-  num_args = argc + added + need_math + shared_libgcc + (library > 0) + 1;
+  /* Make sure to have room for the trailing NULL argument.
+     Add one for shared_libgcc or extra static library.  */
+  num_args = argc + added + need_math + (library > 0) * 4 + 2;
   arglist = XNEWVEC (const char *, num_args);
 
   i = 0;
@@ -303,6 +319,9 @@ lang_specific_driver (int *in_argc, const char *const **in_argv,
          arglist[j] = "-xnone";
        }
 
+      if ((args[i] & SKIPOPT) != 0)
+       --j;
+
       i++;
       j++;
     }
@@ -310,10 +329,32 @@ lang_specific_driver (int *in_argc, const char *const **in_argv,
   /* Add `-lstdc++' if we haven't already done so.  */
   if (library > 0)
     {
+#ifdef HAVE_LD_STATIC_DYNAMIC
+      if (library > 1 && !static_link)
+       {
+         arglist[j] = "-Wl,-Bstatic";
+         j++;
+       }
+#endif
       arglist[j] = saw_profile_flag ? LIBSTDCXX_PROFILE : LIBSTDCXX;
       if (arglist[j][0] != '-' || arglist[j][1] == 'l')
        added_libraries++;
       j++;
+      /* Add target-dependent static library, if necessary.  */
+      if ((static_link || library > 1) && LIBSTDCXX_STATIC != NULL)
+       {
+         arglist[j] = LIBSTDCXX_STATIC;
+         if (arglist[j][0] != '-' || arglist[j][1] == 'l')
+           added_libraries++;
+         j++;
+       }
+#ifdef HAVE_LD_STATIC_DYNAMIC
+      if (library > 1 && !static_link)
+       {
+         arglist[j] = "-Wl,-Bdynamic";
+         j++;
+       }
+#endif
     }
   if (saw_math)
     arglist[j++] = saw_math;
@@ -326,7 +367,7 @@ lang_specific_driver (int *in_argc, const char *const **in_argv,
     }
   if (saw_libc)
     arglist[j++] = saw_libc;
-  if (shared_libgcc)
+  if (shared_libgcc && !static_link)
     arglist[j++] = "-shared-libgcc";
 
   arglist[j] = NULL;