OSDN Git Service

2010-11-21 Michael Matz <matz@suse.de>
[pf3gnuchains/gcc-fork.git] / gcc / fortran / gfortranspec.c
1 /* Specific flags and argument handling of the Fortran front-end.
2    Copyright (C) 1997, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
3    2007, 2008, 2009, 2010
4    Free Software Foundation, Inc.
5
6 This file is part of GCC.
7
8 GNU CC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
11 any later version.
12
13 GNU CC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3.  If not see
20 <http://www.gnu.org/licenses/>.  */
21
22 /* This file is copied more or less verbatim from g77.  */
23 /* This file contains a filter for the main `gcc' driver, which is
24    replicated for the `gfortran' driver by adding this filter.  The purpose
25    of this filter is to be basically identical to gcc (in that
26    it faithfully passes all of the original arguments to gcc) but,
27    unless explicitly overridden by the user in certain ways, ensure
28    that the needs of the language supported by this wrapper are met.
29
30    For GNU Fortran 95(gfortran), we do the following to the argument list
31    before passing it to `gcc':
32
33    1.  Make sure `-lgfortran -lm' is at the end of the list.
34
35    2.  Make sure each time `-lgfortran' or `-lm' is seen, it forms
36        part of the series `-lgfortran -lm'.
37
38    #1 and #2 are not done if `-nostdlib' or any option that disables
39    the linking phase is present, or if `-xfoo' is in effect.  Note that
40    a lack of source files or -l options disables linking.
41
42    This program was originally made out of gcc/cp/g++spec.c, but the
43    way it builds the new argument list was rewritten so it is much
44    easier to maintain, improve the way it decides to add or not add
45    extra arguments, etc.  And several improvements were made in the
46    handling of arguments, primarily to make it more consistent with
47    `gcc' itself.  */
48
49 #include "config.h"
50 #include "system.h"
51 #include "coretypes.h"
52 #include "gcc.h"
53 #include "opts.h"
54
55 #include "tm.h"
56 #include "intl.h"
57
58 #ifndef MATH_LIBRARY
59 #define MATH_LIBRARY "m"
60 #endif
61
62 #ifndef FORTRAN_LIBRARY
63 #define FORTRAN_LIBRARY "gfortran"
64 #endif
65
66 /* Name of the spec file.  */
67 #define SPEC_FILE "libgfortran.spec"
68
69 /* The original argument list and related info is copied here.  */
70 static unsigned int g77_xargc;
71 static const struct cl_decoded_option *g77_x_decoded_options;
72 static void append_arg (const struct cl_decoded_option *);
73
74 /* The new argument list will be built here.  */
75 static unsigned int g77_newargc;
76 static struct cl_decoded_option *g77_new_decoded_options;
77
78 /* The path to the spec file.  */
79 char *spec_file = NULL;
80
81
82 /* Return full path name of spec file if it is in DIR, or NULL if
83    not.  */
84 static char *
85 find_spec_file (const char *dir)
86 {
87   const char dirsep_string[] = { DIR_SEPARATOR, '\0' };
88   char *spec;
89   struct stat sb;
90
91   spec = XNEWVEC (char, strlen (dir) + sizeof (SPEC_FILE) + 4);
92   strcpy (spec, dir);
93   strcat (spec, dirsep_string);
94   strcat (spec, SPEC_FILE);
95   if (!stat (spec, &sb))
96     return spec;
97   free (spec);
98   return NULL;
99 }
100
101
102 /* Return whether strings S1 and S2 are both NULL or both the same
103    string.  */
104
105 static bool
106 strings_same (const char *s1, const char *s2)
107 {
108   return s1 == s2 || (s1 != NULL && s2 != NULL && strcmp (s1, s2) == 0);
109 }
110
111 /* Return whether decoded option structures OPT1 and OPT2 are the
112    same.  */
113
114 static bool
115 options_same (const struct cl_decoded_option *opt1,
116               const struct cl_decoded_option *opt2)
117 {
118   return (opt1->opt_index == opt2->opt_index
119           && strings_same (opt1->arg, opt2->arg)
120           && strings_same (opt1->orig_option_with_args_text,
121                            opt2->orig_option_with_args_text)
122           && strings_same (opt1->canonical_option[0],
123                            opt2->canonical_option[0])
124           && strings_same (opt1->canonical_option[1],
125                            opt2->canonical_option[1])
126           && strings_same (opt1->canonical_option[2],
127                            opt2->canonical_option[2])
128           && strings_same (opt1->canonical_option[3],
129                            opt2->canonical_option[3])
130           && (opt1->canonical_option_num_elements
131               == opt2->canonical_option_num_elements)
132           && opt1->value == opt2->value
133           && opt1->errors == opt2->errors);
134 }
135
136 /* Append another argument to the list being built.  As long as it is
137    identical to the corresponding arg in the original list, just increment
138    the new arg count.  Otherwise allocate a new list, etc.  */
139
140 static void
141 append_arg (const struct cl_decoded_option *arg)
142 {
143   static unsigned int newargsize;
144
145   if (g77_new_decoded_options == g77_x_decoded_options
146       && g77_newargc < g77_xargc
147       && options_same (arg, &g77_x_decoded_options[g77_newargc]))
148     {
149       ++g77_newargc;
150       return;                   /* Nothing new here.  */
151     }
152
153   if (g77_new_decoded_options == g77_x_decoded_options)
154     {                           /* Make new arglist.  */
155       unsigned int i;
156
157       newargsize = (g77_xargc << 2) + 20;       /* This should handle all.  */
158       g77_new_decoded_options = XNEWVEC (struct cl_decoded_option, newargsize);
159
160       /* Copy what has been done so far.  */
161       for (i = 0; i < g77_newargc; ++i)
162         g77_new_decoded_options[i] = g77_x_decoded_options[i];
163     }
164
165   if (g77_newargc == newargsize)
166     fatal_error ("overflowed output arg list for %qs",
167                  arg->orig_option_with_args_text);
168
169   g77_new_decoded_options[g77_newargc++] = *arg;
170 }
171
172 /* Append an option described by OPT_INDEX, ARG and VALUE to the list
173    being built.  */
174 static void
175 append_option (size_t opt_index, const char *arg, int value)
176 {
177   struct cl_decoded_option decoded;
178
179   generate_option (opt_index, arg, value, CL_DRIVER, &decoded);
180   append_arg (&decoded);
181 }
182
183 /* Append a libgfortran argument to the list being built.  If
184    FORCE_STATIC, ensure the library is linked statically.  */
185
186 static void
187 add_arg_libgfortran (bool force_static ATTRIBUTE_UNUSED)
188 {
189 #ifdef HAVE_LD_STATIC_DYNAMIC
190   if (force_static)
191     append_option (OPT_Wl_, "-Bstatic", 1);
192 #endif
193   append_option (OPT_l, FORTRAN_LIBRARY, 1);
194 #ifdef HAVE_LD_STATIC_DYNAMIC
195   if (force_static)
196     append_option (OPT_Wl_, "-Bdynamic", 1);
197 #endif
198 }
199
200 void
201 lang_specific_driver (struct cl_decoded_option **in_decoded_options,
202                       unsigned int *in_decoded_options_count,
203                       int *in_added_libraries ATTRIBUTE_UNUSED)
204 {
205   unsigned int argc = *in_decoded_options_count;
206   struct cl_decoded_option *decoded_options = *in_decoded_options;
207   unsigned int i;
208   int verbose = 0;
209
210   /* This will be NULL if we encounter a situation where we should not
211      link in libf2c.  */
212   const char *library = FORTRAN_LIBRARY;
213
214   /* 0 => -xnone in effect.
215      1 => -xfoo in effect.  */
216   int saw_speclang = 0;
217
218   /* 0 => initial/reset state
219      1 => last arg was -l<library>
220      2 => last two args were -l<library> -lm.  */
221   int saw_library = 0;
222
223   /* By default, we throw on the math library if we have one.  */
224   int need_math = (MATH_LIBRARY[0] != '\0');
225
226   /* Whether we should link a static libgfortran. */
227   int static_lib = 0; 
228
229   /* Whether we need to link statically.  */
230   int static_linking = 0;
231
232   /* The number of input and output files in the incoming arg list.  */
233   int n_infiles = 0;
234   int n_outfiles = 0;
235
236 #if 0
237   fprintf (stderr, "Incoming:");
238   for (i = 0; i < argc; i++)
239     fprintf (stderr, " %s", decoded_options[i].orig_option_with_args_text);
240   fprintf (stderr, "\n");
241 #endif
242
243   g77_xargc = argc;
244   g77_x_decoded_options = decoded_options;
245   g77_newargc = 0;
246   g77_new_decoded_options = decoded_options;
247
248   /* First pass through arglist.
249
250      If -nostdlib or a "turn-off-linking" option is anywhere in the
251      command line, don't do any library-option processing (except
252      relating to -x).  */
253
254   for (i = 1; i < argc; ++i)
255     {
256       switch (decoded_options[i].opt_index)
257         {
258         case OPT_SPECIAL_input_file:
259           ++n_infiles;
260           continue;
261
262         case OPT_nostdlib:
263         case OPT_nodefaultlibs:
264         case OPT_c:
265         case OPT_S:
266         case OPT_fsyntax_only:
267         case OPT_E:
268           /* These options disable linking entirely or linking of the
269              standard libraries.  */
270           library = 0;
271           break;
272
273         case OPT_static_libgfortran:
274 #ifdef HAVE_LD_STATIC_DYNAMIC
275           static_lib = 1;
276 #endif
277           break;
278
279         case OPT_static:
280 #ifdef HAVE_LD_STATIC_DYNAMIC
281           static_linking = 1;
282 #endif
283           break;
284
285         case OPT_l:
286           ++n_infiles;
287           break;
288
289         case OPT_o:
290           ++n_outfiles;
291           break;
292
293         case OPT_v:
294           verbose = 1;
295           break;
296
297         case OPT__version:
298           printf ("GNU Fortran %s%s\n", pkgversion_string, version_string);
299           printf ("Copyright %s 2010 Free Software Foundation, Inc.\n\n",
300                   _("(C)"));
301           printf (_("GNU Fortran comes with NO WARRANTY, to the extent permitted by law.\n\
302 You may redistribute copies of GNU Fortran\n\
303 under the terms of the GNU General Public License.\n\
304 For more information about these matters, see the file named COPYING\n\n"));
305           exit (0);
306           break;
307
308         case OPT__help:
309           /* Let gcc.c handle this, as it has a really
310              cool facility for handling --help and --verbose --help.  */
311           return;
312
313         case OPT_L:
314           if (!spec_file)
315             spec_file = find_spec_file (decoded_options[i].arg);
316           break;
317
318
319         default:
320           break;
321         }
322     }
323
324   if ((n_outfiles != 0) && (n_infiles == 0))
325     fatal_error ("no input files; unwilling to write output files");
326
327   /* If there are no input files, no need for the library.  */
328   if (n_infiles == 0)
329     library = 0;
330
331   /* Second pass through arglist, transforming arguments as appropriate.  */
332
333   append_arg (&decoded_options[0]); /* Start with command name, of course.  */
334
335   for (i = 1; i < argc; ++i)
336     {
337       if (decoded_options[i].errors & CL_ERR_MISSING_ARG)
338         {
339           append_arg (&decoded_options[i]);
340           continue;
341         }
342
343       if (decoded_options[i].opt_index == OPT_SPECIAL_input_file
344           && decoded_options[i].arg[0] == '\0')
345         {
346           /* Interesting.  Just append as is.  */
347           append_arg (&decoded_options[i]);
348           continue;
349         }
350
351       if (decoded_options[i].opt_index != OPT_l
352           && (decoded_options[i].opt_index != OPT_SPECIAL_input_file
353               || strcmp (decoded_options[i].arg, "-") == 0))
354         {
355           /* Not a filename or library.  */
356
357           if (saw_library == 1 && need_math)    /* -l<library>.  */
358             append_option (OPT_l, MATH_LIBRARY, 1);
359
360           saw_library = 0;
361
362           if (decoded_options[i].opt_index == OPT_SPECIAL_input_file)
363             {
364               append_arg (&decoded_options[i]); /* "-" == Standard input.  */
365               continue;
366             }
367
368           if (decoded_options[i].opt_index == OPT_x)
369             {
370               /* Track input language.  */
371               const char *lang = decoded_options[i].arg;
372
373               saw_speclang = (strcmp (lang, "none") != 0);
374             }
375
376           append_arg (&decoded_options[i]);
377
378           continue;
379         }
380
381       /* A filename/library, not an option.  */
382
383       if (saw_speclang)
384         saw_library = 0;        /* -xfoo currently active.  */
385       else
386         {                       /* -lfoo or filename.  */
387           if (decoded_options[i].opt_index == OPT_l
388               && strcmp (decoded_options[i].arg, MATH_LIBRARY) == 0)
389             {
390               if (saw_library == 1)
391                 saw_library = 2;        /* -l<library> -lm.  */
392               else
393                 add_arg_libgfortran (static_lib && !static_linking);
394             }
395           else if (decoded_options[i].opt_index == OPT_l
396               && strcmp (decoded_options[i].arg, FORTRAN_LIBRARY) == 0)
397             {
398               saw_library = 1;  /* -l<library>.  */
399               add_arg_libgfortran (static_lib && !static_linking);
400               continue;
401             }
402           else
403             {                   /* Other library, or filename.  */
404               if (saw_library == 1 && need_math)
405                 append_option (OPT_l, MATH_LIBRARY, 1);
406               saw_library = 0;
407             }
408         }
409       append_arg (&decoded_options[i]);
410     }
411
412   /* Append `-lgfortran -lm' as necessary.  */
413
414   if (library)
415     {                           /* Doing a link and no -nostdlib.  */
416       if (saw_speclang)
417         append_option (OPT_x, "none", 1);
418
419       switch (saw_library)
420         {
421         case 0:
422           add_arg_libgfortran (static_lib && !static_linking);
423           /* Fall through.  */
424
425         case 1:
426           if (need_math)
427             append_option (OPT_l, MATH_LIBRARY, 1);
428         default:
429           break;
430         }
431     }
432
433 #ifdef ENABLE_SHARED_LIBGCC
434   if (library)
435     {
436       unsigned int i;
437
438       for (i = 1; i < g77_newargc; i++)
439         if (g77_new_decoded_options[i].opt_index == OPT_static_libgcc
440             || g77_new_decoded_options[i].opt_index == OPT_static)
441           break;
442
443       if (i == g77_newargc)
444         append_option (OPT_shared_libgcc, NULL, 1);
445     }
446
447 #endif
448
449   /* Read the specs file corresponding to libgfortran.
450      If we didn't find the spec file on the -L path, we load it
451      via lang_specific_pre_link.  */
452   if (spec_file)
453     append_option (OPT_specs_, spec_file, 1);
454
455   if (verbose && g77_new_decoded_options != g77_x_decoded_options)
456     {
457       fprintf (stderr, _("Driving:"));
458       for (i = 0; i < g77_newargc; i++)
459         fprintf (stderr, " %s",
460                  g77_new_decoded_options[i].orig_option_with_args_text);
461       fprintf (stderr, "\n");
462     }
463
464   *in_decoded_options_count = g77_newargc;
465   *in_decoded_options = g77_new_decoded_options;
466 }
467
468
469 /* Called before linking.  Returns 0 on success and -1 on failure.  */
470 int
471 lang_specific_pre_link (void)
472 {
473   if (spec_file)
474     free (spec_file);
475   else
476     do_spec ("%:include(libgfortran.spec)");
477
478   return 0;
479 }
480
481 /* Number of extra output files that lang_specific_pre_link may generate.  */
482 int lang_specific_extra_outfiles = 0;   /* Not used for F77.  */