1 /* Specific flags and argument handling of the Fortran front-end.
2 Copyright (C) 1997, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
3 Free 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 3, 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 GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
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 #ifdef HAVE_LD_STATIC_DYNAMIC
69 #define ADD_ARG_LIBGFORTRAN(arg) \
71 if (static_lib && !static_linking) \
72 append_arg ("-Wl,-Bstatic"); \
74 if (static_lib && !static_linking) \
75 append_arg ("-Wl,-Bdynamic"); \
78 #define ADD_ARG_LIBGFORTRAN(arg) append_arg (arg);
82 /* Options this driver needs to recognize, not just know how to
86 OPTION_b
, /* Aka --prefix. */
87 OPTION_B
, /* Aka --target. */
88 OPTION_c
, /* Aka --compile. */
89 OPTION_E
, /* Aka --preprocess. */
90 OPTION_help
, /* --help. */
91 OPTION_i
, /* -imacros, -include, -include-*. */
93 OPTION_L
, /* Aka --library-directory. */
94 OPTION_nostdlib
, /* Aka --no-standard-libraries, or
96 OPTION_o
, /* Aka --output. */
97 OPTION_S
, /* Aka --assemble. */
98 OPTION_static
, /* -static. */
99 OPTION_static_libgfortran
, /* -static-libgfortran. */
100 OPTION_syntax_only
, /* -fsyntax-only. */
101 OPTION_v
, /* Aka --verbose. */
102 OPTION_version
, /* --version. */
103 OPTION_V
, /* Aka --use-version. */
104 OPTION_x
, /* Aka --language. */
105 OPTION_
/* Unrecognized or unimportant. */
109 /* The original argument list and related info is copied here. */
110 static int g77_xargc
;
111 static const char *const *g77_xargv
;
112 static void lookup_option (Option
*, int *, const char **, const char *);
113 static void append_arg (const char *);
115 /* The new argument list will be built here. */
116 static int g77_newargc
;
117 static const char **g77_newargv
;
119 /* --- This comes from gcc.c (2.8.1) verbatim: */
121 /* This defines which switch letters take arguments. */
123 #ifndef SWITCH_TAKES_ARG
124 #define SWITCH_TAKES_ARG(CHAR) DEFAULT_SWITCH_TAKES_ARG(CHAR)
127 /* This defines which multi-letter switches take arguments. */
129 #ifndef WORD_SWITCH_TAKES_ARG
130 #define WORD_SWITCH_TAKES_ARG(STR) DEFAULT_WORD_SWITCH_TAKES_ARG (STR)
133 /* --- End of verbatim. */
135 /* Assumes text[0] == '-'. Returns number of argv items that belong to
136 (and follow) this one, an option id for options important to the
137 caller, and a pointer to the first char of the arg, if embedded (else
138 returns NULL, meaning no arg or it's the next argv).
140 Note that this also assumes gcc.c's pass converting long options
141 to short ones, where available, has already been run. */
144 lookup_option (Option
*xopt
, int *xskip
, const char **xarg
, const char *text
)
146 Option opt
= OPTION_
;
148 const char *arg
= NULL
;
150 if ((skip
= SWITCH_TAKES_ARG (text
[1])))
151 skip
-= (text
[2] != '\0'); /* See gcc.c. */
154 opt
= OPTION_B
, skip
= (text
[2] == '\0'), arg
= text
+ 2;
155 else if (text
[1] == 'b')
156 opt
= OPTION_b
, skip
= (text
[2] == '\0'), arg
= text
+ 2;
157 else if ((text
[1] == 'c') && (text
[2] == '\0'))
158 opt
= OPTION_c
, skip
= 0;
159 else if ((text
[1] == 'E') && (text
[2] == '\0'))
160 opt
= OPTION_E
, skip
= 0;
161 else if (text
[1] == 'i')
162 opt
= OPTION_i
, skip
= 0;
163 else if (text
[1] == 'l')
165 else if (text
[1] == 'L')
166 opt
= OPTION_L
, arg
= text
+ 2;
167 else if (text
[1] == 'o')
169 else if ((text
[1] == 'S') && (text
[2] == '\0'))
170 opt
= OPTION_S
, skip
= 0;
171 else if (text
[1] == 'V')
172 opt
= OPTION_V
, skip
= (text
[2] == '\0');
173 else if ((text
[1] == 'v') && (text
[2] == '\0'))
174 opt
= OPTION_v
, skip
= 0;
175 else if (text
[1] == 'x')
176 opt
= OPTION_x
, arg
= text
+ 2;
179 if ((skip
= WORD_SWITCH_TAKES_ARG (text
+ 1)) != 0) /* See gcc.c. */
181 else if (!strcmp (text
, "-fhelp")) /* Really --help!! */
183 else if (!strcmp (text
, "-nostdlib")
184 || !strcmp (text
, "-nodefaultlibs"))
185 opt
= OPTION_nostdlib
;
186 else if (!strcmp (text
, "-fsyntax-only"))
187 opt
= OPTION_syntax_only
;
188 else if (!strcmp (text
, "-static-libgfortran"))
189 opt
= OPTION_static_libgfortran
;
190 else if (!strcmp (text
, "-dumpversion"))
191 opt
= OPTION_version
;
192 else if (!strcmp (text
, "-fversion")) /* Really --version!! */
193 opt
= OPTION_version
;
194 else if (!strcmp (text
, "-Xlinker") || !strcmp (text
, "-specs"))
206 if ((arg
!= NULL
) && (arg
[0] == '\0'))
213 /* Append another argument to the list being built. As long as it is
214 identical to the corresponding arg in the original list, just increment
215 the new arg count. Otherwise allocate a new list, etc. */
218 append_arg (const char *arg
)
220 static int newargsize
;
223 fprintf (stderr
, "`%s'\n", arg
);
226 if (g77_newargv
== g77_xargv
227 && g77_newargc
< g77_xargc
228 && (arg
== g77_xargv
[g77_newargc
]
229 || !strcmp (arg
, g77_xargv
[g77_newargc
])))
232 return; /* Nothing new here. */
235 if (g77_newargv
== g77_xargv
)
236 { /* Make new arglist. */
239 newargsize
= (g77_xargc
<< 2) + 20; /* This should handle all. */
240 g77_newargv
= (const char **) xmalloc (newargsize
* sizeof (char *));
242 /* Copy what has been done so far. */
243 for (i
= 0; i
< g77_newargc
; ++i
)
244 g77_newargv
[i
] = g77_xargv
[i
];
247 if (g77_newargc
== newargsize
)
248 fatal ("overflowed output arg list for '%s'", arg
);
250 g77_newargv
[g77_newargc
++] = arg
;
254 lang_specific_driver (int *in_argc
, const char *const **in_argv
,
255 int *in_added_libraries ATTRIBUTE_UNUSED
)
258 const char *const *argv
= *in_argv
;
265 /* This will be NULL if we encounter a situation where we should not
267 const char *library
= FORTRAN_LIBRARY
;
269 /* 0 => -xnone in effect.
270 1 => -xfoo in effect. */
271 int saw_speclang
= 0;
273 /* 0 => initial/reset state
274 1 => last arg was -l<library>
275 2 => last two args were -l<library> -lm. */
278 /* 0 => initial/reset state
279 1 => FORTRAN_INIT linked in */
282 /* By default, we throw on the math library if we have one. */
283 int need_math
= (MATH_LIBRARY
[0] != '\0');
285 /* Whether we should link a static libgfortran. */
288 /* Whether we need to link statically. */
289 int static_linking
= 0;
291 /* The number of input and output files in the incoming arg list. */
296 fprintf (stderr
, "Incoming:");
297 for (i
= 0; i
< argc
; i
++)
298 fprintf (stderr
, " %s", argv
[i
]);
299 fprintf (stderr
, "\n");
305 g77_newargv
= (const char **) CONST_CAST (argv
);
307 /* First pass through arglist.
309 If -nostdlib or a "turn-off-linking" option is anywhere in the
310 command line, don't do any library-option processing (except
311 relating to -x). Also, if -v is specified, but no other options
312 that do anything special (allowing -V version, etc.), remember
313 to add special stuff to make gcc command actually invoke all
314 the different phases of the compilation process so all the version
317 Also, here is where all problems with missing arguments to options
318 are caught. If this loop is exited normally, it means all options
319 have the appropriate number of arguments as far as the rest of this
320 program is concerned. */
322 for (i
= 1; i
< argc
; ++i
)
324 if ((argv
[i
][0] == '+') && (argv
[i
][1] == 'e'))
329 if ((argv
[i
][0] != '-') || (argv
[i
][1] == '\0'))
335 lookup_option (&opt
, &skip
, NULL
, argv
[i
]);
339 case OPTION_nostdlib
:
342 case OPTION_syntax_only
:
344 /* These options disable linking entirely or linking of the
345 standard libraries. */
349 case OPTION_static_libgfortran
:
373 /* These options are useful in conjunction with -v to get
374 appropriate version info. */
378 printf ("GNU Fortran %s%s\n", pkgversion_string
, version_string
);
379 printf ("Copyright %s 2007 Free Software Foundation, Inc.\n\n",
381 printf (_("GNU Fortran comes with NO WARRANTY, to the extent permitted by law.\n\
382 You may redistribute copies of GNU Fortran\n\
383 under the terms of the GNU General Public License.\n\
384 For more information about these matters, see the file named COPYING\n\n"));
389 /* Let gcc.c handle this, as it has a really
390 cool facility for handling --help and --verbose --help. */
397 /* This is the one place we check for missing arguments in the
403 fatal ("argument to '%s' missing", argv
[i
]);
406 if ((n_outfiles
!= 0) && (n_infiles
== 0))
407 fatal ("no input files; unwilling to write output files");
409 /* If there are no input files, no need for the library. */
413 /* Second pass through arglist, transforming arguments as appropriate. */
415 append_arg (argv
[0]); /* Start with command name, of course. */
417 for (i
= 1; i
< argc
; ++i
)
419 if (argv
[i
][0] == '\0')
421 append_arg (argv
[i
]); /* Interesting. Just append as is. */
425 if ((argv
[i
][0] == '-') && (argv
[i
][1] == 'M'))
429 if (argv
[i
][2] == '\0')
431 p
= XNEWVEC (char, strlen (argv
[i
+ 1]) + 2);
434 strcpy (&p
[2], argv
[i
+ 1]);
439 p
= XNEWVEC (char, strlen (argv
[i
]) + 1);
446 if ((argv
[i
][0] == '-') && (argv
[i
][1] != 'l'))
448 /* Not a filename or library. */
450 if (saw_library
== 1 && need_math
) /* -l<library>. */
451 append_arg (MATH_LIBRARY
);
455 lookup_option (&opt
, &skip
, &arg
, argv
[i
]);
457 if (argv
[i
][1] == '\0')
459 append_arg (argv
[i
]); /* "-" == Standard input. */
465 /* Track input language. */
473 saw_speclang
= (strcmp (lang
, "none") != 0);
476 append_arg (argv
[i
]);
478 for (; skip
!= 0; --skip
)
479 append_arg (argv
[++i
]);
484 /* A filename/library, not an option. */
487 saw_library
= 0; /* -xfoo currently active. */
489 { /* -lfoo or filename. */
490 if (strcmp (argv
[i
], MATH_LIBRARY
) == 0)
492 if (saw_library
== 1)
493 saw_library
= 2; /* -l<library> -lm. */
498 append_arg (FORTRAN_INIT
);
502 ADD_ARG_LIBGFORTRAN (FORTRAN_LIBRARY
);
505 else if (strcmp (argv
[i
], FORTRAN_LIBRARY
) == 0)
507 saw_library
= 1; /* -l<library>. */
508 ADD_ARG_LIBGFORTRAN (argv
[i
]);
512 { /* Other library, or filename. */
513 if (saw_library
== 1 && need_math
)
514 append_arg (MATH_LIBRARY
);
518 append_arg (argv
[i
]);
521 /* Append `-lg2c -lm' as necessary. */
524 { /* Doing a link and no -nostdlib. */
526 append_arg ("-xnone");
533 append_arg (FORTRAN_INIT
);
536 ADD_ARG_LIBGFORTRAN (library
);
541 append_arg (MATH_LIBRARY
);
547 #ifdef ENABLE_SHARED_LIBGCC
552 for (i
= 1; i
< g77_newargc
; i
++)
553 if (g77_newargv
[i
][0] == '-')
554 if (strcmp (g77_newargv
[i
], "-static-libgcc") == 0
555 || strcmp (g77_newargv
[i
], "-static") == 0)
558 if (i
== g77_newargc
)
559 append_arg ("-shared-libgcc");
564 if (verbose
&& g77_newargv
!= g77_xargv
)
566 fprintf (stderr
, _("Driving:"));
567 for (i
= 0; i
< g77_newargc
; i
++)
568 fprintf (stderr
, " %s", g77_newargv
[i
]);
569 fprintf (stderr
, "\n");
572 *in_argc
= g77_newargc
;
573 *in_argv
= g77_newargv
;
577 /* Called before linking. Returns 0 on success and -1 on failure. */
579 lang_specific_pre_link (void) /* Not used for F77. */
584 /* Number of extra output files that lang_specific_pre_link may generate. */
585 int lang_specific_extra_outfiles
= 0; /* Not used for F77. */