How do I install Haskell Stack locally? - haskell

I am working on my school server and I need to install Haskell's stack. In the README file and on the website I could not find how to install locally. What can I do if I am not a sudo user?

You don't need superuser privileges to install stack; you can as well install it in your own home directory. All you need for this to work is a Linux system with GMP installed (which GHC depends on at a very fundamental level). If GMP is not installed – the admins really shouldn't have any concerns installing that. (Alternatively, follow these instructions to install GMP without root permissions.)
#!/bin/bash
# Stack installation script, adapted from:
# https://github.com/yantonov/install-ghc/blob/af0b968b9e8423efb152ccec4224821e29317710/ubuntu/install-ghc-ubuntu.md
DOWNLOADS_DIR=$HOME/Downloads
STACK_INSTALL_DIR="$HOME/Development/bin"
mkdir -p ${STACK_INSTALL_DIR}
STACK_VERSION="2.1.3"
STACK_ARCHITECTURE="x86_64"
STACK_PLATFORM="linux"
# Check that libgmp is installed. This is the main critical system-level
# dependency of the Haskell environment that may not be present.
function check_lib()
{
echo "int main(){}" | gcc -o /dev/null -lgmp -x c -
return $?
}
GMP_OK=false
if (ldconfig -p | grep -q "libgmp.so.10"); then
GMP_VERSION_POSTFIX=""
if (check_lib -lgmp); then GMP_OK=true; fi
elif (ldconfig -p | grep -q "libgmpxx.so.4"); then
GMP_VERSION_POSTFIX="-gmp4"
if (check_lib -lgmp); then GMP_OK=true; fi
fi
if [ $GMP_OK = false ]; then
echo >&2 "Haskell requires the GNU multi-precision library (with headers)"
echo >&2 "in version 4 or 10, but neither can be found. Try"
echo >&2
echo >&2 "$ sudo apt-get install libgmp-dev"
echo >&2
echo >&2 "or https://unix.stackexchange.com/questions/265239/how-to-install-a-custom-gmp-lib-for-just-one-user"
echo >&2
exit 1
fi
STACK_DIST_FILENAME="stack-$STACK_VERSION-$STACK_PLATFORM-$STACK_ARCHITECTURE.tar.gz"
STACK_DIST_UNZIPPED_DIR="stack-$STACK_VERSION-$STACK_PLATFORM-$STACK_ARCHITECTURE"
STACK_DIST_URL="https://www.stackage.org/stack/$STACK_PLATFORM-$STACK_ARCHITECTURE"
STACK_TARGET_DIR="stack-$STACK_VERSION"
cd $DOWNLOADS_DIR
curl -L -o $STACK_DIST_FILENAME $STACK_DIST_URL
tar xvfz $STACK_DIST_FILENAME
# in case if error like this:
#curl: (77) error setting certificate verify locations: CAfile:
# /etc/pki/tls/certs/ca-bundle.crt CApath:
# ...
# create ~/.curlrc file
# and put this lines to it
# capath=/etc/ssl/certs/
# cacert=/etc/ssl/certs/ca-certificates.crt
# move to home development dir
rm -rf $STACK_INSTALL_DIR/$STACK_TARGET_DIR
mv $STACK_DIST_UNZIPPED_DIR $STACK_INSTALL_DIR/$STACK_TARGET_DIR
cd $STACK_INSTALL_DIR
# sym link
rm -rvi stack
ln -s `pwd`/$STACK_TARGET_DIR stack
# add to PATH environment
STACK_HOME=$HOME/Development/bin/stack
PATH=$STACK_HOME:$PATH
# clean up
cd $DOWNLOADS_DIR
rm -rf stack-$STACK_VERSION*
# install ghc
stack setup

The Haskell stack is successfully installed using the instructions in Documentation here.
As the case with "sudo user", the command sudo grants a user with super user privileges by flipping the mode bit. The details regarding the mechanism can be found here.
The problem in your case might be the reason that in "School Networks", users are restricted to use sudo for security purposes and hence, either the administrators must grant your account privileges or they must install the Haskell stack themselves. If this is a part of an assignment, adminstrators should have no problem doing so and you must inform administrators regarding this. Thereafter, you must be able to use it comfortably.
If the above steps are not possible, I would suggest you to try out Haskell stack in your personalized account on a device. You may even try out Cloud services like Cloud9, Nitrous and others. An unlikely reason might be that you are not using the Haskell stack properly.
Note: I have used the Haskell stack for some time, hence, I can conclude that it works.

Related

How to install gprbuild on Linux - Centos7

I have recently dowloaded GNAT Community on my Linux machine (Centos7).
Within /home/parallels/opt/GNAT/2019 there is a folder gprbuild, my understanding is that to install this I need to execute the bootstrap.sh script that is located within gprbuild:
/home/parallels/opt/GNAT/2019/gprbuild/bootstrap.sh
I try to execute the bootstrap.sh script like so...
[parallels#localhost gprbuild]$ ./bootstrap.sh
Then I recieve this error message...
./bootstrap.sh: line 87: gnatmake: command not found
Here is the bootstrap.sh script...
# bootstrap.sh - a simple bootstrap for building gprbuild with xmlada
progname=bootstrap
prefix=/usr/local
bindir=/bin
datarootdir=/share
libexecdir=/libexec
srcdir=$PWD
xmlada_src=../xmlada
CC=${CC:-cc}
GNATMAKE=${GNATMAKE:-gnatmake}
CFLAGS=${CFLAGS:-$CFLAGS}
GNATMAKEFLAGS=${GNATMAKEFLAGS:--j0}
usage() {
cat >&2 <<EOF
usage: $progname [options]
Options [defaults in brackets]:
--prefix=DIR installation prefix [$prefix]
--bindir=DIR user executables [PREFIX/bin]
--libexecdir=DIR program executables [PREFIX/libexec]
--datarootdir=DIR read-only arch.-independent data root [PREFIX/share]
--srcdir=DIR source code path [$PWD]
--with-xmlada=DIR xmlada source path [$xmlada_src]
--build build only but do not install
--install install only, skip build steps
Environment variables:
CC specify C compiler [$CC]
CFLAGS set C and Ada compilation flags [$CFLAGS]
DESTDIR optional for staged installs
GNATMAKE specify gnatmake Ada builder [$GNATMAKE]
GNATMAKEFLAGS additional Ada builder flags [$GNATMAKEFLAGS]
EOF
exit 0
}
error() {
printf -- "%s: $1" "$progname" "${#:2}" >&2
exit 1
}
while :; do
case $1 in
--prefix=?*) prefix=${1#*=} ;;
--bindir=?*) bindir=${1#*=} ;;
--libexecdir=?*) libexecdir=${1#*=} ;;
--datarootdir=?*) datarootdir=${1#*=} ;;
--srcdir=?*) srcdir=${1#*=} ;;
--with-xmlada=?*) xmlada_src=${1#*=} ;;
--build) MODE="build";;
--install) MODE="install";;
-h|-\?|--help) usage ;;
*=*) error '%s: Requires a value, try --help\n' "$1" ;;
-?*) error '%s: Unknown option, try --help\n' "$1" ;;
*) break # End of arguments.
esac
shift
done
set -e
inc_flags="-I$srcdir/src -I$srcdir/gpr/src -I$xmlada_src/sax -I$xmlada_src/dom \
-I$xmlada_src/schema -I$xmlada_src/unicode -I$xmlada_src/input_sources"
# Programs to build and install
bin_progs="gprbuild gprconfig gprclean gprinstall gprname gprls"
lib_progs="gprlib gprbind"
# Build
if [ "x"${MODE} == "x" ] || [ ${MODE} == "build" ];
then
command $CC -c $CFLAGS "$srcdir"/gpr/src/gpr_imports.c
for bin in $bin_progs; do
command $GNATMAKE $inc_flags "$bin"-main -o "$bin" $CFLAGS $GNATMAKEFLAGS -largs gpr_imports.o
done
for lib in $lib_progs; do
command $GNATMAKE $inc_flags "$lib" $CFLAGS $GNATMAKEFLAGS -largs gpr_imports.o
done
fi;
# Install
if [ "x"${MODE} == "x" ] || [ ${MODE} == "install" ];
then
mkdir -p "$DESTDIR$prefix$bindir"
mkdir -p "$DESTDIR$prefix$libexecdir"/gprbuild
mkdir -p "$DESTDIR$prefix$datarootdir"/gprconfig
mkdir -p "$DESTDIR$prefix$datarootdir"/gpr
install -m0755 $bin_progs -t "$DESTDIR$prefix$bindir"
install -m0755 $lib_progs -t "$DESTDIR$prefix$libexecdir"/gprbuild
install -m0644 "$srcdir"/share/gprconfig/*.xml -t "$DESTDIR$prefix$datarootdir"/gprconfig
install -m0644 "$srcdir"/share/gprconfig/*.ent -t "$DESTDIR$prefix$datarootdir"/gprconfig
install -m0644 "$srcdir"/share/_default.gpr "$DESTDIR$prefix$datarootdir"/gpr/_default.gpr
fi
I have been told that I need to install xmlada prior to installing gprbuild, then I have read elsewhere that I need to install gprbuild to be able to install xmlada!
I have a similair issue when attempting to install xmlada, the shell script within the xmlada folder is called install-sh, when I attempt to install this I am told there is no input file specified...
[parallels#localhost xmlada]$ ./install-sh
./install-sh: no input file specified.
I apreciate this is really two questions in one, but I felt I had to explain it this way, as I am unsure which library needs to be installed first, and also how do I actually install them.
Any help would be greatly apreciated! I hope you're all having a good weekend... :)
Thanks,
Lloyd
Just install gcc-ada, or search in your package manager for gcc-ada (may change its name), gnat* commands come in this package

Running bash script in another directory

I know this question has been asked many times before but I have not been able to get my code working.
I am using the Raspberry Pi 3, with a CAN-BUS Shield. As this will be going into a production environment I need the Pi setup to be nice and easy. I have started to write a bash script so the production staff can run the script and the Pi will update and install everything it needs from the one script.
I have been following this web site https://harrisonsand.com/can-on-the-raspberry-pi/ and I have run into a problem when it comes to compiling can-utils.
I am able to clone the can-utils.git from here https://github.com/linux-can/can-utils.git
by using sudo git clone https://github.com/linux-can/can-utils.git
but my issues come when I need to run the ./autogen.sh & the ./configure as these are located in the dir can-utils.
If I run this from the Pi terminal as described on the web site, it works fine as I change dir cd can-utils and then just sudo ./autogen.sh but it isn't working when I run it in the bash script.
Below is the script I have so far, I know that most of it is commented out this is so that I can test each part as I write it and don't need to constantly download and install stuff I already have
#!/bin/bash
## Change Password
#printf "***********************************************************************\n"
#printf "Changing Password\n"
#echo "pi:***********" | sudo chpasswd # Password hidden
#sleep 1
#printf "Password Changed\n"
## Update & Upgrade Pi
#printf "***********************************************************************\n"
#printf "Update & Upgrade Pi\n\n"
#sudo apt-get update && sudo apt-get upgrade -y
#sleep 1
## Upgrade dist
#printf "***********************************************************************\n"
#printf "Upgrade Dist\n\n"
#sudo apt-get dist-upgrade -y
#sleep 1
## Install libtools
#printf "***********************************************************************\n"
#printf "Installing libtools\n\n"
#sudo apt-get install git autoconf libtool -y
#sleep 1
## Download required files
#printf "***********************************************************************\n"
#printf "Downloading required files\n\n"
## can-utils
#sudo git clone https://github.com/linux-can/can-utils.git
#sleep 1
## Auto configure can-utils
printf "***********************************************************************\n"
printf "Auto Configure can-utils\n\n"
# Things I have tried and do not work
#(cd /c && exec /can-utils/autogen.sh)
#sudo source /can-utils/autogen.sh
#sudo ./can-utils.autogen.sh
sleep 1
When I try the sudo ./can-utils.autogen.shin the Pi terminal the script starts to work so I think this is sort of the right command I need but then I get an error autoreconf: 'configure.ac or 'configure.in' is required these files are in the can-utils dir but for some reason it can't find them. Please can someone help me I have been searching for the answer for the last 2 days
Thank you for your help, rightly or wrongly I have ended up using cd /home/pi/can-utils I had thought I had tried that in the past but I think cd ./can-utils which didn't work.
sudo with script is for me, a nightmare. I just read in the man of sudo of my fedora 25:
Running shell scripts via sudo can expose the same kernel bugs that make setuid shell scripts unsafe on some operating systems (if your OS has a /dev/fd/ directory, setuid shell scripts are generally safe).
sudo command should protect the root account to avoid to run scripts written by user to gain root privilege.
If you keep the use of sudo, my advise should to add a cd command on top of your script:
cd /where_everithing_is
to be sure to be in the right place.
But, may be, sudo will fight again against you !

Should bash scripts use sudo, or assume sudo?

Which pattern is preferable:
#!/bin/bash
echo Installing blah
apt-get install -y blah
...which will fail if run without root perms, or:
#!/bin/bash
echo Installing blah
sudo apt-get install -y blah
...which will succeed as long as the user has sudo access.
I have tended to use the second pattern, but it seems to be rare, so I'm asking what its disadvantages are. The benefits I see are:
It's clear which commands actually require superuser permissions to run (useful if the reader wants to pull the script apart)
Saves a few keystrokes for the user.
I guess downsides include that the use of root permissions might be surprising ("I didn't type sudo, so I didn't expect anything like apt-get to be run...."). What else?
I will prefer second Pattern,
because running few commands with sudo is better rather then running entire script with root permissions in which some commands are needless to have root access and so if you perform these commands with root user further using that command outputs will again need root access or you will have to change the ownership.
So I will prefer second approach where sudo is necessary do it, else go local user.
You could always test if the user is root (id -u gets the uid of the current user, and 0 is root), and run sudo if they aren't -
#!/bin/bash
echo Installing blah
CMD=""
if [ "$(id -u)" != "0" ]; then
CMD="sudo"
fi
${CMD} apt-get install -y blah
The more common approach would be to exit with an error condition if they aren't root,
#!/bin/bash
if [ "$(id -u)" != "0" ]; then
echo "sudo $0 (must run as root)"
exit 1
fi
echo Installing blah
apt-get install -y blah
The second option is the correct option. Commands that don't require root access should not be run as root just to simplify your script. Commands that do require root access (or access by any specific user, for that matter) should be run by sudo. For clarity, you can use the -p option to sudo to present a custom prompt which can explain exactly why the user is asked for their password.
Option two is also preferable because sudo is highly configurable, and the user may already have permission to run specific commands with sudo without a password, so it's possible the user would not be inconvenienced by a password prompt. It's less likely that the user is allowed to sudo arbitrary commands (such as your script) without a password.

Cross-compiling Node.js for ARM6 (Raspberry Pi)

I'm trying to get node.js v0.7.9 to compile for the raspberry pi, but as node and v8 are quite large, I'm hoping to be able to cross-compile on another more powerful PC. I'm using the linux-x86 arm-bcm2708-linux-gnueabi toolchain from https://github.com/raspberrypi/tools and have used them to successfully build other executables for the system. I ended up setting the CC,CXX,CPP,STRIP,OBJCOPY,etc. variables to the toolchain equivalents in the environmental variables and ran configure with: ./configure --dest-cpu=arm --without-snapshot to get the final executable. Copying it over to the system and running it however produces the following error:
Extension or internal compilation error at line 0.
Segmentation fault
However, the segmentation fault doesn't happen for any of the non-javascript tasks like node --version and node --help. Are there any CFLAGS/CXXFLAGS I might be missing causing this problem? Bit confused....
NodeJS is available pre-compiled for a few Linux distributions:
https://github.com/joyent/node/wiki/Installing-Node.js-via-package-manager
Since NodeJS is still in testing phase for Debian, in order to install NodeJS on my Raspberry Pi under Debian wheezy, I do:
sudo su
echo deb ftp://ftp.dk.debian.org/debian/ sid main > /etc/apt/sources.list.d/sid.list
apt-get update
apt-get install nodejs
rm /etc/apt/sources.list.d/sid.list
apt-get update
exit
NodeJS works very fine and stable on my Raspberry Pi.
Just a note - this worked great for me but didn't install NPM. So if you want NPM (which you most assuredly do I would think) make sure to run
apt-get install npm
after installing node before you remove the update locations from the update list.
I've been working on this a bit since the question was originally asked, even added some patches to help auto-detect cross-compiler settings. Node.js in the repositories is (at the moment) a rather old version, and may or may not support the full hard-float (VFP) architecture.
For a full detailed HOWTO, see Nathan Rajlich's write up at http://n8.io/cross-compiling-nodejs-v0.8/
I've posted binaries for others who don't want to go through all this hassle for the same hardware at https://gist.github.com/3245130
Here's the script I wrote to automatically cross compile NodeJS for ARMv6 (Raspbery Pi) using Jenkins.
https://gist.github.com/hertzg/12c2d7fc40f68ff6deeb
I've used #Adam M-W's 'packing' snippet
The script will automatically download everything required and start building.
Just note that current (v0.10.30) version will not compile due to this issue:
https://github.com/joyent/node/issues/8062#issuecomment-52541037
Run with _PARAMS_NODEJS_SOURCE_ARCHIVE_URL=http://nodejs.org/dist/v0.10.29/node-v0.10.29.tar.gz to get the latest cross compile-able version.
#!/bin/bash
set -e
set -x
### IF we dont have archive url prefix
if [ -z "$_PARAMS_NODEJS_SOURCE_ARCHIVE_URL" ]; then
_PARAMS_NODEJS_SOURCE_ARCHIVE_URL=$(wget -qO- http://nodejs.org/dist/latest/ | egrep -o 'node-v[0-9\.]+.tar.gz' | tail -1);
_PARAMS_NODEJS_SOURCE_ARCHIVE_URL="http://nodejs.org/dist/latest/"$_PARAMS_NODEJS_SOURCE_ARCHIVE_URL
fi
if [ -z "$_PRAMS_RPI_TOOLS_SOURCE_ARCHIVE_URL" ]; then
_PRAMS_RPI_TOOLS_SOURCE_ARCHIVE_URL="https://github.com/raspberrypi/tools/archive/master.tar.gz"
fi;
NODEJS_SOURCE_ARCHIVE_FILENAME=$(basename $_PARAMS_NODEJS_SOURCE_ARCHIVE_URL)
NODEJS_SOURCE_DIRECTORY=${NODEJS_SOURCE_ARCHIVE_FILENAME%.tar.gz}
#Download NodeJS
echo "-> Searching for NodeJS "$NODEJS_SOURCE_ARCHIVE_FILENAME;
if [ ! -e "$PWD/$NODEJS_SOURCE_ARCHIVE_FILENAME" ]; then
echo "--> Downloading from "$_PARAMS_NODEJS_SOURCE_ARCHIVE_URL;
wget --no-check-certificate -O $NODEJS_SOURCE_ARCHIVE_FILENAME $_PARAMS_NODEJS_SOURCE_ARCHIVE_URL
echo "--> Download finished!"
fi;
echo "--> Extracting"
rm -rf $NODEJS_SOURCE_DIRECTORY
tar --overwrite -xf $NODEJS_SOURCE_ARCHIVE_FILENAME
echo "--> Linking"
ln -snf "$PWD/$NODEJS_SOURCE_DIRECTORY" "$PWD/node"
echo "-> Done!"
echo "-> Searching Raspberry Pi Toolset";
if [ ! -d "$PWD/rpi" ]; then
if [ ! -e "$PWD/rpi-tools.tar.gz" ] || [ -s "$PWD/rpi-tools.tar.gz" ]; then
echo "--> Downloading from "$_PRAMS_RPI_TOOLS_SOURCE_ARCHIVE_URL
wget --no-check-certificate -O "rpi-tools.tar.gz" $_PRAMS_RPI_TOOLS_SOURCE_ARCHIVE_URL
echo "--> Download finished"
else
echo "--> Found rpi-tools.tar.gz."
fi
echo "--> Extracting"
tar xf "rpi-tools.tar.gz"
echo "--> Linking tools-master to rpi"
ln -snf "$PWD/tools-master" "$PWD/rpi"
else
echo "-> found"
fi;
echo "-> Done!"
echo "-> Cross-Compile..."
echo "--> Setup ENV"
export PATH="$PWD/rpi/arm-bcm2708/arm-bcm2708hardfp-linux-gnueabi/bin:"$PATH
export HOST="arm-bcm2708hardfp-linux-gnueabi"
export CC="${HOST}-gcc"
export CXX="${HOST}-g++"
export AR="${HOST}-ar"
export RANLIB="${HOST}-ranlib"
export LD="${HOST}-ld"
export CPP="${HOST}-gcc -E"
export STRIP="${HOST}-strip"
export OBJCOPY="${HOST}-objcopy"
export OBJDUMP="${HOST}-objdump"
export NM="${HOST}-nm"
export AS="${HOST}-as"
"${HOST}-gcc" --version
echo "--> Waiting 5s to contiue"
pushd "$PWD/node"
sleep 5
echo "--> Clean"
make clean
echo "--> Configure"
./configure --prefix=/ --without-snapshot --dest-cpu=arm --dest-os=linux
echo "--> Build"
VERSION=${NODEJS_SOURCE_DIRECTORY##node-}
export BINARYNAME=node-${VERSION}-linux-arm-armv6j-vfp-hard
mkdir ${BINARYNAME}
make install DESTDIR=${BINARYNAME} V=1 PORTABLE=1
echo "--> Pack"
cp README.md ${BINARYNAME}
cp LICENSE ${BINARYNAME}
cp ChangeLog ${BINARYNAME}
tar -czf ${BINARYNAME}.tar.gz ${BINARYNAME}
echo "--> Cleanup"
popd
mv $PWD"/node/${BINARYNAME}.tar.gz" "./"
echo "-> Done!"
I managed to cross compile nodejs version 0.10 and run it on Freescale i.MX6.
I created a cross compile script to setup the environment and the execute make.
The script basically just set the CC, CXX etc. variables to my cross compile tools plus it sets the arch and some other flags for the compiler.
Then it runs the configure with dest-cpu=arm
I tried to also link in the V8 library (which I also cross compiled), but it would not compile when I included that flag plus the path in configure.
When I compile node, does it compile it's own V8, since I manage to compile without pointing to V8 library (I can see it is compiling some V8 stuff during the compilation)?
Just a heads up you can now just do:
sudo apt-get install nodejs npm
For node 0.12, http://conoroneill.net//download-compiled-version-of-nodejs-0120-stable-for-raspberry-pi-here has instructions + pre-built binaries.

Building ARM GNU Cross compiler

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
Welcome, you'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.)
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 <martin#decky.cz>
#
# 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.
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.
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.
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.
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.)
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.

Resources