OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [fortran/] [gfortranspec.c] - Blame information for rev 712

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 712 jeremybenn
/* 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, 2011, 2012
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
static char *spec_file = NULL;
80
 
81
/* This will be NULL if we encounter a situation where we should not
82
   link in the fortran libraries.  */
83
static const char *library = NULL;
84
 
85
 
86
/* Return full path name of spec file if it is in DIR, or NULL if
87
   not.  */
88
static char *
89
find_spec_file (const char *dir)
90
{
91
  const char dirsep_string[] = { DIR_SEPARATOR, '\0' };
92
  char *spec;
93
  struct stat sb;
94
 
95
  spec = XNEWVEC (char, strlen (dir) + sizeof (SPEC_FILE) + 4);
96
  strcpy (spec, dir);
97
  strcat (spec, dirsep_string);
98
  strcat (spec, SPEC_FILE);
99
  if (!stat (spec, &sb))
100
    return spec;
101
  free (spec);
102
  return NULL;
103
}
104
 
105
 
106
/* Return whether strings S1 and S2 are both NULL or both the same
107
   string.  */
108
 
109
static bool
110
strings_same (const char *s1, const char *s2)
111
{
112
  return s1 == s2 || (s1 != NULL && s2 != NULL && strcmp (s1, s2) == 0);
113
}
114
 
115
/* Return whether decoded option structures OPT1 and OPT2 are the
116
   same.  */
117
 
118
static bool
119
options_same (const struct cl_decoded_option *opt1,
120
              const struct cl_decoded_option *opt2)
121
{
122
  return (opt1->opt_index == opt2->opt_index
123
          && strings_same (opt1->arg, opt2->arg)
124
          && strings_same (opt1->orig_option_with_args_text,
125
                           opt2->orig_option_with_args_text)
126
          && strings_same (opt1->canonical_option[0],
127
                           opt2->canonical_option[0])
128
          && strings_same (opt1->canonical_option[1],
129
                           opt2->canonical_option[1])
130
          && strings_same (opt1->canonical_option[2],
131
                           opt2->canonical_option[2])
132
          && strings_same (opt1->canonical_option[3],
133
                           opt2->canonical_option[3])
134
          && (opt1->canonical_option_num_elements
135
              == opt2->canonical_option_num_elements)
136
          && opt1->value == opt2->value
137
          && opt1->errors == opt2->errors);
138
}
139
 
140
/* Append another argument to the list being built.  As long as it is
141
   identical to the corresponding arg in the original list, just increment
142
   the new arg count.  Otherwise allocate a new list, etc.  */
143
 
144
static void
145
append_arg (const struct cl_decoded_option *arg)
146
{
147
  static unsigned int newargsize;
148
 
149
  if (g77_new_decoded_options == g77_x_decoded_options
150
      && g77_newargc < g77_xargc
151
      && options_same (arg, &g77_x_decoded_options[g77_newargc]))
152
    {
153
      ++g77_newargc;
154
      return;                   /* Nothing new here.  */
155
    }
156
 
157
  if (g77_new_decoded_options == g77_x_decoded_options)
158
    {                           /* Make new arglist.  */
159
      unsigned int i;
160
 
161
      newargsize = (g77_xargc << 2) + 20;       /* This should handle all.  */
162
      g77_new_decoded_options = XNEWVEC (struct cl_decoded_option, newargsize);
163
 
164
      /* Copy what has been done so far.  */
165
      for (i = 0; i < g77_newargc; ++i)
166
        g77_new_decoded_options[i] = g77_x_decoded_options[i];
167
    }
168
 
169
  if (g77_newargc == newargsize)
170
    fatal_error ("overflowed output arg list for %qs",
171
                 arg->orig_option_with_args_text);
172
 
173
  g77_new_decoded_options[g77_newargc++] = *arg;
174
}
175
 
176
/* Append an option described by OPT_INDEX, ARG and VALUE to the list
177
   being built.  */
178
static void
179
append_option (size_t opt_index, const char *arg, int value)
180
{
181
  struct cl_decoded_option decoded;
182
 
183
  generate_option (opt_index, arg, value, CL_DRIVER, &decoded);
184
  append_arg (&decoded);
185
}
186
 
187
/* Append a libgfortran argument to the list being built.  If
188
   FORCE_STATIC, ensure the library is linked statically.  */
189
 
190
static void
191
add_arg_libgfortran (bool force_static ATTRIBUTE_UNUSED)
192
{
193
#ifdef HAVE_LD_STATIC_DYNAMIC
194
  if (force_static)
195
    append_option (OPT_Wl_, LD_STATIC_OPTION, 1);
196
#endif
197
  append_option (OPT_l, FORTRAN_LIBRARY, 1);
198
#ifdef HAVE_LD_STATIC_DYNAMIC
199
  if (force_static)
200
    append_option (OPT_Wl_, LD_DYNAMIC_OPTION, 1);
201
#endif
202
}
203
 
204
void
205
lang_specific_driver (struct cl_decoded_option **in_decoded_options,
206
                      unsigned int *in_decoded_options_count,
207
                      int *in_added_libraries ATTRIBUTE_UNUSED)
208
{
209
  unsigned int argc = *in_decoded_options_count;
210
  struct cl_decoded_option *decoded_options = *in_decoded_options;
211
  unsigned int i;
212
  int verbose = 0;
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
  library = FORTRAN_LIBRARY;
237
 
238
#if 0
239
  fprintf (stderr, "Incoming:");
240
  for (i = 0; i < argc; i++)
241
    fprintf (stderr, " %s", decoded_options[i].orig_option_with_args_text);
242
  fprintf (stderr, "\n");
243
#endif
244
 
245
  g77_xargc = argc;
246
  g77_x_decoded_options = decoded_options;
247
  g77_newargc = 0;
248
  g77_new_decoded_options = decoded_options;
249
 
250
  /* First pass through arglist.
251
 
252
     If -nostdlib or a "turn-off-linking" option is anywhere in the
253
     command line, don't do any library-option processing (except
254
     relating to -x).  */
255
 
256
  for (i = 1; i < argc; ++i)
257
    {
258
      if (decoded_options[i].errors & CL_ERR_MISSING_ARG)
259
        continue;
260
 
261
      switch (decoded_options[i].opt_index)
262
        {
263
        case OPT_SPECIAL_input_file:
264
          ++n_infiles;
265
          continue;
266
 
267
        case OPT_nostdlib:
268
        case OPT_nodefaultlibs:
269
        case OPT_c:
270
        case OPT_S:
271
        case OPT_fsyntax_only:
272
        case OPT_E:
273
          /* These options disable linking entirely or linking of the
274
             standard libraries.  */
275
          library = 0;
276
          break;
277
 
278
        case OPT_static_libgfortran:
279
#ifdef HAVE_LD_STATIC_DYNAMIC
280
          static_lib = 1;
281
#endif
282
          break;
283
 
284
        case OPT_static:
285
#ifdef HAVE_LD_STATIC_DYNAMIC
286
          static_linking = 1;
287
#endif
288
          break;
289
 
290
        case OPT_l:
291
          ++n_infiles;
292
          break;
293
 
294
        case OPT_o:
295
          ++n_outfiles;
296
          break;
297
 
298
        case OPT_v:
299
          verbose = 1;
300
          break;
301
 
302
        case OPT__version:
303
          printf ("GNU Fortran %s%s\n", pkgversion_string, version_string);
304
          printf ("Copyright %s 2012 Free Software Foundation, Inc.\n\n",
305
                  _("(C)"));
306
          printf (_("GNU Fortran comes with NO WARRANTY, to the extent permitted by law.\n\
307
You may redistribute copies of GNU Fortran\n\
308
under the terms of the GNU General Public License.\n\
309
For more information about these matters, see the file named COPYING\n\n"));
310
          exit (0);
311
          break;
312
 
313
        case OPT__help:
314
          /* Let gcc.c handle this, as it has a really
315
             cool facility for handling --help and --verbose --help.  */
316
          return;
317
 
318
        case OPT_L:
319
          if (!spec_file)
320
            spec_file = find_spec_file (decoded_options[i].arg);
321
          break;
322
 
323
 
324
        default:
325
          break;
326
        }
327
    }
328
 
329
  if ((n_outfiles != 0) && (n_infiles == 0))
330
    fatal_error ("no input files; unwilling to write output files");
331
 
332
  /* If there are no input files, no need for the library.  */
333
  if (n_infiles == 0)
334
    library = 0;
335
 
336
  /* Second pass through arglist, transforming arguments as appropriate.  */
337
 
338
  append_arg (&decoded_options[0]); /* Start with command name, of course.  */
339
 
340
  for (i = 1; i < argc; ++i)
341
    {
342
      if (decoded_options[i].errors & CL_ERR_MISSING_ARG)
343
        {
344
          append_arg (&decoded_options[i]);
345
          continue;
346
        }
347
 
348
      if (decoded_options[i].opt_index == OPT_SPECIAL_input_file
349
          && decoded_options[i].arg[0] == '\0')
350
        {
351
          /* Interesting.  Just append as is.  */
352
          append_arg (&decoded_options[i]);
353
          continue;
354
        }
355
 
356
      if (decoded_options[i].opt_index != OPT_l
357
          && (decoded_options[i].opt_index != OPT_SPECIAL_input_file
358
              || strcmp (decoded_options[i].arg, "-") == 0))
359
        {
360
          /* Not a filename or library.  */
361
 
362
          if (saw_library == 1 && need_math)    /* -l<library>.  */
363
            append_option (OPT_l, MATH_LIBRARY, 1);
364
 
365
          saw_library = 0;
366
 
367
          if (decoded_options[i].opt_index == OPT_SPECIAL_input_file)
368
            {
369
              append_arg (&decoded_options[i]); /* "-" == Standard input.  */
370
              continue;
371
            }
372
 
373
          if (decoded_options[i].opt_index == OPT_x)
374
            {
375
              /* Track input language.  */
376
              const char *lang = decoded_options[i].arg;
377
 
378
              saw_speclang = (strcmp (lang, "none") != 0);
379
            }
380
 
381
          append_arg (&decoded_options[i]);
382
 
383
          continue;
384
        }
385
 
386
      /* A filename/library, not an option.  */
387
 
388
      if (saw_speclang)
389
        saw_library = 0; /* -xfoo currently active.  */
390
      else
391
        {                       /* -lfoo or filename.  */
392
          if (decoded_options[i].opt_index == OPT_l
393
              && strcmp (decoded_options[i].arg, MATH_LIBRARY) == 0)
394
            {
395
              if (saw_library == 1)
396
                saw_library = 2;        /* -l<library> -lm.  */
397
              else
398
                add_arg_libgfortran (static_lib && !static_linking);
399
            }
400
          else if (decoded_options[i].opt_index == OPT_l
401
              && strcmp (decoded_options[i].arg, FORTRAN_LIBRARY) == 0)
402
            {
403
              saw_library = 1;  /* -l<library>.  */
404
              add_arg_libgfortran (static_lib && !static_linking);
405
              continue;
406
            }
407
          else
408
            {                   /* Other library, or filename.  */
409
              if (saw_library == 1 && need_math)
410
                append_option (OPT_l, MATH_LIBRARY, 1);
411
              saw_library = 0;
412
            }
413
        }
414
      append_arg (&decoded_options[i]);
415
    }
416
 
417
  /* Append `-lgfortran -lm' as necessary.  */
418
 
419
  if (library)
420
    {                           /* Doing a link and no -nostdlib.  */
421
      if (saw_speclang)
422
        append_option (OPT_x, "none", 1);
423
 
424
      switch (saw_library)
425
        {
426
        case 0:
427
          add_arg_libgfortran (static_lib && !static_linking);
428
          /* Fall through.  */
429
 
430
        case 1:
431
          if (need_math)
432
            append_option (OPT_l, MATH_LIBRARY, 1);
433
        default:
434
          break;
435
        }
436
    }
437
 
438
#ifdef ENABLE_SHARED_LIBGCC
439
  if (library)
440
    {
441
      unsigned int i;
442
 
443
      for (i = 1; i < g77_newargc; i++)
444
        if (g77_new_decoded_options[i].opt_index == OPT_static_libgcc
445
            || g77_new_decoded_options[i].opt_index == OPT_static)
446
          break;
447
 
448
      if (i == g77_newargc)
449
        append_option (OPT_shared_libgcc, NULL, 1);
450
    }
451
 
452
#endif
453
 
454
  /* Read the specs file corresponding to libgfortran.
455
     If we didn't find the spec file on the -L path, we load it
456
     via lang_specific_pre_link.  */
457
  if (spec_file)
458
    append_option (OPT_specs_, spec_file, 1);
459
 
460
  if (verbose && g77_new_decoded_options != g77_x_decoded_options)
461
    {
462
      fprintf (stderr, _("Driving:"));
463
      for (i = 0; i < g77_newargc; i++)
464
        fprintf (stderr, " %s",
465
                 g77_new_decoded_options[i].orig_option_with_args_text);
466
      fprintf (stderr, "\n");
467
    }
468
 
469
  *in_decoded_options_count = g77_newargc;
470
  *in_decoded_options = g77_new_decoded_options;
471
}
472
 
473
 
474
/* Called before linking.  Returns 0 on success and -1 on failure.  */
475
int
476
lang_specific_pre_link (void)
477
{
478
  free (spec_file);
479
  if (spec_file == NULL && library)
480
    do_spec ("%:include(libgfortran.spec)");
481
 
482
  return 0;
483
}
484
 
485
/* Number of extra output files that lang_specific_pre_link may generate.  */
486
int lang_specific_extra_outfiles = 0;    /* Not used for F77.  */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.