g++spec.c revision 90075
150397Sobrien/* Specific flags and argument handling of the C++ front-end. 290075Sobrien Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. 350397Sobrien 450397SobrienThis file is part of GNU CC. 550397Sobrien 650397SobrienGNU CC is free software; you can redistribute it and/or modify 750397Sobrienit under the terms of the GNU General Public License as published by 850397Sobrienthe Free Software Foundation; either version 2, or (at your option) 950397Sobrienany later version. 1050397Sobrien 1150397SobrienGNU CC is distributed in the hope that it will be useful, 1250397Sobrienbut WITHOUT ANY WARRANTY; without even the implied warranty of 1350397SobrienMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1450397SobrienGNU General Public License for more details. 1550397Sobrien 1650397SobrienYou should have received a copy of the GNU General Public License 1750397Sobrienalong with GNU CC; see the file COPYING. If not, write to 1850397Sobrienthe Free Software Foundation, 59 Temple Place - Suite 330, 1950397SobrienBoston, MA 02111-1307, USA. */ 2050397Sobrien 2150397Sobrien#include "config.h" 2250397Sobrien#include "system.h" 2390075Sobrien#include "gcc.h" 2450397Sobrien 2550397Sobrien/* This bit is set if we saw a `-xfoo' language specification. */ 2650397Sobrien#define LANGSPEC (1<<1) 2750397Sobrien/* This bit is set if they did `-lm' or `-lmath'. */ 2850397Sobrien#define MATHLIB (1<<2) 2950397Sobrien/* This bit is set if they did `-lc'. */ 3050397Sobrien#define WITHLIBC (1<<3) 3150397Sobrien 3250397Sobrien#ifndef MATH_LIBRARY 3350397Sobrien#define MATH_LIBRARY "-lm" 3450397Sobrien#endif 3552284Sobrien 3652284Sobrien#ifndef LIBSTDCXX 3752284Sobrien#define LIBSTDCXX "-lstdc++" 3850397Sobrien#endif 3950397Sobrien 4050397Sobrienvoid 4190075Sobrienlang_specific_driver (in_argc, in_argv, in_added_libraries) 4250397Sobrien int *in_argc; 4390075Sobrien const char *const **in_argv; 4450397Sobrien int *in_added_libraries; 4550397Sobrien{ 4650397Sobrien int i, j; 4750397Sobrien 4850397Sobrien /* If non-zero, the user gave us the `-v' flag. */ 4950397Sobrien int saw_verbose_flag = 0; 5050397Sobrien 5150397Sobrien /* This will be 0 if we encounter a situation where we should not 5250397Sobrien link in libstdc++. */ 5350397Sobrien int library = 1; 5450397Sobrien 5550397Sobrien /* The number of arguments being added to what's in argv, other than 5650397Sobrien libraries. We use this to track the number of times we've inserted 5750397Sobrien -xc++/-xnone. */ 5850397Sobrien int added = 2; 5950397Sobrien 6050397Sobrien /* Used to track options that take arguments, so we don't go wrapping 6150397Sobrien those with -xc++/-xnone. */ 6290075Sobrien const char *quote = NULL; 6350397Sobrien 6450397Sobrien /* The new argument list will be contained in this. */ 6590075Sobrien const char **arglist; 6650397Sobrien 6750397Sobrien /* Non-zero if we saw a `-xfoo' language specification on the 6850397Sobrien command line. Used to avoid adding our own -xc++ if the user 6950397Sobrien already gave a language for the file. */ 7050397Sobrien int saw_speclang = 0; 7150397Sobrien 7250397Sobrien /* "-lm" or "-lmath" if it appears on the command line. */ 7390075Sobrien const char *saw_math = 0; 7450397Sobrien 7550397Sobrien /* "-lc" if it appears on the command line. */ 7690075Sobrien const char *saw_libc = 0; 7750397Sobrien 7850397Sobrien /* An array used to flag each argument that needs a bit set for 7950397Sobrien LANGSPEC, MATHLIB, or WITHLIBC. */ 8050397Sobrien int *args; 8150397Sobrien 8252284Sobrien /* By default, we throw on the math library if we have one. */ 8352284Sobrien int need_math = (MATH_LIBRARY[0] != '\0'); 8450397Sobrien 8590075Sobrien /* True if we should add -shared-libgcc to the command-line. */ 8690075Sobrien int shared_libgcc = 1; 8790075Sobrien 8850397Sobrien /* The total number of arguments with the new stuff. */ 8950397Sobrien int argc; 9050397Sobrien 9150397Sobrien /* The argument list. */ 9290075Sobrien const char *const *argv; 9350397Sobrien 9450397Sobrien /* The number of libraries added in. */ 9550397Sobrien int added_libraries; 9650397Sobrien 9750397Sobrien /* The total number of arguments with the new stuff. */ 9850397Sobrien int num_args = 1; 9950397Sobrien 10050397Sobrien argc = *in_argc; 10150397Sobrien argv = *in_argv; 10250397Sobrien added_libraries = *in_added_libraries; 10350397Sobrien 10490075Sobrien args = (int *) xcalloc (argc, sizeof (int)); 10550397Sobrien 10650397Sobrien for (i = 1; i < argc; i++) 10750397Sobrien { 10850397Sobrien /* If the previous option took an argument, we swallow it here. */ 10950397Sobrien if (quote) 11050397Sobrien { 11150397Sobrien quote = NULL; 11250397Sobrien continue; 11350397Sobrien } 11450397Sobrien 11550397Sobrien /* We don't do this anymore, since we don't get them with minus 11650397Sobrien signs on them. */ 11750397Sobrien if (argv[i][0] == '\0' || argv[i][1] == '\0') 11850397Sobrien continue; 11950397Sobrien 12050397Sobrien if (argv[i][0] == '-') 12150397Sobrien { 12250397Sobrien if (library != 0 && (strcmp (argv[i], "-nostdlib") == 0 12350397Sobrien || strcmp (argv[i], "-nodefaultlibs") == 0)) 12450397Sobrien { 12550397Sobrien library = 0; 12650397Sobrien } 12750397Sobrien else if (strcmp (argv[i], "-lm") == 0 12850397Sobrien || strcmp (argv[i], "-lmath") == 0 12952284Sobrien || strcmp (argv[i], MATH_LIBRARY) == 0 13050397Sobrien#ifdef ALT_LIBM 13150397Sobrien || strcmp (argv[i], ALT_LIBM) == 0 13250397Sobrien#endif 13350397Sobrien ) 13450397Sobrien { 13550397Sobrien args[i] |= MATHLIB; 13650397Sobrien need_math = 0; 13750397Sobrien } 13850397Sobrien else if (strcmp (argv[i], "-lc") == 0) 13950397Sobrien args[i] |= WITHLIBC; 14050397Sobrien else if (strcmp (argv[i], "-v") == 0) 14150397Sobrien { 14250397Sobrien saw_verbose_flag = 1; 14350397Sobrien if (argc == 2) 14450397Sobrien { 14550397Sobrien /* If they only gave us `-v', don't try to link 14650397Sobrien in libg++. */ 14750397Sobrien library = 0; 14850397Sobrien } 14950397Sobrien } 15050397Sobrien else if (strncmp (argv[i], "-x", 2) == 0) 15150397Sobrien saw_speclang = 1; 15250397Sobrien else if (((argv[i][2] == '\0' 15350397Sobrien && (char *)strchr ("bBVDUoeTuIYmLiA", argv[i][1]) != NULL) 15490075Sobrien || strcmp (argv[i], "-Xlinker") == 0 15550397Sobrien || strcmp (argv[i], "-Tdata") == 0)) 15650397Sobrien quote = argv[i]; 15750397Sobrien else if (library != 0 && ((argv[i][2] == '\0' 15850397Sobrien && (char *) strchr ("cSEM", argv[i][1]) != NULL) 15990075Sobrien || strcmp (argv[i], "-MM") == 0 16090075Sobrien || strcmp (argv[i], "-fsyntax-only") == 0)) 16150397Sobrien { 16250397Sobrien /* Don't specify libraries if we won't link, since that would 16350397Sobrien cause a warning. */ 16450397Sobrien library = 0; 16550397Sobrien added -= 2; 16650397Sobrien } 16790075Sobrien else if (strcmp (argv[i], "-static-libgcc") == 0 16890075Sobrien || strcmp (argv[i], "-static") == 0) 16990075Sobrien shared_libgcc = 0; 17050397Sobrien else 17150397Sobrien /* Pass other options through. */ 17250397Sobrien continue; 17350397Sobrien } 17450397Sobrien else 17550397Sobrien { 17650397Sobrien int len; 17750397Sobrien 17850397Sobrien if (saw_speclang) 17950397Sobrien { 18050397Sobrien saw_speclang = 0; 18150397Sobrien continue; 18250397Sobrien } 18350397Sobrien 18450397Sobrien /* If the filename ends in .c or .i, put options around it. 18550397Sobrien But not if a specified -x option is currently active. */ 18650397Sobrien len = strlen (argv[i]); 18750397Sobrien if (len > 2 18850397Sobrien && (argv[i][len - 1] == 'c' || argv[i][len - 1] == 'i') 18950397Sobrien && argv[i][len - 2] == '.') 19050397Sobrien { 19150397Sobrien args[i] |= LANGSPEC; 19250397Sobrien added += 2; 19350397Sobrien } 19450397Sobrien } 19550397Sobrien } 19650397Sobrien 19750397Sobrien if (quote) 19890075Sobrien fatal ("argument to `%s' missing\n", quote); 19950397Sobrien 20050397Sobrien /* If we know we don't have to do anything, bail now. */ 20150397Sobrien if (! added && ! library) 20250397Sobrien { 20350397Sobrien free (args); 20450397Sobrien return; 20550397Sobrien } 20650397Sobrien 20790075Sobrien /* There's no point adding -shared-libgcc if we don't have a shared 20890075Sobrien libgcc. */ 20990075Sobrien#ifndef ENABLE_SHARED_LIBGCC 21090075Sobrien shared_libgcc = 0; 21190075Sobrien#endif 21250397Sobrien 21390075Sobrien /* Make sure to have room for the trailing NULL argument. */ 21490075Sobrien num_args = argc + added + need_math + shared_libgcc + 1; 21590075Sobrien arglist = (const char **) xmalloc (num_args * sizeof (char *)); 21690075Sobrien 21790075Sobrien i = 0; 21890075Sobrien j = 0; 21990075Sobrien 22090075Sobrien /* Copy the 0th argument, i.e., the name of the program itself. */ 22190075Sobrien arglist[i++] = argv[j++]; 22290075Sobrien 22350397Sobrien /* NOTE: We start at 1 now, not 0. */ 22490075Sobrien while (i < argc) 22550397Sobrien { 22650397Sobrien arglist[j] = argv[i]; 22750397Sobrien 22850397Sobrien /* Make sure -lstdc++ is before the math library, since libstdc++ 22950397Sobrien itself uses those math routines. */ 23050397Sobrien if (!saw_math && (args[i] & MATHLIB) && library) 23150397Sobrien { 23250397Sobrien --j; 23350397Sobrien saw_math = argv[i]; 23450397Sobrien } 23550397Sobrien 23650397Sobrien if (!saw_libc && (args[i] & WITHLIBC) && library) 23750397Sobrien { 23850397Sobrien --j; 23950397Sobrien saw_libc = argv[i]; 24050397Sobrien } 24150397Sobrien 24250397Sobrien /* Wrap foo.c and foo.i files in a language specification to 24350397Sobrien force the gcc compiler driver to run cc1plus on them. */ 24450397Sobrien if (args[i] & LANGSPEC) 24550397Sobrien { 24650397Sobrien int len = strlen (argv[i]); 24750397Sobrien if (argv[i][len - 1] == 'i') 24850397Sobrien arglist[j++] = "-xc++-cpp-output"; 24950397Sobrien else 25050397Sobrien arglist[j++] = "-xc++"; 25150397Sobrien arglist[j++] = argv[i]; 25250397Sobrien arglist[j] = "-xnone"; 25350397Sobrien } 25450397Sobrien 25590075Sobrien i++; 25690075Sobrien j++; 25790075Sobrien } 25890075Sobrien 25950397Sobrien /* Add `-lstdc++' if we haven't already done so. */ 26050397Sobrien if (library) 26150397Sobrien { 26252284Sobrien arglist[j++] = LIBSTDCXX; 26350397Sobrien added_libraries++; 26450397Sobrien } 26550397Sobrien if (saw_math) 26650397Sobrien arglist[j++] = saw_math; 26750397Sobrien else if (library && need_math) 26850397Sobrien { 26950397Sobrien arglist[j++] = MATH_LIBRARY; 27050397Sobrien added_libraries++; 27150397Sobrien } 27250397Sobrien if (saw_libc) 27350397Sobrien arglist[j++] = saw_libc; 27490075Sobrien if (shared_libgcc) 27590075Sobrien arglist[j++] = "-shared-libgcc"; 27650397Sobrien 27750397Sobrien arglist[j] = NULL; 27850397Sobrien 27950397Sobrien *in_argc = j; 28050397Sobrien *in_argv = arglist; 28150397Sobrien *in_added_libraries = added_libraries; 28250397Sobrien} 28350397Sobrien 28450397Sobrien/* Called before linking. Returns 0 on success and -1 on failure. */ 28550397Sobrienint lang_specific_pre_link () /* Not used for C++. */ 28650397Sobrien{ 28750397Sobrien return 0; 28850397Sobrien} 28950397Sobrien 29050397Sobrien/* Number of extra output files that lang_specific_pre_link may generate. */ 29150397Sobrienint lang_specific_extra_outfiles = 0; /* Not used for C++. */ 292