1 /* G++ preliminary semantic processing for the compiler driver.
2 Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc.
3 Contributed by Brendan Kehoe (brendan@cygnus.com).
5 This file is part of GNU CC.
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, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
22 /* This program is a wrapper to the main `gcc' driver. For GNU C++,
23 we need to do two special things: a) append `-lg++' in situations
24 where it's appropriate, to link in libg++, and b) add `-xc++'..`-xnone'
25 around file arguments named `foo.c' or `foo.i'. So, we do all of
26 this semantic processing then just exec gcc with the new argument
29 We used to do all of this in a small shell script, but many users
30 found the performance of this as a shell script to be unacceptable.
31 In situations where your PATH has a lot of NFS-mounted directories,
32 using a script that runs sed and other things would be a nasty
33 performance hit. With this program, we never search the PATH at all. */
42 #include <sys/types.h>
44 #include <sys/file.h> /* May get R_OK, etc. on some systems. */
50 /* Defined to the name of the compiler; if using a cross compiler, the
51 Makefile should compile this file with the proper name
52 (e.g., "i386-aout-gcc"). */
54 #define GCC_NAME "gcc"
57 /* This bit is set if we saw a `-xfoo' language specification. */
58 #define LANGSPEC (1<<1)
59 /* This bit is set if they did `-lm' or `-lmath'. */
60 #define MATHLIB (1<<2)
63 #define MATH_LIBRARY "-lm"
66 /* On MSDOS, write temp files in current dir
67 because there's no place else we can expect to use. */
81 #define PVPROTO(ARGS) ARGS
82 #define VPROTO(ARGS) ARGS
83 #define VA_START(va_list,var) va_start(va_list,var)
85 #define PVPROTO(ARGS) ()
86 #define VPROTO(ARGS) (va_alist) va_dcl
87 #define VA_START(va_list,var) va_start(va_list)
98 extern const char *const sys_errlist[];
100 extern char *sys_errlist[];
103 extern char *strerror();
106 /* Name with which this program was invoked. */
107 static char *programname;
119 static char buffer[30];
123 if (e > 0 && e < sys_nerr)
124 return sys_errlist[e];
126 sprintf (buffer, "Unknown error %d", e);
132 /* Output an error message and exit */
135 fatal VPROTO((char *format, ...))
142 VA_START (ap, format);
145 format = va_arg (ap, char*);
148 fprintf (stderr, "%s: ", programname);
149 vfprintf (stderr, format, ap);
151 fprintf (stderr, "\n");
153 /* XXX Not needed for g++ driver. */
154 delete_temp_files ();
160 error VPROTO((char *format, ...))
167 VA_START (ap, format);
170 format = va_arg (ap, char*);
173 fprintf (stderr, "%s: ", programname);
174 vfprintf (stderr, format, ap);
177 fprintf (stderr, "\n");
180 #else /* not HAVE_VPRINTF */
183 error (msg, arg1, arg2)
184 char *msg, *arg1, *arg2;
186 fprintf (stderr, "%s: ", programname);
187 fprintf (stderr, msg, arg1, arg2);
188 fprintf (stderr, "\n");
192 fatal (msg, arg1, arg2)
193 char *msg, *arg1, *arg2;
195 error (msg, arg1, arg2);
197 /* XXX Not needed for g++ driver. */
198 delete_temp_files ();
203 #endif /* not HAVE_VPRINTF */
205 /* More 'friendly' abort that prints the line and file.
206 config.h can #define abort fancy_abort if you like that sort of thing. */
211 fatal ("Internal g++ abort.");
218 register char *value = (char *) malloc (size);
220 fatal ("virtual memory exhausted");
224 /* Return a newly-allocated string whose contents concatenate those
230 int len1 = strlen (s1), len2 = strlen (s2), len3 = strlen (s3);
231 char *result = xmalloc (len1 + len2 + len3 + 1);
234 strcpy (result + len1, s2);
235 strcpy (result + len1 + len2, s3);
236 *(result + len1 + len2 + len3) = 0;
242 pfatal_with_name (name)
245 fatal (concat ("%s: ", my_strerror (errno), ""), name);
249 /* This is the common prefix we use to make temp file names. */
252 /* Length of the prefix. */
253 int temp_filename_length;
255 /* Compute a string to use as the base of all temporary file names. */
257 choose_temp_base_try (try, base)
264 else if (try == (char *)0)
266 else if (access (try, R_OK | W_OK) != 0)
279 base = choose_temp_base_try (getenv ("TMPDIR"), base);
280 base = choose_temp_base_try (getenv ("TMP"), base);
281 base = choose_temp_base_try (getenv ("TEMP"), base);
284 base = choose_temp_base_try (P_tmpdir, base);
287 base = choose_temp_base_try ("/usr/tmp", base);
288 base = choose_temp_base_try ("/tmp", base);
290 /* If all else fails, use the current directory! */
291 if (base == (char *)0)
295 temp_filename = xmalloc (len + sizeof("/ccXXXXXX"));
296 strcpy (temp_filename, base);
297 if (len > 0 && temp_filename[len-1] != '/')
298 temp_filename[len++] = '/';
299 strcpy (temp_filename + len, "ccXXXXXX");
301 mktemp (temp_filename);
302 temp_filename_length = strlen (temp_filename);
303 if (temp_filename_length == 0)
313 if (errno < sys_nerr)
314 s = concat ("installation problem, cannot exec %s: ",
315 my_strerror( errno ), "");
317 s = "installation problem, cannot exec %s";
321 /* This is almost exactly what's in gcc.c:pexecute for MSDOS. */
323 run_dos (program, argv)
331 choose_temp_base (); /* not in gcc.c */
333 scmd = (char *) malloc (strlen (program) + strlen (temp_filename) + 10);
334 rf = scmd + strlen (program) + 6;
335 sprintf (scmd, "%s.exe @%s.gp", program, temp_filename);
337 argfile = fopen (rf, "w");
339 pfatal_with_name (rf);
341 for (i=1; argv[i]; i++)
344 for (cp = argv[i]; *cp; cp++)
346 if (*cp == '"' || *cp == '\'' || *cp == '\\' || isspace (*cp))
347 fputc ('\\', argfile);
348 fputc (*cp, argfile);
350 fputc ('\n', argfile);
359 perror_exec (program);
361 #endif /* __MSDOS__ */
368 register int i, j = 0;
372 /* This will be 0 if we encounter a situation where we should not
373 link in libstdc++, or 2 if we should link in libg++ as well. */
376 /* Used to track options that take arguments, so we don't go wrapping
377 those with -xc++/-xnone. */
380 /* The new argument list will be contained in this. */
383 /* The name of the compiler we will want to run---by default, it
384 will be the definition of `GCC_NAME', e.g., `gcc'. */
385 char *gcc = GCC_NAME;
387 /* Non-zero if we saw a `-xfoo' language specification on the
388 command line. Used to avoid adding our own -xc++ if the user
389 already gave a language for the file. */
390 int saw_speclang = 0;
392 /* Non-zero if we saw `-lm' or `-lmath' on the command line. */
395 /* The number of arguments being added to what's in argv, other than
396 libraries. We use this to track the number of times we've inserted
400 /* An array used to flag each argument that needs a bit set for
401 LANGSPEC or MATHLIB. */
404 p = argv[0] + strlen (argv[0]);
406 /* If we're called as g++ (or i386-aout-g++), link in libg++ as well. */
408 if (strcmp (p - 3, "g++") == 0)
413 while (p != argv[0] && p[-1] != '/')
418 fatal ("No input files specified");
421 /* We do a little magic to find out where the main gcc executable
422 is. If they ran us as /usr/local/bin/g++, then we will look
423 for /usr/local/bin/gcc; similarly, if they just ran us as `g++',
424 we'll just look for `gcc'. */
428 gcc = (char *) malloc ((strlen (argv[0]) + 1 + strlen (GCC_NAME) + 1)
430 sprintf (gcc, "%s/%s", argv[0], GCC_NAME);
434 args = (int *) malloc (argc * sizeof (int));
435 bzero ((char *) args, argc * sizeof (int));
437 for (i = 1; i < argc; i++)
439 /* If the previous option took an argument, we swallow it here. */
446 if (argv[i][0] == '\0' || argv[i][1] == '\0')
449 if (argv[i][0] == '-')
451 if (library != 0 && strcmp (argv[i], "-nostdlib") == 0)
455 else if (strcmp (argv[i], "-lm") == 0
456 || strcmp (argv[i], "-lmath") == 0)
458 else if (strcmp (argv[i], "-v") == 0)
463 /* If they only gave us `-v', don't try to link
468 else if (strncmp (argv[i], "-x", 2) == 0)
470 else if (((argv[i][2] == '\0'
471 && (char *)strchr ("bBVDUoeTuIYmLiA", argv[i][1]) != NULL)
472 || strcmp (argv[i], "-Tdata") == 0))
474 else if (library != 0 && ((argv[i][2] == '\0'
475 && (char *) strchr ("cSEM", argv[i][1]) != NULL)
476 || strcmp (argv[i], "-MM") == 0))
478 /* Don't specify libraries if we won't link, since that would
483 /* Pass other options through. */
496 /* If the filename ends in .c or .i, put options around it.
497 But not if a specified -x option is currently active. */
498 len = strlen (argv[i]);
500 && (argv[i][len - 1] == 'c' || argv[i][len - 1] == 'i')
501 && argv[i][len - 2] == '.')
510 fatal ("argument to `%s' missing\n", quote);
512 if (added || library)
514 arglist = (char **) malloc ((argc + added + 4) * sizeof (char *));
516 for (i = 1, j = 1; i < argc; i++, j++)
518 arglist[j] = argv[i];
520 /* Make sure -lg++ is before the math library, since libg++
521 itself uses those math routines. */
522 if (!saw_math && (args[i] & MATHLIB) && library)
528 /* Wrap foo.c and foo.i files in a language specification to
529 force the gcc compiler driver to run cc1plus on them. */
530 if (args[i] & LANGSPEC)
532 int len = strlen (argv[i]);
533 if (argv[i][len - 1] == 'i')
534 arglist[j++] = "-xc++-cpp-output";
536 arglist[j++] = "-xc++";
537 arglist[j++] = argv[i];
538 arglist[j] = "-xnone";
542 /* Add `-lg++' if we haven't already done so. */
544 arglist[j++] = "-lg++";
546 arglist[j++] = "-lstdc++";
548 arglist[j++] = saw_math;
550 arglist[j++] = MATH_LIBRARY;
555 /* No need to copy 'em all. */
565 for (i = 0; i < j; i++)
566 fprintf (stderr, " %s", arglist[i]);
567 fprintf (stderr, "\n");
569 #if !defined(OS2) && !defined (_WIN32)
571 run_dos (gcc, arglist);
572 #else /* !__MSDOS__ */
573 if (execvp (gcc, arglist) < 0)
574 pfatal_with_name (gcc);
575 #endif /* __MSDOS__ */
576 #else /* OS2 or _WIN32 */
577 if (spawnvp (1, gcc, arglist) < 0)
578 pfatal_with_name (gcc);