Mercurial > hg > aboriginal
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);