views:

3057

answers:

9

A similiar (less descriptive) post is here.

I'm trying to roll my own tool chain using recent releases on Ubuntu and was hoping there was enough of a Linux community here that I could get specific advice on certain problems as they come up.

With everyone's help I'd like to see this turn into a useful reference eventually.

First off "Crosstool" to which nearly everyone refers is a little (2006) out of date and "Crosstool-NG" which seems to now be carrying the torch fails on my machine. I'd rather debug the process itself than a script (which it would seem requires me to understand the process).

Below are basic steps of what I've got working so far; at present I'm stuck trying to compile the first pass GCC.

Where it's failing ...

It's failing because the cross compiled library containing "crti.o" is missing:

# ./gcc-4.4.1/configure --target=arm-linux --disable-thread --enable-langauges=c 
/bin/bash ../../../gcc-4.4.1/libgcc/../mkinstalldirs .
/usr/src/gnu-4.4.1-build/./gcc/xgcc -B ........
/usr/local/arm-linux/bin/ld: crti.o No such file: No such file or directory
collect2: ld returned 1 exit status
make[2]: *** [libgcc_s.so] Error 1
make[2]: Leaving directory `/usr/src/gnu/gcc-4.4.1-build/arm-linux/libgcc'
make[1]: *** [all-target-libgcc] Error 2
make[1]: Leaving directory `/usr/src/gnu/gcc-4.4.1-build'
make: *** [all] Error 2

Build steps

On a 'freshly' configured Ubuntu 9.04 installation, here are the steps I've done so far:

#New configuration of Ubuntu 9.04
sudo updatedb
sudo apt-get install build-essential subversion
# For kernel configuration
sudo apt-get install libncurses5-dev
# For building GCC
sudo apt-get install libgmp3-dev libmpfr-dev

#Get Linux Headers for GCC/GLIBC compilations
# I use a hacked Linux from Artilla, 
pushd ~ && svn co http://.../linux m501-linux && cd !$
make ARCH=arm m501_defconfig
make ARCH=arm menuconfig
sudo mkdir /usr/local/arm-linux/include
sudo cp -dR include/asm-arm /usr/local/arm-linux/include/asm
sudo cp -dR include/linux /usr/local/arm-linux/include/linux
cd /usr/local/arm-linux/
sudo ln -s include sys-include
popd

#Get sources:
cd /usr/src/
sudo su root
mkdir gnu
ftp ftp.gnu.org
# get gnu/binutils/binutils-2.19.1.tar.bz2
# get gnu/gcc/gcc-4.4.1/gcc-4.4.1.tar.bz2
# get gnu/glibc/glibc-2.10.1.tar.bz2
# get gnu/gdb/gdb-6.8.tar.bz2

#Build Binutils
bzcat binutils-2.19.1.tar.bz2 | tar -xv
mkdir binutils-2.19.1-build && cd !$
cp ../binutils-2.19.1/gas/config/tc-arm.c ./tc-arm.c 
sed -r 's/(as_bad[ \t]*\()(.+\[.+\]\))/\1\"%s\",\2/' < ./tc-arm.c > ../binutils-2.19.1/gas/config/tc-arm.c 
rm ./tc-arm.c    
../binutils-2.19.1/configure --target=arm-linux
make && make install && cd ..

#Build GCC
bzcat gcc-4.4.1.tar.bz2 | tar -xv
mkdir gcc-4.4.1-build && cd !$
../gcc-4.4.1/configure --target=arm-linux --disable-thread --enable-langauges=c -with-headers=/usr/local/arm-linux/include
make
+1  A: 

If you're really want to build entire toolchain for yourself:
http://frank.harvard.edu/~coldwell/toolchain/
http://ftp.snapgear.org/pub/snapgear/tools/arm-linux/build-arm-linux-3.4.4
Take in mind, though, as you should search for toolchain compatibilty matrix or you may run into weird compilation errors.

If you still have the option for crosstool-ng, this is what I'm was working on for last few days:
http://blog.stranadurakov.com/2009/08/04/how-to-arm-linux/
Here you will find my crosstool-ng configuration file, which had worked for me.

Andrejs Cainikovs
+1  A: 

Here is the HelenOS arm-32 toolchain installation script, this should do what you want with very little fiddling. I'm using it on Ubuntu now (I'm one of the HelenOS developers). It was written by Martin Decky:

#!/bin/bash

# Cross-Compiler Toolchain for ${PLATFORM}
#  by Martin Decky <[email protected]>
#
#  GPL'ed, copyleft
#


check_error() {
    if [ "$1" -ne "0" ]; then
        echo
        echo "Script failed: $2"
        exit
    fi
}

if [ -z "${CROSS_PREFIX}" ] ; then
    CROSS_PREFIX="/usr/local"
fi

BINUTILS_VERSION="2.19.1"
GCC_VERSION="4.3.3"

BINUTILS="binutils-${BINUTILS_VERSION}.tar.gz"
GCC_CORE="gcc-core-${GCC_VERSION}.tar.bz2"
GCC_OBJC="gcc-objc-${GCC_VERSION}.tar.bz2"
GCC_CPP="gcc-g++-${GCC_VERSION}.tar.bz2"

BINUTILS_SOURCE="ftp://ftp.gnu.org/gnu/binutils/"
GCC_SOURCE="ftp://ftp.gnu.org/gnu/gcc/gcc-${GCC_VERSION}/"

PLATFORM="arm"
WORKDIR=`pwd`
TARGET="${PLATFORM}-linux-gnu"
PREFIX="${CROSS_PREFIX}/${PLATFORM}"
BINUTILSDIR="${WORKDIR}/binutils-${BINUTILS_VERSION}"
GCCDIR="${WORKDIR}/gcc-${GCC_VERSION}"
OBJDIR="${WORKDIR}/gcc-obj"

echo ">>> Downloading tarballs"

if [ ! -f "${BINUTILS}" ]; then
    wget -c "${BINUTILS_SOURCE}${BINUTILS}"
    check_error $? "Error downloading binutils."
fi
if [ ! -f "${GCC_CORE}" ]; then
    wget -c "${GCC_SOURCE}${GCC_CORE}"
    check_error $? "Error downloading GCC Core."
fi
if [ ! -f "${GCC_OBJC}" ]; then
    wget -c "${GCC_SOURCE}${GCC_OBJC}"
    check_error $? "Error downloading GCC Objective C."
fi
if [ ! -f "${GCC_CPP}" ]; then
    wget -c "${GCC_SOURCE}${GCC_CPP}"
    check_error $? "Error downloading GCC C++."
fi

echo ">>> Creating destionation directory"
if [ ! -d "${PREFIX}" ]; then
    mkdir -p "${PREFIX}"
    test -d "${PREFIX}"
    check_error $? "Unable to create ${PREFIX}."
fi

echo ">>> Creating GCC work directory"
if [ ! -d "${OBJDIR}" ]; then
    mkdir -p "${OBJDIR}"
    test -d "${OBJDIR}"
    check_error $? "Unable to create ${OBJDIR}."
fi

echo ">>> Unpacking tarballs"
tar -xvzf "${BINUTILS}"
check_error $? "Error unpacking binutils."
tar -xvjf "${GCC_CORE}"
check_error $? "Error unpacking GCC Core."
tar -xvjf "${GCC_OBJC}"
check_error $? "Error unpacking GCC Objective C."
tar -xvjf "${GCC_CPP}"
check_error $? "Error unpacking GCC C++."

echo ">>> Compiling and installing binutils"
cd "${BINUTILSDIR}"
check_error $? "Change directory failed."
./configure "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" "--disable-nls"
check_error $? "Error configuring binutils."
make all install
check_error $? "Error compiling/installing binutils."

echo ">>> Compiling and installing GCC"
cd "${OBJDIR}"
check_error $? "Change directory failed."
"${GCCDIR}/configure" "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" --with-gnu-as --with-gnu-ld --disable-nls --disable-threads --enable-languages=c,objc,c++,obj-c++ --disable-multilib --disable-libgcj --without-headers --disable-shared
check_error $? "Error configuring GCC."
PATH="${PATH}:${PREFIX}/bin" make all-gcc install-gcc
check_error $? "Error compiling/installing GCC."

echo
echo ">>> Cross-compiler for ${TARGET} installed."

Sorry for any line wrapping, should be easy to fix. If you want a pastebin or http link to get it, just leave a comment.

Tim Post
Thanks. I'm trying it now; before I hoped I could just past the configure line from your script into what I was trying above ... no luck (yet).
Jamie
Did you test this? Bin utils doesn't compile. In the compilation of BINUTILS, I added some "sed" scripting to change one of the source files. see http://www.mail-archive.com/[email protected]/msg06475.html
Jamie
Aside from the error compiling BinUtils, this works if you want a compiler for the bare metal. I need a Linux/GLIBC tool stack. Thanks though.
Jamie
It turns out your answer wasn't to question I was asking, but the question I should have been asking. (That is, I don't need a cross compiled GLIBC because one exists on the target already).
Jamie
@Jamie - Sorry, I assumed that you knew that (and were just building to make packages for an architecture different than the host machine).
Tim Post
+1  A: 

If you get stuck here, the #gnu channel on Freenode will likely be able to help, as will the gcc-help mailing list.

mattl
As a fallback, sure, and thanks, but generally speaking I'd prefer to have the Stackoverflow community help; they're/we're far more responsive than most mailing lists I've got experience with.
Jamie
+1  A: 

I recently built a GNU toolchain for ARM using crosstool-ng. It took a bit of trial and error to figure out which versions of the toolchain components would play nice together, but I finally got it working with the following versions:

  • binutils 2.19.1
  • gcc 4.3.2
  • gmp 4.2.2
  • linux kernel 2.6.29.1
  • mpfr 2.3.1
  • uClibc 0.9.30.1

See if these work for you too.

Also, OpenWrt as a part of it's build process creates a cross-compiling toolchain. You may want to try that, selecting one of the ARM-based boards as a target, even if you aren't interested in making a wireless router.

Tyler McHenry
+1  A: 

The Maemo community are very supportive for cross-development on the Nokia N800 and friends, which are handheld Linux boxes. I recall we did some cross-development around 2007 using Scratchbox 2, which was dead easy to use and is packaged with Debian. There are also some wiki pages on using older versions of scratchbox with Ubuntu.

Norman Ramsey
A: 

This was a bit of red-herring. Apparently cross-compling a tool chain for an existing system with a working GLIBC doesn't require GLIBC to be recompiled. I honestly don't know how I ignored this fact.

So even though I still don't know how to cross compile GCC and GLIBC, as I only need GCC I'm going to mark this as closed.

If I can, I'll come back to this post and mark what I eventually did.

EDIT:

Checkout this.

Jamie
+1  A: 

I've had good luck using buildroot to build toolchains and libraries for cross-compiling Linux. Buildroot uses the lightweight uclibc C library rather than glibc, so it might not work for your purposes. (And getting the toolchain this way might not be quite as exciting and compiling it yourself.)

Commodore Jaeger
+2  A: 

Welcome, your're not alone.

The story

I don't know why ARM cross-compiling is such a nightmare. It's not my opinion, let's see, what others say...

Building a gcc / glibc cross-toolchain for use in embedded systems development used to be a scary prospect, requiring iron will, days if not weeks of effort, lots of Unix and Gnu lore, and sometimes willingness to take dodgy shortcuts. ( http://www.kegel.com/crosstool/ )

My ARM computer (GuruPlug) is running on Debian, so I just need a standard G++ compiler, without any tweaks.

I'm using 32-bit Ubuntu on my notebook. There are deb packages for AVR cross-compiler, or even for Z80, but none for ARM - why? OK, we have to compile one. Let's go. The compilation process of the toolchain is a bit confusing for me. 14k lines long Makefile, thank you.

After some days (and nights) I've failed.

The solution

Finally, I've found an out-of-the box soluion. I've just downloaded the lite edition of this stuff: http://www.codesourcery.com/sgpp/lite_edition.html and now I'm happy. It has an ugly installer, but it works. It says: arm-none-linux-gnueabi-g++ (Sourcery G++ Lite 2010q1-202) 4.4.1, which is an up-to-date G++ version.

(My friend has a Mac, and he has also failed compiling the toolchain after fighting with it for a week. He is now using this compiler on a VM running Ubuntu.)

ern0
My particular challenge is that I have to link a toolchain that uses existing libraries on the target, and will compile a more recent version of the Kernel. I eventually got it to work, weeks after giving up a documented approach so I've know idea what I did. Now I move those binaries around as a tarball, making sure that as long as the 32 bit libraries are installed on my host.
Jamie
By the way, the sales staff, or at least Carlos, at codesourcery was immensely helpful in my understanding of what my needs were. Because of those needs, they couldn't help me 'outof the box'; nonetheless I was impressed with their service to just a potential customer.
Jamie
+2  A: 

You should really have put more effort with using crosstool-NG, since the crosstool mailing list is very reactive. Since understanding the whole process is a huge task, understanding how to use a tool that you might reuse is IMHO more interesting.

shodanex
Agreed, and I'm moving that way. But I've been using COTS arm boards for three years now, and there is a compelling business case to fab the processor, ram etc. ourselves. crosstool-NG is ... amazing for what it delivers, but, it is producing a fairly large footprint in the `sys-root`. This exercise is turning into a hobby, one where I'd like to say "yeah, I could do that, but why bother".
Jamie