OSDN Git Service

2009-08-15 Tobias Burnus <burnus@net-b.de>
[pf3gnuchains/gcc-fork.git] / gcc / fortran / gfortranspec.c
index bbf9fa3..534fe89 100644 (file)
@@ -1,11 +1,13 @@
 /* Specific flags and argument handling of the Fortran front-end.
-   Copyright (C) 1997, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+   Copyright (C) 1997, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
+   2007, 2008, 2009
+   Free Software Foundation, Inc.
 
-This file is part of GNU CC.
+This file is part of GCC.
 
 GNU CC 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.
 
 GNU CC is distributed in the hope that it will be useful,
@@ -14,9 +16,9 @@ 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 GNU CC; see the file COPYING.  If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.  */
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
+
 /* This file is copied more or less verbatim from g77.  */
 /* This file contains a filter for the main `gcc' driver, which is
    replicated for the `gfortran' driver by adding this filter.  The purpose
@@ -50,41 +52,54 @@ Boston, MA 02111-1307, USA.  */
 
 #include "coretypes.h"
 #include "tm.h"
+#include "intl.h"
 
 #ifndef MATH_LIBRARY
 #define MATH_LIBRARY "-lm"
 #endif
 
-#ifndef FORTRAN_INIT
-#define FORTRAN_INIT "-lgfortranbegin"
-#endif
-
 #ifndef FORTRAN_LIBRARY
 #define FORTRAN_LIBRARY "-lgfortran"
 #endif
 
+#ifdef HAVE_LD_STATIC_DYNAMIC
+#define ADD_ARG_LIBGFORTRAN(arg) \
+  { \
+    if (static_lib && !static_linking) \
+      append_arg ("-Wl,-Bstatic"); \
+    append_arg (arg); \
+    if (static_lib && !static_linking) \
+      append_arg ("-Wl,-Bdynamic"); \
+  }
+#else
+#define ADD_ARG_LIBGFORTRAN(arg) append_arg (arg);
+#endif
+
+
 /* Options this driver needs to recognize, not just know how to
    skip over.  */
 typedef enum
 {
-  OPTION_b,                    /* Aka --prefix. */
-  OPTION_B,                    /* Aka --target. */
-  OPTION_c,                    /* Aka --compile. */
-  OPTION_E,                    /* Aka --preprocess. */
-  OPTION_help,                 /* --help. */
-  OPTION_i,                    /* -imacros, -include, -include-*. */
+  OPTION_b,                    /* Aka --prefix.  */
+  OPTION_B,                    /* Aka --target.  */
+  OPTION_c,                    /* Aka --compile.  */
+  OPTION_E,                    /* Aka --preprocess.  */
+  OPTION_help,                 /* --help.  */
+  OPTION_i,                    /* -imacros, -include, -include-*.  */
   OPTION_l,
-  OPTION_L,                    /* Aka --library-directory. */
+  OPTION_L,                    /* Aka --library-directory.  */
   OPTION_nostdlib,             /* Aka --no-standard-libraries, or
-                                  -nodefaultlibs. */
-  OPTION_o,                    /* Aka --output. */
-  OPTION_S,                    /* Aka --assemble. */
-  OPTION_syntax_only,          /* -fsyntax-only. */
-  OPTION_v,                    /* Aka --verbose. */
-  OPTION_version,              /* --version. */
-  OPTION_V,                    /* Aka --use-version. */
-  OPTION_x,                    /* Aka --language. */
-  OPTION_                      /* Unrecognized or unimportant. */
+                                  -nodefaultlibs.  */
+  OPTION_o,                    /* Aka --output.  */
+  OPTION_S,                    /* Aka --assemble.  */
+  OPTION_static,               /* -static.  */
+  OPTION_static_libgfortran,   /* -static-libgfortran.  */
+  OPTION_syntax_only,          /* -fsyntax-only.  */
+  OPTION_v,                    /* Aka --verbose.  */
+  OPTION_version,              /* --version.  */
+  OPTION_V,                    /* Aka --use-version.  */
+  OPTION_x,                    /* Aka --language.  */
+  OPTION_                      /* Unrecognized or unimportant.  */
 }
 Option;
 
@@ -98,8 +113,6 @@ static void append_arg (const char *);
 static int g77_newargc;
 static const char **g77_newargv;
 
-const struct spec_function lang_specific_spec_functions[] = {{0,0}};
-
 /* --- This comes from gcc.c (2.8.1) verbatim: */
 
 /* This defines which switch letters take arguments.  */
@@ -132,7 +145,7 @@ lookup_option (Option *xopt, int *xskip, const char **xarg, const char *text)
   const char *arg = NULL;
 
   if ((skip = SWITCH_TAKES_ARG (text[1])))
-    skip -= (text[2] != '\0'); /* See gcc.c. */
+    skip -= (text[2] != '\0'); /* See gcc.c.  */
 
   if (text[1] == 'B')
     opt = OPTION_B, skip = (text[2] == '\0'), arg = text + 2;
@@ -158,9 +171,11 @@ lookup_option (Option *xopt, int *xskip, const char **xarg, const char *text)
     opt = OPTION_v, skip = 0;
   else if (text[1] == 'x')
     opt = OPTION_x, arg = text + 2;
+  else if (text[1] == 'J')
+    ;
   else
     {
-      if ((skip = WORD_SWITCH_TAKES_ARG (text + 1)) != 0)      /* See gcc.c. */
+      if ((skip = WORD_SWITCH_TAKES_ARG (text + 1)) != 0)  /* See gcc.c.  */
        ;
       else if (!strcmp (text, "-fhelp"))       /* Really --help!! */
        opt = OPTION_help;
@@ -169,8 +184,8 @@ lookup_option (Option *xopt, int *xskip, const char **xarg, const char *text)
        opt = OPTION_nostdlib;
       else if (!strcmp (text, "-fsyntax-only"))
        opt = OPTION_syntax_only;
-      else if (!strcmp (text, "-dumpversion"))
-       opt = OPTION_version;
+      else if (!strcmp (text, "-static-libgfortran"))
+       opt = OPTION_static_libgfortran;
       else if (!strcmp (text, "-fversion"))    /* Really --version!! */
        opt = OPTION_version;
       else if (!strcmp (text, "-Xlinker") || !strcmp (text, "-specs"))
@@ -211,14 +226,14 @@ append_arg (const char *arg)
          || !strcmp (arg, g77_xargv[g77_newargc])))
     {
       ++g77_newargc;
-      return;                  /* Nothing new here. */
+      return;                  /* Nothing new here.  */
     }
 
   if (g77_newargv == g77_xargv)
-    {                          /* Make new arglist. */
+    {                          /* Make new arglist.  */
       int i;
 
-      newargsize = (g77_xargc << 2) + 20;      /* This should handle all. */
+      newargsize = (g77_xargc << 2) + 20;      /* This should handle all.  */
       g77_newargv = (const char **) xmalloc (newargsize * sizeof (char *));
 
       /* Copy what has been done so far.  */
@@ -227,7 +242,7 @@ append_arg (const char *arg)
     }
 
   if (g77_newargc == newargsize)
-    fatal ("overflowed output arg list for `%s'", arg);
+    fatal ("overflowed output arg list for '%s'", arg);
 
   g77_newargv[g77_newargc++] = arg;
 }
@@ -257,13 +272,15 @@ lang_specific_driver (int *in_argc, const char *const **in_argv,
      2 => last two args were -l<library> -lm.  */
   int saw_library = 0;
 
-  /* 0 => initial/reset state
-     1 => FORTRAN_INIT linked in */
-  int use_init = 0;
-
   /* By default, we throw on the math library if we have one.  */
   int need_math = (MATH_LIBRARY[0] != '\0');
 
+  /* Whether we should link a static libgfortran.  */
+  int static_lib = 0;
+
+  /* Whether we need to link statically.  */
+  int static_linking = 0;
+
   /* The number of input and output files in the incoming arg list.  */
   int n_infiles = 0;
   int n_outfiles = 0;
@@ -278,7 +295,7 @@ lang_specific_driver (int *in_argc, const char *const **in_argv,
   g77_xargc = argc;
   g77_xargv = argv;
   g77_newargc = 0;
-  g77_newargv = (const char **) argv;
+  g77_newargv = CONST_CAST2 (const char **, const char *const *, argv);
 
   /* First pass through arglist.
 
@@ -322,6 +339,13 @@ lang_specific_driver (int *in_argc, const char *const **in_argv,
          library = 0;
          break;
 
+       case OPTION_static_libgfortran:
+         static_lib = 1;
+         break;
+
+       case OPTION_static:
+         static_linking = 1;
+
        case OPTION_l:
          ++n_infiles;
          break;
@@ -344,15 +368,13 @@ lang_specific_driver (int *in_argc, const char *const **in_argv,
          break;
 
        case OPTION_version:
-         printf ("\
-GNU Fortran 95 (GCC %s)\n\
-Copyright (C) 2003 Free Software Foundation, Inc.\n\
-\n\
-GNU Fortran comes with NO WARRANTY, to the extent permitted by law.\n\
+         printf ("GNU Fortran %s%s\n", pkgversion_string, version_string);
+         printf ("Copyright %s 2009 Free Software Foundation, Inc.\n\n",
+                 _("(C)"));
+         printf (_("GNU Fortran comes with NO WARRANTY, to the extent permitted by law.\n\
 You may redistribute copies of GNU Fortran\n\
 under the terms of the GNU General Public License.\n\
-For more information about these matters, see the file named COPYING\n\
-", version_string);
+For more information about these matters, see the file named COPYING\n\n"));
          exit (0);
          break;
 
@@ -366,12 +388,12 @@ For more information about these matters, see the file named COPYING\n\
        }
 
       /* This is the one place we check for missing arguments in the
-         program.  */
+        program.  */
 
       if (i + skip < argc)
        i += skip;
       else
-       fatal ("argument to `%s' missing", argv[i]);
+       fatal ("argument to '%s' missing", argv[i]);
     }
 
   if ((n_outfiles != 0) && (n_infiles == 0))
@@ -383,42 +405,51 @@ For more information about these matters, see the file named COPYING\n\
 
   /* Second pass through arglist, transforming arguments as appropriate.  */
 
-  append_arg (argv[0]);                /* Start with command name, of course. */
+  append_arg (argv[0]);                /* Start with command name, of course.  */
 
   for (i = 1; i < argc; ++i)
     {
       if (argv[i][0] == '\0')
        {
-         append_arg (argv[i]); /* Interesting.  Just append as is. */
+         append_arg (argv[i]); /* Interesting.  Just append as is.  */
          continue;
        }
 
       if ((argv[i][0] == '-') && (argv[i][1] == 'M'))
-        {
-          char *p;
-
-          if (argv[i][2] == '\0')
-            {
-              p = xmalloc (strlen (argv[i + 1]) + 2);
-              p[0] = '-';
-              p[1] = 'J';
-              strcpy (&p[2], argv[i + 1]);
-              i++;
-            }
-          else
-            {
-              p = xmalloc (strlen (argv[i]) + 1);
-              strcpy (p, argv[i]);
-            }
-          append_arg (p);
-          continue;
-        }
+       {
+         char *p;
+
+         fprintf (stderr, _("Warning: Using -M <directory> is deprecated, "
+                  "use -J instead\n"));
+         if (argv[i][2] == '\0')
+           {
+             if (i+1 < argc)
+               {
+                 p = XNEWVEC (char, strlen (argv[i + 1]) + 3);
+                 p[0] = '-';
+                 p[1] = 'J';
+                 strcpy (&p[2], argv[i + 1]);
+                 i++;
+               }
+             else
+               fatal ("argument to '%s' missing", argv[i]);
+           }
+         else
+           {
+             p = XNEWVEC (char, strlen (argv[i]) + 1);
+             p[0] = '-';
+             p[1] = 'J';
+             strcpy (&p[2], argv[i] + 2);
+           }
+         append_arg (p);
+         continue;
+       }
 
       if ((argv[i][0] == '-') && (argv[i][1] != 'l'))
        {
-         /* Not a filename or library. */
+         /* Not a filename or library.  */
 
-         if (saw_library == 1 && need_math)    /* -l<library>. */
+         if (saw_library == 1 && need_math)    /* -l<library>.  */
            append_arg (MATH_LIBRARY);
 
          saw_library = 0;
@@ -427,13 +458,13 @@ For more information about these matters, see the file named COPYING\n\
 
          if (argv[i][1] == '\0')
            {
-             append_arg (argv[i]);     /* "-" == Standard input. */
+             append_arg (argv[i]);     /* "-" == Standard input.  */
              continue;
            }
 
          if (opt == OPTION_x)
            {
-             /* Track input language. */
+             /* Track input language.  */
              const char *lang;
 
              if (arg == NULL)
@@ -452,30 +483,29 @@ For more information about these matters, see the file named COPYING\n\
          continue;
        }
 
-      /* A filename/library, not an option. */
+      /* A filename/library, not an option.  */
 
       if (saw_speclang)
-       saw_library = 0;        /* -xfoo currently active. */
+       saw_library = 0;        /* -xfoo currently active.  */
       else
-       {                       /* -lfoo or filename. */
+       {                       /* -lfoo or filename.  */
          if (strcmp (argv[i], MATH_LIBRARY) == 0)
            {
              if (saw_library == 1)
-               saw_library = 2;        /* -l<library> -lm. */
+               saw_library = 2;        /* -l<library> -lm.  */
              else
                {
-                 if (0 == use_init)
-                   {
-                     append_arg (FORTRAN_INIT);
-                     use_init = 1;
-                   }
-                 append_arg (FORTRAN_LIBRARY);
+                 ADD_ARG_LIBGFORTRAN (FORTRAN_LIBRARY);
                }
            }
          else if (strcmp (argv[i], FORTRAN_LIBRARY) == 0)
-           saw_library = 1;    /* -l<library>. */
+           {
+             saw_library = 1;  /* -l<library>.  */
+             ADD_ARG_LIBGFORTRAN (argv[i]);
+             continue;
+           }
          else
-           {                   /* Other library, or filename. */
+           {                   /* Other library, or filename.  */
              if (saw_library == 1 && need_math)
                append_arg (MATH_LIBRARY);
              saw_library = 0;
@@ -487,19 +517,16 @@ For more information about these matters, see the file named COPYING\n\
   /* Append `-lg2c -lm' as necessary.  */
 
   if (library)
-    {                          /* Doing a link and no -nostdlib. */
+    {                          /* Doing a link and no -nostdlib.  */
       if (saw_speclang)
        append_arg ("-xnone");
 
       switch (saw_library)
        {
        case 0:
-         if (0 == use_init)
-           {
-             append_arg (FORTRAN_INIT);
-             use_init = 1;
-           }
-         append_arg (library);
+         ADD_ARG_LIBGFORTRAN (library);
+         /* Fall through.  */
+
        case 1:
          if (need_math)
            append_arg (MATH_LIBRARY);
@@ -527,7 +554,7 @@ For more information about these matters, see the file named COPYING\n\
 
   if (verbose && g77_newargv != g77_xargv)
     {
-      fprintf (stderr, "Driving:");
+      fprintf (stderr, _("Driving:"));
       for (i = 0; i < g77_newargc; i++)
        fprintf (stderr, " %s", g77_newargv[i]);
       fprintf (stderr, "\n");
@@ -537,12 +564,13 @@ For more information about these matters, see the file named COPYING\n\
   *in_argv = g77_newargv;
 }
 
-/* Called before linking.  Returns 0 on success and -1 on failure. */
+
+/* Called before linking.  Returns 0 on success and -1 on failure.  */
 int
-lang_specific_pre_link (void)  /* Not used for F77. */
+lang_specific_pre_link (void)  /* Not used for F77.  */
 {
   return 0;
 }
 
-/* Number of extra output files that lang_specific_pre_link may generate. */
-int lang_specific_extra_outfiles = 0;  /* Not used for F77. */
+/* Number of extra output files that lang_specific_pre_link may generate.  */
+int lang_specific_extra_outfiles = 0;  /* Not used for F77.  */