diff options
author | Bent Bisballe Nyeng <deva@aasimon.org> | 2013-05-02 20:32:37 +0200 |
---|---|---|
committer | Bent Bisballe Nyeng <deva@aasimon.org> | 2013-05-02 20:32:37 +0200 |
commit | d1daccfd3f00d73e51dedfc452f103e6aeb77d13 (patch) | |
tree | 979cae37faebea15fd9627c567651bc5031412aa /toolchain/build-toolchain |
New build environment and documentation.
Diffstat (limited to 'toolchain/build-toolchain')
-rwxr-xr-x | toolchain/build-toolchain | 217 |
1 files changed, 217 insertions, 0 deletions
diff --git a/toolchain/build-toolchain b/toolchain/build-toolchain new file mode 100755 index 0000000..c872e65 --- /dev/null +++ b/toolchain/build-toolchain @@ -0,0 +1,217 @@ +#!/usr/bin/perl +use strict; +use warnings; +use FindBin qw($Bin $Script); +use File::Path; + +my $GNU_MIRROR = 'ftp://ftp.fu-berlin.de/unix/gnu'; +my $NEWLIB_URL = 'ftp://sources.redhat.com/pub/newlib'; + +my $GCC_VERSION = '4.6.3'; +my $GDB_VERSION = '7.4'; +my $BINUTILS_VERSION = '2.22'; +my $NEWLIB_VERSION = '1.20.0'; +my $OPENOCD_VERSION = '0.5.0'; + +my $GCC_URL = "$GNU_MIRROR/gcc/gcc-$GCC_VERSION"; +my $GDB_URL = "$GNU_MIRROR/gdb"; +my $BINUTILS_URL = "$GNU_MIRROR/binutils"; + +my $issue = 'this OS'; +if (open I, "</etc/issue") { + $issue = <I>; + close I; + + $issue =~ s/\\.*$//g; + $issue =~ s/\s+$//g; +} + +if ($issue =~ /^Ubuntu/) { + + if ($issue !~ /^Ubuntu 11.10/) { + warn "Notice that this script hasn't been tested on $issue, if it fails, try Ubuntu 11.10 in stead\n"; + } + + my @missing; + for my $p qw'build-essential zlib1g-dev libgmp-dev libmpfr-dev libmpc-dev texinfo libftdi-dev libncurses5-dev libreadline-dev libexpat1-dev' { + print "Checking that you have $p\n"; + push @missing, $p if system("dpkg -s $p > /dev/null"); + } + + if (@missing) { + my $cmd = "sudo apt-get install ".join(' ', @missing); + print "You're missing some packages, trying to fix that with: $cmd\n"; + system($cmd) and die "Failed to install missing packages, please run this command manually: $cmd"; + } + +} else { + warn "Notice that this script hasn't been tested on $issue, if it fails, try Ubuntu 11.10 in stead\n"; +} + +my @DIRS = ( + { + dir => "binutils-$BINUTILS_VERSION", + url => $BINUTILS_URL, + cfg => ['--target=arm-none-eabi', '--enable-interwork', '--enable-multilib'], + make => 'make all install', + }, + + { + dir => "gcc-$GCC_VERSION", + url => $GCC_URL, + cfg => ['--target=arm-none-eabi', '--enable-interwork', '--enable-multilib', '--enable-languages=c,c++', + '--with-newlib', + "--with-headers=../../src/newlib-$NEWLIB_VERSION/newlib/libc/include", + '--with-system-zlib', + '--with-cpu=cortex-m3', '--with-mode=thumb', + ], + make=>'make all-gcc install-gcc', + + make2=>'make all install', + }, + + { + dir => "gcc-core-$GCC_VERSION", + url => $GCC_URL, + }, + + { + dir => "gcc-g++-$GCC_VERSION", + url => $GCC_URL, + }, + + { + dir => "newlib-$NEWLIB_VERSION", + file => "newlib-$NEWLIB_VERSION.tar.gz", + url => $NEWLIB_URL, + + cfg => ['--target=arm-none-eabi', '--enable-interwork', '--enable-multilib', + '--with-cpu=cortex-m3', '--with-mode=thumb', '--disable-newlib-supplied-syscalls' + ], + make => 'make all install', + }, + + { + dir => "gdb-$GDB_VERSION", + url => $GDB_URL, + + cfg2=>['--target=arm-none-eabi', '--enable-interwork', '--enable-multilib'], + make2=>'make all install', + }, + + { + dir=> "openocd-$OPENOCD_VERSION", + url=>"http://downloads.sourceforge.net/project/openocd/openocd/$OPENOCD_VERSION/openocd-$OPENOCD_VERSION.tar.bz2?use_mirror=autoselect", + + inplace=>1, + patch=>'openocd-0.5.0-fix.patch', + cfg=>['--enable-ft2232_libftdi', '--enable-jlink', + '--enable-buspirate' + ], + make=>'make all install', + }, +); + +my $tarDir = "$Bin/tarballs"; +mkdir $tarDir; + +# Do all the downloading up front, so we get that out of the way. +for my $d (@DIRS) { + $d->{file} //= "$d->{dir}.tar.bz2"; + + my $fn = "$tarDir/$d->{file}"; + my $url = "$d->{url}/$d->{file}"; + + if (-f $fn) { + print "You already have $d->{file}, skipping\n"; + } else { + system("wget", "-O", $fn, $url) and die "Failed to fetch $d->{file} from $url"; + die "Did not find the expected file: $fn" unless -f $fn; + } +} + + +# Unpack, configure, build and install each package. +my $srcDir = "$Bin/src"; +mkdir $srcDir; +my $buildDir = "$Bin/build"; +mkdir $buildDir; +my $installDir = "$Bin/arm-toolchain"; +mkdir $installDir; + +$ENV{PATH} = "$ENV{PATH}:$installDir/bin"; + +# Unpack all at sources once. +for my $d (@DIRS) { + my $fn = "$tarDir/$d->{file}"; + my $dn = "$srcDir/$d->{dir}"; + + if (-d $dn) { + print "Already unpacked $d->{dir}, skipping unpack\n"; + } else { + print "Unpacking $fn\n"; + chdir $srcDir; + system("tar", "xf", $fn) and die "Failed to unpack $fn into $srcDir"; + mkdir $dn; + + if ($d->{patch}) { + chdir $dn; + system("patch -p 1 < $Bin/$d->{patch}") and die "Failed to apply patch: $d->{patch}"; + } + } +} + +# Do the actual building, first pass +for my $d (@DIRS) { + my $fn = "$tarDir/$d->{file}"; + my $dn = "$srcDir/$d->{dir}"; + my $bn = "$buildDir/$d->{dir}"; + + next if -f "$bn.done"; # Lazyness ftw. + + rmtree $bn; + mkdir $bn; + if ($d->{inplace}) { + chdir $dn; # Build in the source directory, needed for borken packages + } else { + chdir $bn; # Build in a separate tree, because it's nice not to mess up the source tree. + } + + next unless $d->{make} and $d->{cfg}; + + my @cfg = (@{$d->{cfg}}, "--prefix=$installDir"); + print "Running: $bn> $dn/configure ".join(' ',@cfg)."\n"; + system("$dn/configure", @cfg) and die "Failed to configure in $bn"; + + print "Running: $bn> $d->{make}\n"; + system($d->{make}) and die "Failed to run $d->{make} in $bn"; + open D, ">$bn.done"; + close D; +} + +# Second pass, needed because we need to hit gcc twice, before and after building newlib. +for my $d (@DIRS) { + my $fn = "$tarDir/$d->{file}"; + my $dn = "$srcDir/$d->{dir}"; + my $bn = "$buildDir/$d->{dir}"; + + next unless $d->{make2}; + + next if -f "$bn.done2"; # Lazyness ftw. + chdir $bn; + + if ($d->{cfg2}) { + my @cfg = (@{$d->{cfg2}}, "--prefix=$installDir"); + print "Running2: $bn> $dn/configure ".join(' ',@cfg)."\n"; + system("$dn/configure", @cfg) and die "Failed to configure in $bn"; + } + print "Running2: $bn> $d->{make2}\n"; + system($d->{make2}) and die "Failed to run2 $d->{make2} in $bn"; + open D, ">$bn.done2"; + close D; +} + +print "\n\nAll done, toolchain can be found in $installDir\n"; +print "Add to path with: export PATH=\${PATH}:$installDir/bin\n"; +exit 0; + |