changeset 18:eaf7a8d5e697

Managed to get a working toolchain, with wrapper script, to build a hello world program. There's probably a typo here somewhere, but the basics are there.
author Rob Landley <rob@landley.net>
date Mon, 04 Dec 2006 20:30:51 -0500
parents 1202bdb44025
children b5ffd82d9ae5
files build.sh sources/toys/gcc-uClibc.c
diffstat 2 files changed, 93 insertions(+), 80 deletions(-) [+]
line wrap: on
line diff
--- a/build.sh	Mon Dec 04 18:25:14 2006 -0500
+++ b/build.sh	Mon Dec 04 20:30:51 2006 -0500
@@ -96,11 +96,15 @@
 
 export STAGE=build-cross
 
+# Install the linux kernel headers.
+
 setupfor linux
 make headers_install ARCH="${KARCH}" INSTALL_HDR_PATH="${CROSS}"
 
 [ $? -ne 0 ] && dienow
 
+# Build and install binutils
+
 setupfor binutils build-binutils
 "${CURSRC}/configure" --prefix="${CROSS}" --host=${CROSS_HOST} \
 	--target=${CROSS_TARGET} --with-lib-path=lib --disable-nls \
@@ -114,6 +118,8 @@
 
 [ $? -ne 0 ] && dienow
 
+# Build and install gcc
+
 setupfor gcc-core build-gcc gcc-
 "${CURSRC}/configure" --prefix="${CROSS}" --host=${CROSS_HOST} \
 	--target=${CROSS_TARGET} \
@@ -125,10 +131,18 @@
 make all-gcc &&
 make install-gcc &&
 cd .. &&
-$CLEANUP "${CURSRC}" build-gcc
+
+# Move the gcc internal libraries and headers somewhere sane.
+
+mkdir -p "${CROSS}"gcc &&
+mv "${CROSS}"lib/gcc/*/*/include "${CROSS}"gcc/include &&
+mv "${CROSS}"lib/gcc/*/* "${CROSS}"gcc/lib &&
+$CLEANUP "${CURSRC}" build-gcc "${CROSS}"lib/gcc "${CROSS}"gcc/lib/install-tools
 
 [ $? -ne 0 ] && dienow
 
+# Build and install uClibc
+
 setupfor uClibc
 make TARGET_ARCH=${KARCH} CROSS=${CROSS_TARGET}- defconfig &&
 make TARGET_ARCH=${KARCH} CROSS=${CROSS_TARGET}- KERNEL_SOURCE="${CROSS}" &&
@@ -142,13 +156,36 @@
 cd .. &&
 $CLEANUP uClibc-*
 
-GCCNAME="$(echo "$CROSS"/bin/*-gcc)"
-# Convert above path into just the name at the end, plus -unwrapped, and
-# surrounded by double quotes.
-GCCMANGLED='"'"$(echo $NAME | sed -e 's@.*/@@')"'-unwrapped"' 
-[ ! -f "$NAME"-unwrapped ] && cp "$GCCNAME" "$GCCNAME"-unwrapped
+[ $? -ne 0 ] && dienow
+
+# Build and install gcc wrapper script.
+
+mkdir -p "${CROSS}"gcc
+mv "${CROSS}"lib/gcc/*/*/include "${CROSS}"gcc/include
+mv "${CROSS}"lib/gcc/*/* "${CROSS}"gcc/lib
+$CLEANUP -rf "${CROSS}"lib/gcc "${CROSS}"gcc/lib/install-tools
+GCCNAME="$(echo "${CROSS}"bin/*-gcc)" &&
+mv "$GCCNAME" "${CROSS}"bin/gcc-unwrapped &&
+gcc sources/toys/gcc-uClibc.c -Os -s -o "$GCCNAME" &&
+
+# A quick hello world program to test the cross-compiler out.
 
-gcc sources/toys/gcc-uClibc.c -DGCC_BIN="$GCCMANGLED" -DDYNAMIC_LINKER='"/lib/ld-uClibc.so.0"' -DEXTRAGCCFLAGS=0 -Os -s -o "$GCCNAME"
+cat > "$WORK"/hello.c << 'EOF' &&
+#include <stdio.h>
 
+int main(int argc, char *argv[])
+{
+  printf("Hello world!\n");
+  return 0;
+}
+EOF
+
+# Build something dynamic, then static, to verify header/library paths.
+
+"$GCCNAME" -Os "$WORK"/hello.c -o "$WORK"/hello &&
+"$GCCNAME" -Os -static "$WORK"/hello.c -o "$WORK"/hello
+[ x`qemu-${KARCH} hello` == x"Hello world!" ] &&
+echo Cross-toolchain seems to work.
 
 [ $? -ne 0 ] && dienow
+
--- a/sources/toys/gcc-uClibc.c	Mon Dec 04 18:25:14 2006 -0500
+++ b/sources/toys/gcc-uClibc.c	Mon Dec 04 20:30:51 2006 -0500
@@ -80,23 +80,6 @@
 	return NULL;
 }
 
-void xstrcat(char **string, ...)
-{
-	const char *c;
-	va_list p; 
-	/* Don't bother to calculate how big exerything 
-	 * will be, just be careful to not overflow...  */
-	va_start(p, string);
-	*string = malloc(BUFSIZ);
-	**string = '\0';
-	while(1) {
-		if (!(c = va_arg(p, const char *)))
-			break;
-		strcat(*string, c); 
-	}
-	va_end(p);
-}
-
 int main(int argc, char **argv)
 {
 	int use_build_dir = 0, linking = 1, use_static_linking = 0;
@@ -147,7 +130,7 @@
 	// What's the name of the C compiler we're wrapping?  (It may have a
 	// cross-prefix.)
 	cc = getenv("UCLIBC_CC");
-	if (!cc) cc = GCC_BIN;
+	if (!cc) cc = "gcc-unwrapped";
 
 	
 	// Check end of name, since there could be a cross-prefix on the thing
@@ -185,30 +168,25 @@
 	}
 
 
-	xstrcat(&(rpath_link[0]), "-Wl,-rpath-link,", devprefix, "/lib", NULL);
-
-	xstrcat(&(rpath[0]), "-Wl,-rpath,", devprefix, "/lib", NULL);
-
-	xstrcat(&(uClibc_inc[0]), devprefix, "/include/", NULL);
+	asprintf(rpath_link,"-Wl,-rpath-link,%s/lib", devprefix);
+	asprintf(rpath, "-Wl,-rpath,%s/lib", devprefix);
+	asprintf(uClibc_inc, "%s/include/", devprefix);
 
 //#ifdef CTOR_DTOR
-	xstrcat(&(crt0_path[0]), devprefix, "/lib/crt1.o", NULL);
-	xstrcat(&(crti_path[0]), devprefix, "/lib/crti.o", NULL);
-	xstrcat(&(crtn_path[0]), devprefix, "/lib/crtn.o", NULL);
+    asprintf(crt0_path, "%s/lib/crt1.o", devprefix);
+	asprintf(crti_path, "%s/lib/crti.o", devprefix);
+	asprintf(crtn_path, "%s/lib/crtn.o", devprefix);
 //#else
-//	xstrcat(&(crt0_path[0]), devprefix, "/lib/crt0.o", NULL);
+//	*crt0_path = asprintf("%s/lib/crt0.o", devprefix);
 //#endif
 
 	// profiling
-	xstrcat(&(gcrt1_path[0]), devprefix, "/lib/gcrt1.o", NULL);
-
-	xstrcat(&(our_lib_path[0]), "-L", devprefix, "/lib", NULL);
+	asprintf(gcrt1_path, "%s/lib/gcrt1.o", devprefix, "/lib/gcrt1.o");
+	asprintf(our_lib_path, "-L%s/lib", devprefix);
 
 	// Figure out where the dynamic linker is.
 	dlstr = getenv("UCLIBC_GCC_DLOPT");
-	if (!dlstr) {
-		dlstr = "-Wl,--dynamic-linker," DYNAMIC_LINKER;
-	}
+	if (!dlstr) dlstr = "-Wl,--dynamic-linker,/lib/ld-uClibc.so.0";
 
 	m = 0;
 	libraries = __builtin_alloca(sizeof(char*) * (argc));
@@ -218,6 +196,8 @@
 	libpath = __builtin_alloca(sizeof(char*) * (argc));
 	libpath[n] = '\0';
 
+	// Parse the incoming gcc arguments.
+
 	for ( i = 1 ; i < argc ; i++ ) {
 		if (argv[i][0] == '-' && argv[i][1]) { /* option */
 			switch (argv[i][1]) {
@@ -226,12 +206,11 @@
 				case 'E':		/* preprocess only */
 				case 'M':	    /* generate dependencies */
 					linking = 0;
-					if (argv[i][1] == 'M')
-						  sawM = 1;
-					else
-						  sawcES = 1;
+					if (argv[i][1] == 'M') sawM = 1;
+					else sawcES = 1;
 					break;
-				case 'L': 		/* library */
+
+				case 'L': 		/* library path */
 					libpath[n++] = argv[i];
 					libpath[n] = '\0';
 					if (argv[i][2] == 0) {
@@ -241,16 +220,19 @@
 					}
 					argv[i] = '\0';
 					break;
+
 				case 'l': 		/* library */
 					libraries[m++] = argv[i];
 					libraries[m] = '\0';
 					argv[i] = '\0';
 					break;
+
 				case 'v':		/* verbose */
 					if (argv[i][2] == 0) verbose = 1;
 					printf("Invoked as %s\n", argv[0]);
 					printf("Reference path: %s\n", topdir);
 					break;
+
 				case 'n':
 					if (strcmp(nostdinc,argv[i]) == 0) {
 						use_stdinc = 0;
@@ -270,6 +252,7 @@
 						}
 					}
 					break;
+
 				case 's':
 					if (strstr(argv[i],static_linking) != NULL) {
 						use_static_linking = 1;
@@ -279,6 +262,7 @@
 						use_pic = 1;
 					}
 					break;
+
 				case 'W':		/* -static could be passed directly to ld */
 					if (strncmp("-Wl,",argv[i],4) == 0) {
 						if (strstr(argv[i],static_linking) != 0) {
@@ -293,10 +277,9 @@
 				// Profiling.
 
 				case 'p':
-					if (strcmp("-pg",argv[i]) == 0) {
-						profile = 1;
-					}
+					if (!strcmp("-pg",argv[i]) == 0) profile = 1;
 					break;
+
 				case 'f':
 					/* Check if we are doing PIC */
 					if (strcmp("-fPIC",argv[i]) == 0) {
@@ -339,31 +322,25 @@
 			}
 		} else {				/* assume it is an existing source file */
 			char *p = strchr (argv[i], '\0') - 2;
-			if (p > argv[i] && sawM && (strcmp (p, ".o") == 0 || strcmp (p, ".a") == 0))
+			if (p > argv[i] && sawM && (!strcmp(p, ".o") || !strcmp(p, ".a")))
 				  sawdotoa = 1;
 			++source_count;
 		}
 	}
 
-	if (sawdotoa && sawM && !sawcES)
-		  linking = 1;
-
 	gcc_argv = __builtin_alloca(sizeof(char*) * (argc + 128));
 
 	i = 0;
 	if (ctor_dtor) {
-		xstrcat(&(crtbegin_path[0]), devprefix, "/lib/crtbegin.o", NULL);
-		xstrcat(&(crtbegin_path[1]), devprefix, "/lib/crtbeginS.o", NULL);
-		xstrcat(&(crtend_path[0]), devprefix, "/lib/crtend.o", NULL);
-		xstrcat(&(crtend_path[1]), devprefix, "/lib/crtendS.o", NULL);
+		asprintf(crtbegin_path, "%s/gcc/lib/crtbegin.o", devprefix);
+		asprintf(crtbegin_path+1, "%s/gcc/lib/crtbeginS.o", devprefix);
+		asprintf(crtend_path, "%s/gcc/lib/crtend.o", devprefix);
+		asprintf(crtend_path+1, "%s/gcc/lib/crtendS.o", devprefix);
 	}
 
 	gcc_argv[i++] = cpp ? cpp : cc;
 
-	if (EXTRAGCCFLAGS) gcc_argv[i++] = EXTRAGCCFLAGS;
-
-	if (cplusplus)
-		gcc_argv[i++] = "-fno-use-cxa-atexit";
+	if (cplusplus) gcc_argv[i++] = "-fno-use-cxa-atexit";
 
 	if (linking && source_count) {
 //#if defined HAS_ELF && ! defined HAS_MMU
@@ -389,35 +366,31 @@
 		if( libstr )
 			gcc_argv[i++] = libstr;
 		gcc_argv[i++] = our_lib_path[use_build_dir];
-		if (!use_build_dir) {
-			xstrcat(&(gcc_argv[i++]), "-L", devprefix, "/lib", NULL);
-		}
+		if (!use_build_dir) asprintf(gcc_argv+(i++), "-L%s/gcc/lib", devprefix);
 	}
 	if (use_stdinc && source_count) {
 		gcc_argv[i++] = nostdinc;
 
 		if (cplusplus) {
-			char *cppinc;
 			if (use_nostdinc_plus) {
 				gcc_argv[i++] = nostdinc_plus;
 			}
-			xstrcat(&cppinc, uClibc_inc[use_build_dir], "c++/4.1.1", NULL);
 			gcc_argv[i++] = "-isystem";
-			gcc_argv[i++] = cppinc;
-			xstrcat(&cppinc, uClibc_inc[use_build_dir], "c++/4.1.1/" TARGET_DIR, NULL);
-			gcc_argv[i++] = "-isystem";
-			gcc_argv[i++] = cppinc;
-			xstrcat(&cppinc, uClibc_inc[use_build_dir], "c++/4.1.1", NULL);
-			gcc_argv[i++] = "-isystem";
-			gcc_argv[i++] = cppinc;
+			asprintf(gcc_argv+(i++), "%sc++/4.1.1", uClibc_inc[use_build_dir]);
+			//char *cppinc;
+			//xstrcat(&cppinc, uClibc_inc[use_build_dir], "c++/4.1.1/" TARGET_DIR, NULL);
+			//gcc_argv[i++] = "-isystem";
+			//gcc_argv[i++] = cppinc;
+			//xstrcat(&cppinc, uClibc_inc[use_build_dir], "c++/4.1.1", NULL);
+			//gcc_argv[i++] = "-isystem";
+			//gcc_argv[i++] = cppinc;
 		}
 
 		gcc_argv[i++] = "-isystem";
 		gcc_argv[i++] = uClibc_inc[use_build_dir];
-//		gcc_argv[i++] = "-iwithprefix";
-//		gcc_argv[i++] = "include";
-		if( incstr )
-			gcc_argv[i++] = incstr;
+		gcc_argv[i++] = "-isystem";
+		asprintf(gcc_argv+(i++), "%s/gcc/include", devprefix);
+		if(incstr) gcc_argv[i++] = incstr;
 	}
 
     gcc_argv[i++] = "-U__nptl__";
@@ -448,7 +421,7 @@
 		if (use_stdlib) {
 			//gcc_argv[i++] = "-Wl,--start-group";
 			gcc_argv[i++] = "-lgcc";
-			gcc_argv[i++] = "-lgcc_eh";
+//			gcc_argv[i++] = "-lgcc_eh";
 		}
 		for ( l = 0 ; l < m ; l++ ) {
 			if (libraries[l]) gcc_argv[i++] = libraries[l];
@@ -460,7 +433,7 @@
 			}
 			gcc_argv[i++] = "-lc";
 			gcc_argv[i++] = "-lgcc";
-			gcc_argv[i++] = "-lgcc_eh";
+//			gcc_argv[i++] = "-lgcc_eh";
 			//gcc_argv[i++] = "-Wl,--end-group";
 		}
 		if (ctor_dtor) {
@@ -485,8 +458,11 @@
 
 	//no need to free memory from xstrcat because we never return... 
 //for(l=0;gcc_argv[l];l++) dprintf(2,"gcc_argv[%d]=%s\n",l,gcc_argv[l]);
-//for(l=0;gcc_argv[l];l++) dprintf(2,"%s ",gcc_argv[l]);
-//dprintf(2,"\n");
+	if (verbose) {
+		for(l=0; gcc_argv[l]; l++)
+			fprintf(stderr, "%s ",gcc_argv[l]);
+		fprintf(stderr, "\n");
+	}
 	execvp(gcc_argv[0], gcc_argv);
 	fprintf(stderr, "%s: %s\n", cpp ? cpp : cc, strerror(errno));
 	exit(EXIT_FAILURE);