Skip to content

Compilation for OpenWrt

Ondřej Perutka edited this page May 30, 2018 · 1 revision

The Arrow Client can be quite easily compiled for huge variety of devices running OpenWrt. This guide will help you with setting up your build environment for building Arrow Client for your device.

Setting up Rust

The first thing you need is Rust compiler. Detailed instructions on installing Rust can be found here or you can just use this command:

curl https://sh.rustup.rs -sSf | sh

After installing Rust, you will also need Rust libraries for the target architecture (i.e. your device). The list of targets supported by Rust can be found here. If you're not sure which target is correct, you can figure it out from OpenWrt SDK package for your device (see below). For simplicity, let's assume we're building Arrow Client for mipsel-unknown-linux-musl, you'll need to modify all the commands and variables mentioned here to match your target.

Use this command to install Rust libraries for our target:

rustup target add mipsel-unknown-linux-musl

Setting up OpenWrt SDK

The Rust compiler is ready but we still need a linker and some libraries for the target architecture. We'll need an OpenWrt SDK for the target device. Look up your device in the list of supported devices and find information about CPU type of your device from the corresponding device page. For example, device page for Nexx WT3020H says it's RAMIPS MT7620. OpenWrt SDK and system images for this device can be found here. For now, we'll just need the SDK:

# Replace the link here with a link to OpenWrt SDK for your device
wget https://downloads.openwrt.org/releases/17.01.4/targets/ramips/mt7620/lede-sdk-17.01.4-ramips-mt7620_gcc-5.4.0_musl-1.1.16.Linux-x86_64.tar.xz

Unpack the SDK:

tar xf lede-sdk-17.01.4-ramips-mt7620_gcc-5.4.0_musl-1.1.16.Linux-x86_64.tar.xz

If you didn't know which Rust target to install, look into the toolchain bin directory of your SDK. For example:

ls -l lede-sdk-17.01.4-ramips-mt7620_gcc-5.4.0_musl-1.1.16.Linux-x86_64/staging_dir/toolchain-mipsel_24kc_gcc-5.4.0_musl-1.1.16/bin

You'll find many build tools prefixed with target you're looking for. For example mipsel-openwrt-linux-musl-gcc. The target is mipsel-openwrt-linux-musl which can be translated as mipsel-unknown-linux-musl.


We have the SDK for our device, so let's build the libraries that we'll need for the Arrow Client. We need to install and build libopenssl and libpcap packages in our SDK:

cd lede-sdk-17.01.4-ramips-mt7620_gcc-5.4.0_musl-1.1.16.Linux-x86_64

# Update the package feeds (it's similar to apt update)
scripts/feeds update

# Install the packages
scripts/feeds install libopenssl
scripts/feeds install libpcap

# Build the packages
make

When you hit make, you'll see a Linux Kernel Configuration window. Enter the Global build settings section and disable the option for cryptographically signing package lists. We don't need it as we're not going to create a public package repository. Save the changes and exit the configuration manager.

Building Arrow Client

Our build environment is almost ready, we just need to tell Rust which linker and archiver to use and set up a few environment variables. Create .cargo/config in your build root (i.e. the directory with your copy of Arrow Client) with the following content:

# Change the target and the names of the tools accordingly to match your target
[target.mipsel-unknown-linux-musl]
ar = "mipsel-openwrt-linux-musl-ar"
linker = "mipsel-openwrt-linux-musl-gcc"

Finally, set the environment variables:

WORK_DIR=`pwd`

# This variable is required by the OpenWrt SDK tools
export STAGING_DIR=$WORK_DIR/lede-sdk-17.01.4-ramips-mt7620_gcc-5.4.0_musl-1.1.16.Linux-x86_64/staging_dir

TOOLCHAIN_DIR=$STAGING_DIR/toolchain-mipsel_24kc_gcc-5.4.0_musl-1.1.16
TARGET_DIR=$STAGING_DIR/target-mipsel_24kc_musl-1.1.16

# These two variables are required by the Rust OpenSSL wrapper
export OPENSSL_LIB_DIR=$TARGET_DIR/usr/lib
export OPENSSL_INCLUDE_DIR=$TARGET_DIR/usr/include

# Make sure the toolchain is in PATH
export PATH=$TOOLCHAIN_DIR/bin:$PATH

# Tell Rust build scripts which C compiler should be used for building their C dependencies. Modify this variable to match your target.
export CC_mipsel_unknown_linux_musl=mipsel-openwrt-linux-musl-gcc

and build the Arrow Clinet:

# Change the target accordingly
cargo build --target=mipsel-unknown-linux-musl --features discovery --release

You'll find the resulting binary in the target/mipsel-unknown-linux-musl/release directory. If the binary is too large for your device, you can strip symbols from it using:

# Change the command to match your target
mipsel-openwrt-linux-musl-strip target/mipsel-unknown-linux-musl/release/arrow-client