1 /* Specific flags and argument handling of the Fortran front-end.
2 Copyright (C) 1997, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free
3 Software Foundation, Inc.
5 This file is part of GCC.
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING. If not, write to
19 the Free Software Foundation, 51 Franklin Street, Fifth Floor,
20 Boston, MA 02110-1301, USA. */
21 /* This file is copied more or less verbatim from g77. */
22 /* This file contains a filter for the main `gcc' driver, which is
23 replicated for the `gfortran' driver by adding this filter. The purpose
24 of this filter is to be basically identical to gcc (in that
25 it faithfully passes all of the original arguments to gcc) but,
26 unless explicitly overridden by the user in certain ways, ensure
27 that the needs of the language supported by this wrapper are met.
29 For GNU Fortran 95(gfortran), we do the following to the argument list
30 before passing it to `gcc':
32 1. Make sure `-lgfortran -lm' is at the end of the list.
34 2. Make sure each time `-lgfortran' or `-lm' is seen, it forms
35 part of the series `-lgfortran -lm'.
37 #1 and #2 are not done if `-nostdlib' or any option that disables
38 the linking phase is present, or if `-xfoo' is in effect. Note that
39 a lack of source files or -l options disables linking.
41 This program was originally made out of gcc/cp/g++spec.c, but the
42 way it builds the new argument list was rewritten so it is much
43 easier to maintain, improve the way it decides to add or not add
44 extra arguments, etc. And several improvements were made in the
45 handling of arguments, primarily to make it more consistent with
52 #include "coretypes.h"
57 #define MATH_LIBRARY "-lm"
61 #define FORTRAN_INIT "-lgfortranbegin"
64 #ifndef FORTRAN_LIBRARY
65 #define FORTRAN_LIBRARY "-lgfortran"
68 /* Options this driver needs to recognize, not just know how to
72 OPTION_b
, /* Aka --prefix. */
73 OPTION_B
, /* Aka --target. */
74 OPTION_c
, /* Aka --compile. */
75 OPTION_E
, /* Aka --preprocess. */
76 OPTION_help
, /* --help. */
77 OPTION_i
, /* -imacros, -include, -include-*. */
79 OPTION_L
, /* Aka --library-directory. */
80 OPTION_nostdlib
, /* Aka --no-standard-libraries, or
82 OPTION_o
, /* Aka --output. */
83 OPTION_S
, /* Aka --assemble. */
84 OPTION_syntax_only
, /* -fsyntax-only. */
85 OPTION_v
, /* Aka --verbose. */
86 OPTION_version
, /* --version. */
87 OPTION_V
, /* Aka --use-version. */
88 OPTION_x
, /* Aka --language. */
89 OPTION_
/* Unrecognized or unimportant. */
93 /* The original argument list and related info is copied here. */
95 static const char *const *g77_xargv
;
96 static void lookup_option (Option
*, int *, const char **, const char *);
97 static void append_arg (const char *);
99 /* The new argument list will be built here. */
100 static int g77_newargc
;
101 static const char **g77_newargv
;
103 const struct spec_function lang_specific_spec_functions
[] = {{0,0}};
105 /* --- This comes from gcc.c (2.8.1) verbatim: */
107 /* This defines which switch letters take arguments. */
109 #ifndef SWITCH_TAKES_ARG
110 #define SWITCH_TAKES_ARG(CHAR) DEFAULT_SWITCH_TAKES_ARG(CHAR)
113 /* This defines which multi-letter switches take arguments. */
115 #ifndef WORD_SWITCH_TAKES_ARG
116 #define WORD_SWITCH_TAKES_ARG(STR) DEFAULT_WORD_SWITCH_TAKES_ARG (STR)
119 /* --- End of verbatim. */
121 /* Assumes text[0] == '-'. Returns number of argv items that belong to
122 (and follow) this one, an option id for options important to the
123 caller, and a pointer to the first char of the arg, if embedded (else
124 returns NULL, meaning no arg or it's the next argv).
126 Note that this also assumes gcc.c's pass converting long options
127 to short ones, where available, has already been run. */
130 lookup_option (Option
*xopt
, int *xskip
, const char **xarg
, const char *text
)
132 Option opt
= OPTION_
;
134 const char *arg
= NULL
;
136 if ((skip
= SWITCH_TAKES_ARG (text
[1])))
137 skip
-= (text
[2] != '\0'); /* See gcc.c. */
140 opt
= OPTION_B
, skip
= (text
[2] == '\0'), arg
= text
+ 2;
141 else if (text
[1] == 'b')
142 opt
= OPTION_b
, skip
= (text
[2] == '\0'), arg
= text
+ 2;
143 else if ((text
[1] == 'c') && (text
[2] == '\0'))
144 opt
= OPTION_c
, skip
= 0;
145 else if ((text
[1] == 'E') && (text
[2] == '\0'))
146 opt
= OPTION_E
, skip
= 0;
147 else if (text
[1] == 'i')
148 opt
= OPTION_i
, skip
= 0;
149 else if (text
[1] == 'l')
151 else if (text
[1] == 'L')
152 opt
= OPTION_L
, arg
= text
+ 2;
153 else if (text
[1] == 'o')
155 else if ((text
[1] == 'S') && (text
[2] == '\0'))
156 opt
= OPTION_S
, skip
= 0;
157 else if (text
[1] == 'V')
158 opt
= OPTION_V
, skip
= (text
[2] == '\0');
159 else if ((text
[1] == 'v') && (text
[2] == '\0'))
160 opt
= OPTION_v
, skip
= 0;
161 else if (text
[1] == 'x')
162 opt
= OPTION_x
, arg
= text
+ 2;
165 if ((skip
= WORD_SWITCH_TAKES_ARG (text
+ 1)) != 0) /* See gcc.c. */
167 else if (!strcmp (text
, "-fhelp")) /* Really --help!! */
169 else if (!strcmp (text
, "-nostdlib")
170 || !strcmp (text
, "-nodefaultlibs"))
171 opt
= OPTION_nostdlib
;
172 else if (!strcmp (text
, "-fsyntax-only"))
173 opt
= OPTION_syntax_only
;
174 else if (!strcmp (text
, "-dumpversion"))
175 opt
= OPTION_version
;
176 else if (!strcmp (text
, "-fversion")) /* Really --version!! */
177 opt
= OPTION_version
;
178 else if (!strcmp (text
, "-Xlinker") || !strcmp (text
, "-specs"))
190 if ((arg
!= NULL
) && (arg
[0] == '\0'))
197 /* Append another argument to the list being built. As long as it is
198 identical to the corresponding arg in the original list, just increment
199 the new arg count. Otherwise allocate a new list, etc. */
202 append_arg (const char *arg
)
204 static int newargsize
;
207 fprintf (stderr
, "`%s'\n", arg
);
210 if (g77_newargv
== g77_xargv
211 && g77_newargc
< g77_xargc
212 && (arg
== g77_xargv
[g77_newargc
]
213 || !strcmp (arg
, g77_xargv
[g77_newargc
])))
216 return; /* Nothing new here. */
219 if (g77_newargv
== g77_xargv
)
220 { /* Make new arglist. */
223 newargsize
= (g77_xargc
<< 2) + 20; /* This should handle all. */
224 g77_newargv
= (const char **) xmalloc (newargsize
* sizeof (char *));
226 /* Copy what has been done so far. */
227 for (i
= 0; i
< g77_newargc
; ++i
)
228 g77_newargv
[i
] = g77_xargv
[i
];
231 if (g77_newargc
== newargsize
)
232 fatal ("overflowed output arg list for '%s'", arg
);
234 g77_newargv
[g77_newargc
++] = arg
;
238 lang_specific_driver (int *in_argc
, const char *const **in_argv
,
239 int *in_added_libraries ATTRIBUTE_UNUSED
)
242 const char *const *argv
= *in_argv
;
249 /* This will be NULL if we encounter a situation where we should not
251 const char *library
= FORTRAN_LIBRARY
;
253 /* 0 => -xnone in effect.
254 1 => -xfoo in effect. */
255 int saw_speclang
= 0;
257 /* 0 => initial/reset state
258 1 => last arg was -l<library>
259 2 => last two args were -l<library> -lm. */
262 /* 0 => initial/reset state
263 1 => FORTRAN_INIT linked in */
266 /* By default, we throw on the math library if we have one. */
267 int need_math
= (MATH_LIBRARY
[0] != '\0');
269 /* The number of input and output files in the incoming arg list. */
274 fprintf (stderr
, "Incoming:");
275 for (i
= 0; i
< argc
; i
++)
276 fprintf (stderr
, " %s", argv
[i
]);
277 fprintf (stderr
, "\n");
283 g77_newargv
= (const char **) argv
;
285 /* First pass through arglist.
287 If -nostdlib or a "turn-off-linking" option is anywhere in the
288 command line, don't do any library-option processing (except
289 relating to -x). Also, if -v is specified, but no other options
290 that do anything special (allowing -V version, etc.), remember
291 to add special stuff to make gcc command actually invoke all
292 the different phases of the compilation process so all the version
295 Also, here is where all problems with missing arguments to options
296 are caught. If this loop is exited normally, it means all options
297 have the appropriate number of arguments as far as the rest of this
298 program is concerned. */
300 for (i
= 1; i
< argc
; ++i
)
302 if ((argv
[i
][0] == '+') && (argv
[i
][1] == 'e'))
307 if ((argv
[i
][0] != '-') || (argv
[i
][1] == '\0'))
313 lookup_option (&opt
, &skip
, NULL
, argv
[i
]);
317 case OPTION_nostdlib
:
320 case OPTION_syntax_only
:
322 /* These options disable linking entirely or linking of the
323 standard libraries. */
344 /* These options are useful in conjunction with -v to get
345 appropriate version info. */
349 printf ("GNU Fortran 95 (GCC) %s\n", version_string
);
350 printf ("Copyright %s 2005 Free Software Foundation, Inc.\n\n",
352 printf (_("GNU Fortran comes with NO WARRANTY, to the extent permitted by law.\n\
353 You may redistribute copies of GNU Fortran\n\
354 under the terms of the GNU General Public License.\n\
355 For more information about these matters, see the file named COPYING\n\n"));
360 /* Let gcc.c handle this, as it has a really
361 cool facility for handling --help and --verbose --help. */
368 /* This is the one place we check for missing arguments in the
374 fatal ("argument to '%s' missing", argv
[i
]);
377 if ((n_outfiles
!= 0) && (n_infiles
== 0))
378 fatal ("no input files; unwilling to write output files");
380 /* If there are no input files, no need for the library. */
384 /* Second pass through arglist, transforming arguments as appropriate. */
386 append_arg (argv
[0]); /* Start with command name, of course. */
388 for (i
= 1; i
< argc
; ++i
)
390 if (argv
[i
][0] == '\0')
392 append_arg (argv
[i
]); /* Interesting. Just append as is. */
396 if ((argv
[i
][0] == '-') && (argv
[i
][1] == 'M'))
400 if (argv
[i
][2] == '\0')
402 p
= xmalloc (strlen (argv
[i
+ 1]) + 2);
405 strcpy (&p
[2], argv
[i
+ 1]);
410 p
= xmalloc (strlen (argv
[i
]) + 1);
417 if ((argv
[i
][0] == '-') && (argv
[i
][1] != 'l'))
419 /* Not a filename or library. */
421 if (saw_library
== 1 && need_math
) /* -l<library>. */
422 append_arg (MATH_LIBRARY
);
426 lookup_option (&opt
, &skip
, &arg
, argv
[i
]);
428 if (argv
[i
][1] == '\0')
430 append_arg (argv
[i
]); /* "-" == Standard input. */
436 /* Track input language. */
444 saw_speclang
= (strcmp (lang
, "none") != 0);
447 append_arg (argv
[i
]);
449 for (; skip
!= 0; --skip
)
450 append_arg (argv
[++i
]);
455 /* A filename/library, not an option. */
458 saw_library
= 0; /* -xfoo currently active. */
460 { /* -lfoo or filename. */
461 if (strcmp (argv
[i
], MATH_LIBRARY
) == 0)
463 if (saw_library
== 1)
464 saw_library
= 2; /* -l<library> -lm. */
469 append_arg (FORTRAN_INIT
);
472 append_arg (FORTRAN_LIBRARY
);
475 else if (strcmp (argv
[i
], FORTRAN_LIBRARY
) == 0)
476 saw_library
= 1; /* -l<library>. */
478 { /* Other library, or filename. */
479 if (saw_library
== 1 && need_math
)
480 append_arg (MATH_LIBRARY
);
484 append_arg (argv
[i
]);
487 /* Append `-lg2c -lm' as necessary. */
490 { /* Doing a link and no -nostdlib. */
492 append_arg ("-xnone");
499 append_arg (FORTRAN_INIT
);
502 append_arg (library
);
505 append_arg (MATH_LIBRARY
);
511 #ifdef ENABLE_SHARED_LIBGCC
516 for (i
= 1; i
< g77_newargc
; i
++)
517 if (g77_newargv
[i
][0] == '-')
518 if (strcmp (g77_newargv
[i
], "-static-libgcc") == 0
519 || strcmp (g77_newargv
[i
], "-static") == 0)
522 if (i
== g77_newargc
)
523 append_arg ("-shared-libgcc");
528 if (verbose
&& g77_newargv
!= g77_xargv
)
530 fprintf (stderr
, _("Driving:"));
531 for (i
= 0; i
< g77_newargc
; i
++)
532 fprintf (stderr
, " %s", g77_newargv
[i
]);
533 fprintf (stderr
, "\n");
536 *in_argc
= g77_newargc
;
537 *in_argv
= g77_newargv
;
540 /* Called before linking. Returns 0 on success and -1 on failure. */
542 lang_specific_pre_link (void) /* Not used for F77. */
547 /* Number of extra output files that lang_specific_pre_link may generate. */
548 int lang_specific_extra_outfiles
= 0; /* Not used for F77. */