# Makefile that builds a cross compiler against an existing system.
#
# This version fetches the Maverick libc and headers and builds a
# compiler against that.  To build for a different system,
# replace the sysroot.stamp rule with one that installs the headers
# and libc for your target.
#
# Tested on Ubuntu Maverick.  It should work on any Linux
# operating that has 'dpkg' including Fedora.  Note that .deb files are
# 'ar' archives so you could extract them manually.
#
# Copyright (c) 2010 Linaro
# Contributors:
#   Michael Hope - initial implementation
#

# Basics:

# Target machine triplet
TARGET = arm-linux-gnueabi

# Where to install.  Must be writable.
PREFIX = $(HOME)/opt/gcc-linaro-cross

# Configure flags to pass to GCC.  Sets the default system that GCC
# builds for.  Note that the calling convention must be the same as
# the pre-built sysroot
GCCFLAGS = --with-mode=thumb --with-arch=armv7-a --with-float=softfp --with-fpu=vfpv3-d16

# Sysroot:

# Where the headers and libc will end up.  You may want to check out
# the GCC --with-build-sysroot configure option
SYSROOT = $(PREFIX)/$(TARGET)/libc

# Where to fetch the packages from
MIRROR = http://ports.ubuntu.com/

# Set the pre-built headers and libc to build against.  The following are
# from Ubuntu Maverick as at 2010-12-01.  To check these, log into a
# Ubuntu ARM machine, run 'apt-cache show libc6', and look for the
# 'Filename:' line.
LIBC6 = pool/main/e/eglibc/libc6_2.12.1-0ubuntu10_armel.deb
LIBC6DEV = pool/main/e/eglibc/libc6-dev_2.12.1-0ubuntu10_armel.deb
LINUXLIBCDEV = pool/main/l/linux/linux-libc-dev_2.6.35-1023.41_armel.deb

# All of the packages that go into the sysroot
PACKAGES = $(LIBC6) $(LIBC6DEV) $(LINUXLIBCDEV)

# Sources:

# The binutils version to build
BINUTILSSRC = src/binutils-2.20.51.tar.bz2
# The Linaro GCC version to build.  Check out
# https://launchpad.net/gcc-linaro/+download for the latest link.
# You'll also need to update the URL used in $(GCCSRC): below.
GCCSRC = src/gcc-linaro-4.5-2010.11-1.tar.bz2

# Alternatively, use the easy-to-install source packages that come
# with Maverick.  Try 'apt-get install gcc-4.5-source binutils-source'
# and uncomment the following lines
#BINUTILSSRC = $(wildcard /usr/src/binutils/binutils-*z)
#GCCSRC = $(wildcard /usr/src/gcc-4.5/gcc-*z)

# Options:

# Build in parallel
PARALLEL = -j3
# Tell curl to be quiet, follow links, and resume
CURLFLAGS = -s -L -C -

all: binutils gcc

# Binutils
binutils: binutils-install.stamp

# Convenience target to fetch the binutils source
binutils-src: $(BINUTILSSRC)

# Fetch the binutils tarball.  MLH uses a HTTP proxy, so the  URL is
# the first HTTP mirror that I found.  The primary URL is
# ftp://sourceware.org/pub/binutils/snapshots/
$(BINUTILSSRC):
	mkdir -p src
	curl $(CURLFLAGS) -o $@ http://mirror.facebook.net/sourceware/binutils/snapshots/$(@F)

# Extract
binutils-extract.stamp: $(BINUTILSSRC)
	mkdir -p src
	tar xaf $< -C src
	touch $@

# Configure
binutils-configure.stamp: binutils-extract.stamp
	mkdir -p build/binutils
	cd build/binutils && ../../src/binutils*/configure \
	--prefix=$(PREFIX) \
	--target=$(TARGET) \
	--disable-nls \
	--with-sysroot=$(SYSROOT)
	touch $@

# Build and install
binutils-install.stamp: binutils-configure.stamp
	make -C build/binutils $(PARALLEL)
	make -C build/binutils $(PARALLEL) install
	touch $@

# Fetch and extract the sysroot.  Unfortunately the packages include
# absolute links in sysroot/usr/lib.  Fix these up to point to the
# sysroot instead.
sysroot.stamp:
	mkdir -p src
	cd src && curl $(CURLFLAGS) $(PACKAGES:%=-O $(MIRROR)%)
	mkdir -p $(SYSROOT)
	find src -name "*.deb" -exec dpkg -x {} $(SYSROOT) \;
	for i in $(SYSROOT)/usr/lib/*; do \
		if [ -L $i ] && (readlink $$i | grep -q ^/); then \
			x=`readlink $$i`; rm $$i; ln -s $(SYSROOT)$$x $$i; \
	fi; done	
	touch $@

# Build GCC
gcc: gcc-install.stamp

# Convenience target to fetch the GCC source
gcc-src: $(GCCSRC)

# Fetch
$(GCCSRC):
	mkdir -p src
	curl $(CURLFLAGS) -o $@ http://launchpad.net/gcc-linaro/4.5/4.5-2010.11-0/+download/$(@F)

# Extract
gcc-extract.stamp: $(GCCSRC)
	mkdir -p src
	tar xaf $< -C src
	touch $@

# Configure
gcc-configure.stamp: binutils-install.stamp sysroot.stamp gcc-extract.stamp
	mkdir -p build/gcc
	cd build/gcc && ../../src/gcc*/configure \
	--enable-languages=c,c++ \
	--prefix=$(PREFIX) \
	--target=$(TARGET) \
	--with-sysroot=$(SYSROOT) \
	$(GCCFLAGS)
	touch $@

# Build and install
gcc-install.stamp: gcc-configure.stamp
	make -C build/gcc $(PARALLEL)
	make -C build/gcc $(PARALLEL) install
	touch $@

# Remove all temporary files
clean:
	rm -rf *.stamp build src
