Far far far from VCS coding, time for some higher level stuff… but not that much !

Since a few months, I’m looking at what « new » languages can bring, I’m still very fond of C, C++ and even Java but when I need to be efficient and code little tools especially to check something, those languages usually divert me from my original goal and I spent more time on the code design itself than on the functional aspect of my program.
But on the other hand I simply hate Python, Ruby, Javascript (even if I must admit I like node.js, but not due to the language choice…).

So I coded a few things in Go… Funny, especially the error management, a lot of opensource framework…. but somewhat not that new. And I failed make it working on embedded platforms (it was not clear one year ago if it could work or not), Go’s memory management simply doesn’t fit.

And recently I took time to look at Mozilla’s Rust and I must admit it seems to solve most of my issues : one language for embedded dev up to webdev, a large community, and new paradigms really interesting. I won’t go much in details, a lot of smarter people gave their opinions, just DuckDuckGo for it :)

Consequently, as I’dd like my little tools to run on my Raspberry Pis, I tried to cross-compile the Rust Compiler (rustc) for the Rpi so that I can directly code and execute. Currently there is no official port of the rustc for Rpi, so with the help of kwantam who already ported if to the Nexus7, I modified his script to compile it for the Rpi… and it works :)

Basically, the « only » changes is to used the prebuilt gcc gnueabihf toolchain for the Rpi (DON’T use the one provided in Ubuntu packages) and define the good target/options.

 

This was tested with an Ubuntu Server 14.04 LTS x64, and gcc/g++ 4.8, compiled for the Rasbpian (Debian Wheezy June 2014).
Note that you will need also to install gcc 4-8 on the Rpi to make it working.

 

Here is the result :

echo "-------------------------------"
echo "setup linux env"
echo "-------------------------------"
sudo apt-get update
sudo apt-get -y install apt-utils git gcc g++ perl python2.7 curl make unzip nano

echo "-------------------------------"
echo "download rpi toolchain"
echo "-------------------------------"
wget https://github.com/raspberrypi/tools/archive/master.zip
unzip master.zip
export PATH=$PWD/tools-master/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin:$PATH

echo "-------------------------------"
echo "First steps"
echo "-------------------------------"
mkdir -p $HOME/toolchains/src
cd $HOME/toolchains/src
git clone https://github.com/mozilla/rust.git
cd rust
git submodule update --init

echo "-------------------------------"
echo "Configuring Rust"
echo "-------------------------------"
cd $HOME/toolchains/src/rust
mkdir build
cd build
mkdir -p $HOME/toolchains/var/lib
mkdir $HOME/toolchains/etc

$PWD/../configure --prefix=$HOME/toolchains                       \
    --host=x86_64-unknown-linux-gnu --disable-llvm-assertions     \
    --target=x86_64-unknown-linux-gnu,arm-unknown-linux-gnueabihf \
    --localstatedir=$HOME/toolchains/var/lib                      \
    --sysconfdir=$HOME/toolchains/etc
cd x86_64-unknown-linux-gnu
find . -type d -exec mkdir -p ../arm-unknown-linux-gnueabihf/\{\} \;

echo "-------------------------------"
echo "Building cross LLVM"
echo "-------------------------------"
cd $HOME/toolchains/src/rust/build/x86_64-unknown-linux-gnu/llvm
$HOME/toolchains/src/rust/src/llvm/configure --enable-target=x86,x86_64,arm,mips  \
    --enable-optimized --disable-assertions --disable-docs --enable-bindings=none \
    --disable-terminfo --disable-zlib --disable-libffi                            \
    --with-python=/usr/bin/python2.7
make -j$(nproc)

cd $HOME/toolchains/src/rust/build/arm-unknown-linux-gnueabihf/llvm
$HOME/toolchains/src/rust/src/llvm/configure --enable-target=x86,x86_64,arm,mips  \
    --enable-optimized --disable-assertions --disable-docs --enable-bindings=none \
    --disable-terminfo --disable-zlib --disable-libffi                            \
    --with-python=/usr/bin/python2.7 --build=x86_64-unknown-linux-gnu             \
    --host=arm-linux-gnueabihf --target=arm-linux-gnueabihf
make -j$(nproc)

echo "-------------------------------"
echo "Enable llvm-config for the cross LLVM build"
echo "-------------------------------"

cd $HOME/toolchains/src/rust/build/arm-unknown-linux-gnueabihf/llvm/Release/bin
mv llvm-config llvm-config-arm
ln -s ../../BuildTools/Release/bin/llvm-config .
# (Now test to be sure this works.)
./llvm-config --cxxflags
# (You should see some CXX flags printed out here!)

echo "-------------------------------"
echo "Making RBS use our LLVM builds"
echo "-------------------------------"
cd $HOME/toolchains/src/rust/build/
chmod 0644 config.mk
grep 'CFG_LLVM_[BI]' config.mk |                                          \
    sed 's/x86_64\(.\)unknown.linux.gnu/arm\1unknown\1linux\1gnueabihf/g' \
    >> config.mk

cd $HOME/toolchains/src/rust
sed -i.bak 's/\([\t]*\)\(.*\$(MAKE).*\)/\1#\2/' mk/llvm.mk    

echo "-------------------------------"
echo "Building a working librustc for the cross architecture"
echo "-------------------------------"
cd $HOME/toolchains/src/rust
sed -i.bak                                                                         \
    's/^CRATES := .*/TARGET_CRATES += $(HOST_CRATES)\nCRATES := $(TARGET_CRATES)/' \
    mk/crates.mk
sed -i.bak                                                                                        \
    's/\(.*call DEF_LLVM_VARS.*\)/\1\n$(eval $(call DEF_LLVM_VARS,arm-unknown-linux-gnueabihf))/' \
    mk/main.mk
sed -i.bak 's/foreach host,$(CFG_HOST)/foreach host,$(CFG_TARGET)/' mk/rustllvm.mk

cd $HOME/toolchains/src/rust
sed -i.bak 's/.*target_arch = .*//' src/etc/mklldeps.py

cd $HOME/toolchains/src/rust/build
arm-unknown-linux-gnueabihf/llvm/Release/bin/llvm-config --libs \
    | tr '-' '\n' | sort > arm
x86_64-unknown-linux-gnu/llvm/Release/bin/llvm-config --libs \
    | tr '-' '\n' | sort > x86
diff arm x86

echo "-------------------------------"
echo "Build it, part 1"
echo "-------------------------------"
cd $HOME/toolchains/src/rust/build
make -j$(nproc)

echo "-------------------------------"
echo "Build it, part 2"
echo "-------------------------------"
cd $HOME/toolchains/src/rust/build
LD_LIBRARY_PATH=$PWD/x86_64-unknown-linux-gnu/stage2/lib/rustlib/x86_64-unknown-linux-gnueabihf/lib:$LD_LIBRARY_PATH 	\
    ./x86_64-unknown-linux-gnu/stage2/bin/rustc --cfg stage2 -O --cfg rtopt                                       	\
    -C linker=arm-linux-gnueabihf-g++ -C ar=arm-linux-gnueabihf-ar               				  	\
    -C target-feature=+vfp2,-neon  -C target-cpu=arm1176jzf-s					  			\
    --cfg debug -C prefer-dynamic --target=arm-unknown-linux-gnueabihf                                            	\
    -o x86_64-unknown-linux-gnu/stage2/lib/rustlib/arm-unknown-linux-gnueabihf/bin/rustc --cfg rustc              	\
    $PWD/../src/driver/driver.rs
LD_LIBRARY_PATH=$PWD/x86_64-unknown-linux-gnu/stage2/lib/rustlib/x86_64-unknown-linux-gnueabihf/lib:$LD_LIBRARY_PATH 	\
    ./x86_64-unknown-linux-gnu/stage2/bin/rustc --cfg stage2 -O --cfg rtopt                                       	\
    -C linker=arm-linux-gnueabihf-g++ -C ar=arm-linux-gnueabihf-ar 				                 	\
    -C target-feature=+vfp2,-neon  -C target-cpu=arm1176jzf-s 					  			\
    --cfg debug -C prefer-dynamic --target=arm-unknown-linux-gnueabihf                                            	\
    -o x86_64-unknown-linux-gnu/stage2/lib/rustlib/arm-unknown-linux-gnueabihf/bin/rustdoc --cfg rustdoc          	\
    $PWD/../src/driver/driver.rs

echo "-------------------------------"
echo "Package"
echo "-------------------------------"
cd $HOME/toolchains/src/rust/build/
mkdir -p cross-dist/lib/rustlib/arm-unknown-linux-gnueabihf
cd cross-dist
cp -R ../x86_64-unknown-linux-gnu/stage2/lib/rustlib/arm-unknown-linux-gnueabihf/* \
    lib/rustlib/arm-unknown-linux-gnueabihf
mv lib/rustlib/arm-unknown-linux-gnueabihf/bin .
cd lib
for i in rustlib/arm-unknown-linux-gnueabihf/lib/*.so; do ln -s $i .; done
cd ../
tar cjf ../rust_arm-unknown-linux-gnueabihf_dist.tbz2 .

Oh, last point, please consider watching a good movie or going outside, it takes a while to compile :)

Comments are closed.