rust-std
library relies on glibc
for things like syscalls
and other low-level stuff, in order to cross-compile a Rust binary, one needs the appropriate C toolchain to be present as well. And this is where crosstool-NG comes into play.
crosstool-NG
is in the toolchain building business. You’re going to use it to build yourself a toolchain for linking against ARMv7-compatible glibc
, which will in turn allow you to successfully build your Rust binary for the Pi.
- Clone the repo to a good location and bootstrap it:
cd /Users/USER
git clone https://github.com/crosstool-ng/crosstool-ng
cd crosstool-ng
./bootstrap
- Configure the installation and run it. To set where the tool goes on install, run:
./configure --prefix=$PWD
make
make install
export PATH="${PATH}:${PWD}/bin"
If all things went as expected, you should be able to run ct-ng version
and verify the tool’s ready to go.
- Configure the tool to build your
ARMv7 toolchain
. Luckily, crosstool-NG comes with some preset configurations, namely armv7-rpi2-linux-gnueabihf
. Run:
ct-ng armv7-rpi2-linux-gnueabihf
There should be some output indicating that it’s now configured for armv7-rpi2-linux-gnueabihf
. You just need to tell ct-ng where the toolchain ought to go:
mkdir /Users/USER/ct-ng-toolchains
cd /Users/USER/ct-ng-toolchains
ct-ng menuconfig
It can be overwhelming, as there are a ton of options, but stick to the Paths and misc options ---> menu option
. Highlight it and hit Enter.
Under *** crosstool-NG behavior ***
, scroll down until you see this long string:
(${CT_PREFIX:-${HOME}/x-tools}/${CT_HOST:+HOST-${CT_HOST}/}${CT_TARGET}) Prefix directory
- Hit Enter, delete the contents, and replace it with /Users/USER/ct-ng-toolchains
.
- When you’re finished, hit Enter to confirm, scroll over and save, and then exit the configurator.
- Build your toolchain (this may take half an hour):
ct-ng build
If it worked successfully, You should see a great many binaries now in /Users/USER/ct-ng-toolchains/armv7-rpi2-linux-gnueabihf/bin
, namely armv7-rpi2-linux-gnueabihf-gcc
.
For cargo to build using your new cross-compiler, you must:
- Add the bin folder listed above to your PATH:
export PATH="${PATH}:/Users/USER/ct-ng-toolchains/armv7-rpi2-linux-gnueabihf/bin"
- Update (or create) your global
/Users/USER/.cargo/config
file with (you can avoid this and use it in local .cargo/config
):
[target.armv7-unknown-linux-gnueabihf]
linker = "armv7-rpi2-linux-gnueabihf-gcc"
3.Return to your Rust project and rerun cargo build:
cd /Users/USER/rust/hello
cargo build --target=armv7-unknown-linux-gnueabihf
- The output should be something similar to:
Compiling hello v0.1.0 (file:///Users/USER/rust/hello)
Finished dev [unoptimized + debuginfo] target(s) in 0.85 secs
- SCP your file over to the RPi and run the binary remotely:
scp target/armv7-unknown-linux-gnueabihf/debug/hello pi@192.168.1.43:
ssh pi@192.168.3.155 'chmod +x ~/hello && ~/hello'
Hello, world!
Credit goes to Kappel Codes I tried to summarize it here, as I found this question hours before I get that article :)