Pandora How to cross-compile Rust programs


ssokolow

Member
Joined
May 24, 2012
Messages
245
Location
Ontario, Canada
Since it took a bit of googling to piece together how to set up a Pandora-targeting Rust cross-compiler, I thought I'd share these instructions here in case they save someone else some time.

Step 0: Set up one of the C cross-compilers from https://pandorawiki.org/Cross-compiler (I'm using Sebt3's Yactfeau)
...

Step 1: Set up Rust to cross-compile for the LLVM-style triple which matches the GCC-style one used in the compiler from step 0
Code:
rustup target add arm-unknown-linux-gnueabi

# Optional: Also add Pandora support to the nightly toolchain (see release.sh)
rustup target add --toolchain nightly arm-unknown-linux-gnueabi

Step 2: Amend ~/.cargo/config to point at the compiler from step 0 for the final link against libc
Code:
[target.arm-unknown-linux-gnueabi]
linker = "/home/ssokolow/opt/pandora-dev/arm-2011.09/bin/pandora-gcc"

Step 3: Test your results by opening up a Rust project without complex native dependencies and asking cargo to cross-compile it
Code:
cd ~/src/rip_media
cargo build --release --target=arm-unknown-linux-gnueabi

Step 4: Confirm that you got an ARM binary and test it on your Pandora
Code:
file target/arm-unknown-linux-gnueabi/release/rip_media
scp target/arm-unknown-linux-gnueabi/release/rip_media 192.168.0.8:/home/ssokolow/
ssh 192.168.0.8 ./rip_media

NOTE: While I tested this, I actually use a slightly more involved release.sh to crunch the output down more. I've included it below in case anyone's interested.

Code:
#!/bin/sh
# Definitions for setting target platform
#--------------------------------------------------------------------------------
# 32-bit x86 with static libc
#TARGET=i686-unknown-linux-musl
#STRIP=strip
#--------------------------------------------------------------------------------
# OpenPandora
TARGET=arm-unknown-linux-gnueabi
STRIP=/home/ssokolow/opt/pandora-dev/arm-2011.09/bin/pandora-strip
#--------------------------------------------------------------------------------

TARGET_PATH="target/$TARGET/release/rip_media"
CHANNEL=stable
FEATURES=""
STRIP_FLAGS="--strip-unneeded"
export UPX="--ultra-brute"

# If --nightly, use opt-level=z and alloc_system to cut 115K from the final output
if [ "$1" = "--nightly" ]; then
    CHANNEL=nightly
    FEATURES="$FEATURES --features=nightly"

    # TODO: Find a less hacky way to do this
    cleanup() {
        sed -i 's/opt-level = "z"/opt-level = 3/' Cargo.toml
    }
    trap cleanup EXIT
    sed -i 's/opt-level = 3/opt-level = "z"/' Cargo.toml
fi

# Always delete and rebuild (since stripping a UPXd executable is fatal)
rm "$TARGET_PATH"
# shellcheck disable=SC2086
rustup run "$CHANNEL" cargo build --release --target="$TARGET" $FEATURES

# Crunch down the resulting output using strip, sstrip, and upx
"$STRIP" $STRIP_FLAGS "$TARGET_PATH"
sstrip "$TARGET_PATH"  # from ELFkickers
upx "$TARGET_PATH"

# Display the result
ls -lh "$TARGET_PATH"

(One of these days, I need to refresh my memory of the more complex GNU make language constructs.)
 
Last edited:
Nice.
You should put it on the wiki if you have the will to do it ;^) .
 
The current structure of the Wiki seems to be based on the assumption that languages not included in GCC don't need cross-compilation and I'm not sure how to go about changing things without making them worse. (eg. The cross-compilation page currently sorts its sections from most to least recommended, but adding Rust to an ordered list of C/C++ compilation options is like comparing apples and oranges on how good a pie filling they'll make.)
 
Back
Top