diff options
| -rw-r--r-- | extra/gcc-uClibc/gcc-uClibc.c | 77 | 
1 files changed, 48 insertions, 29 deletions
diff --git a/extra/gcc-uClibc/gcc-uClibc.c b/extra/gcc-uClibc/gcc-uClibc.c index c2971f3af..e6c57c6c9 100644 --- a/extra/gcc-uClibc/gcc-uClibc.c +++ b/extra/gcc-uClibc/gcc-uClibc.c @@ -1,7 +1,7 @@  /* vi: set sw=4 ts=4: */  /*   * Copyright (C) 2000 Manuel Novoa III - * Copyright (C) 2002 Erik Andersen + * Copyright (C) 2002-2003 Erik Andersen   *   * This is a crude wrapper to use uClibc with gcc.   * It was originally written to work around ./configure for ext2fs-utils. @@ -76,6 +76,7 @@  #include <stdarg.h>  #include <string.h>  #include <unistd.h> +#include <errno.h>  #include <sys/stat.h>  #include <sys/wait.h> @@ -203,17 +204,23 @@ int main(int argc, char **argv)  	char *crtn_path[2];  	int len;  	int ctor_dtor = 1, cplusplus = 0, use_nostdinc_plus = 0; -	char *GPLUSPLUS_BIN = NULL; +	int findlibgcc = 1; +	char *cpp = NULL;  #endif  #ifdef __UCLIBC_PROFILING__  	int profile = 0;  	char *gcrt1_path[2];  #endif +#ifdef __UCLIBC_CTOR_DTOR__  	cc     = getenv("UCLIBC_CC"); -	if (!cc) { +	if (cc==NULL) {  		cc = GCC_BIN; +		findlibgcc = 0;  	} +#else +	cc = GCC_BIN; +#endif  	application_name = basename(argv[0]);  	if (application_name[0] == '-') @@ -230,9 +237,9 @@ int main(int argc, char **argv)  			(strcmp(application_name+len-3, "c++")==0)) {  		len = strlen(cc);  		if (strcmp(cc+len-3, "gcc")==0) { -			GPLUSPLUS_BIN = strdup(cc); -			GPLUSPLUS_BIN[len-1]='+'; -			GPLUSPLUS_BIN[len-2]='+'; +			cpp = strdup(cc); +			cpp[len-1]='+'; +			cpp[len-2]='+';  		}  		cplusplus = 1;  		use_nostdinc_plus = 1; @@ -435,10 +442,11 @@ int main(int argc, char **argv)  #ifdef __UCLIBC_CTOR_DTOR__  	if (ctor_dtor) {  		struct stat statbuf; -		if (stat(LIBGCC_DIR, &statbuf)!=0 ||  +		if (findlibgcc==1 || stat(LIBGCC_DIR, &statbuf)!=0 ||   				!S_ISDIR(statbuf.st_mode))  		{ -			/* Bummer, gcc has moved things on us... */ +			/* Bummer, gcc is hiding from us. This is going +			 * to really slow things down... bummer.  */  			int status, gcc_pipe[2];  			pid_t pid, wpid; @@ -450,35 +458,41 @@ int main(int argc, char **argv)  				close(2);  				dup2(gcc_pipe[1], 1);  				dup2(gcc_pipe[1], 2); -				argv[0] = cc;  -				argv[2] = "-print-libgcc-file-name"; -				argv[3] = NULL; -				execvp(argv[0], argv); +				argv[0] = cc; +				argv[1] = "-print-libgcc-file-name"; +				argv[2] = NULL; +				execvp(cc, argv);  				close(gcc_pipe[1]); -				_exit(-1); +				_exit(EXIT_FAILURE);  			}  			wpid=0;  			while (wpid != pid) {  				wpid = wait(&status);  			}  			close(gcc_pipe[1]); -			if (WIFEXITED(status)) { +			if (WIFEXITED(status) && WEXITSTATUS(status)) { +crash_n_burn: +				fprintf(stderr, "Unable to locale crtbegin.o provided by gcc"); +				exit(EXIT_FAILURE); +			} +			if (WIFSIGNALED(status)) { +				fprintf(stderr, "%s exited because of uncaught signal %d", cc, WTERMSIG(status)); +				exit(EXIT_FAILURE); +			} + +			{  				char buf[1024], *dir;  				status = read(gcc_pipe[0], buf, sizeof(buf)); +				close(gcc_pipe[0]);  				if (status < 0) {  					goto crash_n_burn;  				}  				dir = dirname(buf); -				xstrcat(&(crtbegin_path[0]), dir, "crtbegin.o", NULL); -				xstrcat(&(crtbegin_path[1]), dir, "crtbeginS.o", NULL); -				xstrcat(&(crtend_path[0]), dir, "crtend.o", NULL); -				xstrcat(&(crtend_path[1]), dir, "crtendS.o", NULL); -			} else { -crash_n_burn: -				fprintf(stderr, "Unable to locale crtbegin.o provided by gcc"); -				exit(EXIT_FAILURE); +				xstrcat(&(crtbegin_path[0]), dir, "/crtbegin.o", NULL); +				xstrcat(&(crtbegin_path[1]), dir, "/crtbeginS.o", NULL); +				xstrcat(&(crtend_path[0]), dir, "/crtend.o", NULL); +				xstrcat(&(crtend_path[1]), dir, "/crtendS.o", NULL);  			} -			close(gcc_pipe[0]);  		} else {  			xstrcat(&(crtbegin_path[0]), LIBGCC_DIR, "crtbegin.o", NULL); @@ -488,8 +502,8 @@ crash_n_burn:  		}  	} -	if (cplusplus && GPLUSPLUS_BIN) -		gcc_argv[i++] = GPLUSPLUS_BIN; +	if (cplusplus && cpp) +		gcc_argv[i++] = cpp;  	else  #endif  		gcc_argv[i++] = cc; @@ -628,9 +642,14 @@ crash_n_burn:  	}  	//no need to free memory from xstrcat because we never return...   #ifdef __UCLIBC_CTOR_DTOR__ -	if (cplusplus && GPLUSPLUS_BIN) -		return execvp(GPLUSPLUS_BIN, gcc_argv); -	else +	if (cplusplus && cpp) { +		execvp(cpp, gcc_argv); +		fprintf(stderr, "%s: %s\n", cpp, strerror(errno)); +	} else  #endif -		return execvp(cc, gcc_argv); +	{ +		execvp(cc, gcc_argv); +		fprintf(stderr, "%s: %s\n", cc, strerror(errno)); +	} +	exit(EXIT_FAILURE);  }  | 
