[UPD 2021-02-22] Cross compilation for Raspberry Pi

[EDIT]

Hi there !

Thanks to the advices of @dirvine, I’ve finally managed to have something working, from the sources to the Raspberry Pi. Unfortunately…it is the “hello test”, not sn_node…yet :wink:
Here are the steps :

Update your environment :

sudo apt update
sudo apt install curl git binutils-arm-linux-gnueabihf gcc-arm-linux-gnueabihf

Install Rust :

curl --proto ‘=https’ --tlsv1.2 -sSf https://sh.rustup.rs | sh
source ~/.cargo/env

Get the right ARM version of your Pi :
On your Pi:

uname -m

ex: armv6l (old version of Raspberry Pi)

Choose the right target for ARM compilation :
for arm < 7 :

rustup target add arm-unknown-linux-musleabihf

for armv7 :

rustup target add armv7-unknown-linux-musleabihf

Set Cargo configuration :
for arm < 7 :

cat >> ~/.cargo/config <<EOF
[target.arm-unknown-linux-musleabihf]
linker = “arm-linux-gnueabihf-gcc”
EOF

for armv7 :

cat >> ~/.cargo/config <<EOF
[target.armv7-unknown-linux-musleabihf]
linker = “arm-linux-gnueabihf-gcc”
EOF

Test your environment:

cargo new --bin hello
cd hello

for arm < 7 :

cargo build --target=arm-unknown-linux-musleabihf

for armv7 :

cargo build --target=armv7-unknown-linux-musleabihf

Check the result :

file target/arm*-unknown-linux-musleabihf/debug/hello
target/arm-unknown-linux-musleabihf/debug/hello: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked, BuildID[sha1]=d9e1117d104e7e73497dca40dbb1cf75348bf558, with debug_info, not stripped

Once the environment is OK, let’s work on sn_node !
Download the sources:

git clone https://github.com/maidsafe/sn_node.git

Build :

cd sn_node

for arm < 7 :

CC=arm-linux-gnueabihf-gcc cargo build --release --target=arm-unknown-linux-musleabihf

for armv7 :

CC=arm-linux-gnueabihf-gcc cargo build --release --target=armv7-unknown-linux-musleabihf

In case of failure…
…watch for the next release :slight_smile:

Strip your binary (optional)

arm-linux-gnueabihf-strip target/arm*-unknown-linux-musleabihf/release/sn_node

9 Likes

There is a community PR that fixes this, couple small issues but will be merged soon.

I would perhaps use the musl target, but that’s me I prefer to not rely on local libc.

For Pi it’s best to build on a desktop, here’s a couple of tips if you are on Linux (in your env there)

sudo apt install gcc-arm-linux-gnueabihf This is the arm linker
then add

[target.armv7-unknown-linux-gnueabihf]
linker = "arm-linux-gnueabihf-gcc"

to your cargo.config

There are a few good articles around (check how recent though this is a fast moving / improving issue. I would search for compiling rust for pi and setup your desktop/laptop to cross compile.

As I say the error you see should be fixed just as we merge the PR.

11 Likes

I haven’t tried these for a while, but if you’d like to check them out and report back that would be handy, and if they need updating a PR world be welcome.

Includes a script to build on Raspbian:

5 Likes

Hello! I’m dipping a toe … SAFE pi build using github SafeNetwork CLI instructions.

Whole new learning curve but all good. I’ve noticed what I think is an error & am looking to feedback. I appreciate builds are ongoing so may not be of value but ask if/where feedback should be posted?
For the moment I’ll state here but happy to move.

Build Step: $ cargo build

Terminal Error:
bash: export: /home/pi/.cargo/env’: not a valid identifier`

Checking :

sudo nano /home/pi/.bashr

Shows: invalid directory (does not exist)

/clisource

Correct line should I think read:

export PATH=$PATH:/home/pi/.safe/cli:"$HOME/.cargo/env"

Which is 2 changes:

  1. /cli

  2. replacing space with ‘:’

https://askubuntu.com/questions/529919/how-to-fix-not-a-valid-identifier-error-after-setting-environment-variables

Iain

3 Likes

Hi @felixmc
on your .bashrc, you should have
export PATH=$PATH:/home/pi/.safe/cli
but then you have to source the cargo env file like this :
source /home/pi/.cargo/env
OR
you complete the PATH update with the content of this env file :
export PATH=$PATH:/home/pi/.safe/cli:/home/pi/.cargo/bin

Hope this help !

4 Likes

Yep, that worked, thanks @Aragorn

5 Likes

Hi @happybeing
PR is served :slight_smile:

5 Likes

Super thank you.

3 Likes

Starting feel like we are getting traction in many areas now. Something is in the air! Maybe just a feeling, but this does feel like a lot of things are facing the same way here. Anyhow :muscle: all round.

9 Likes

Hi !

The error I was talking about in my (edited) initial post :

error: failed to run custom build command for ring v0.16.20

Caused by:
process didn’t exit successfully: /home/richard/safenet/sn_node/target/release/build/ring-f50be9e32fe54896/build-script-build (exit code: 101)
— stdout
OPT_LEVEL = Some(“3”)
TARGET = Some(“arm-unknown-linux-musleabihf”)
HOST = Some(“x86_64-unknown-linux-gnu”)
CC_arm-unknown-linux-musleabihf = None
CC_arm_unknown_linux_musleabihf = None
TARGET_CC = None
CC = None
CROSS_COMPILE = None
CFLAGS_arm-unknown-linux-musleabihf = None
CFLAGS_arm_unknown_linux_musleabihf = None
TARGET_CFLAGS = None
CFLAGS = None
CRATE_CC_NO_DEFAULTS = None
DEBUG = Some(“false”)
CARGO_CFG_TARGET_FEATURE = None

— stderr
running “arm-linux-musleabihf-gcc” “-O3” “-ffunction-sections” “-fdata-sections” “-fPIC” “-march=armv6” “-marm” “-mfpu=vfp” “-I” “include” “-Wall” “-Wextra” “-pedantic” “-pedantic-errors” “-Wall” “-Wextra” “-Wcast-align” “-Wcast-qual” “-Wconversion” “-Wenum-compare” “-Wfloat-equal” “-Wformat=2” “-Winline” “-Winvalid-pch” “-Wmissing-field-initializers” “-Wmissing-include-dirs” “-Wredundant-decls” “-Wshadow” “-Wsign-compare” “-Wsign-conversion” “-Wundef” “-Wuninitialized” “-Wwrite-strings” “-fno-strict-aliasing” “-fvisibility=hidden” “-fstack-protector” “-g3” “-U_FORTIFY_SOURCE” “-DNDEBUG” “-c” “-o/home/richard/safenet/sn_node/target/arm-unknown-linux-musleabihf/release/build/ring-08857c92ac2e7894/out/aesv8-armx-linux32.o” “/home/richard/.cargo/registry/src/github.com-1ecc6299db9ec823/ring-0.16.20/pregenerated/aesv8-armx-linux32.S”
thread ‘main’ panicked at ‘failed to execute [“arm-linux-musleabihf-gcc” “-O3” “-ffunction-sections” “-fdata-sections” “-fPIC” “-march=armv6” “-marm” “-mfpu=vfp” “-I” “include” “-Wall” “-Wextra” “-pedantic” “-pedantic-errors” “-Wall” “-Wextra” “-Wcast-align” “-Wcast-qual” “-Wconversion” “-Wenum-compare” “-Wfloat-equal” “-Wformat=2” “-Winline” “-Winvalid-pch” “-Wmissing-field-initializers” “-Wmissing-include-dirs” “-Wredundant-decls” “-Wshadow” “-Wsign-compare” “-Wsign-conversion” “-Wundef” “-Wuninitialized” “-Wwrite-strings” “-fno-strict-aliasing” “-fvisibility=hidden” “-fstack-protector” “-g3” “-U_FORTIFY_SOURCE” “-DNDEBUG” “-c” “-o/home/richard/safenet/sn_node/target/arm-unknown-linux-musleabihf/release/build/ring-08857c92ac2e7894/out/aesv8-armx-linux32.o” “/home/richard/.cargo/registry/src/github.com-1ecc6299db9ec823/ring-0.16.20/pregenerated/aesv8-armx-linux32.S”]: No such file or directory (os error 2)’, /home/richard/.cargo/registry/src/github.com-1ecc6299db9ec823/ring-0.16.20/build.rs:653:9

Actually, this error is known, for another architecture, but quite similar :

Fixed :
CC=arm-linux-gnueabihf-gcc cargo build …

A quick update on cross-compilation for Raspberry Pi 4 w/ Ubuntu 64 Bits (https://ubuntu.com/tutorials/how-to-install-ubuntu-on-your-raspberry-pi#1-overview)

Tested on Ubuntu 20.10 (host)

On the host, update the environment and install the packages :

sudo apt update
sudo apt install curl git build-essential binutils-aarch64-linux-gnu gcc-aarch64-linux-gnu

Install Rust :

curl --proto ‘=https’ --tlsv1.2 -sSf https://sh.rustup.rs | sh
source ~/.cargo/env

Add the target aarch64 (64 bits) musl (statically-linked libraries) for rustup toolchain :

rustup target add aarch64-unknown-linux-musl

Set cargo configuration :

cat >> ~/.cargo/config <<EOF
[target.aarch64-unknown-linux-musl]
linker = "aarch64-linux-gnu-gcc"
rustflags = [ "-C", "target-feature=+crt-static", "-C", "link-arg=-lgcc" ]
EOF

Download the sources and build :

git clone https://github.com/maidsafe/sn_node.git
cd sn_node
CC=aarch64-linux-gnu-gcc cargo build --release –target=aarch64-unknown-linux-musl
aarch64-linux-gnu-strip target/aarch64-unknown-linux-musl/release/sn_node

On you Pi, create the folders :

sudo mkdir -p /opt/safenet/node/bin
sudo mkdir -p /opt/safenet/node/var/{log,data}
chown -R <YOU> /opt/safenet/node/bin

From your host, copy the binary :

scp target/aarch64-unknown-linux-musl/release/sn_node <YOU>@<PI>:/opt/safenet/node/bin

On you Pi, launch the node with the given IP and PORT (soon :slight_smile: )

sudo chroot /opt/safenet/node /bin/sn_node -vvvv --idle-timeout-msec 5500 --keep-alive-interval-msec 4000 --hard-coded-contacts [\"<IP>:<PORT>\"] --root-dir /var/data --log-dir /var/log &

And watch the process :

tail -f /opt/safenet/node/var/log/sn_node.log

8 Likes

Last year I did a little hobby project using sensors on the Raspberry Pi. I came across the excellent Rust Embedded cross project. With cross installed and Docker started:

$ git clone https://github.com/maidsafe/sn_node.git
$ cd sn_node && cross build --release --target=aarch64-unknown-linux-musl
10 Likes

just for the record - 2 raspis ready to rumble here

this was amazingly simple - just a

$ cargo install cross

and your two lines and i had a readily built arm64 binary :slight_smile: Awesome!

7 Likes

Done in QP2P ! :tada:
We should be able to cross-compile for the older Raspberry Pi in the next version of the node ! :smiley:

10 Likes