Skip to content

Compilation

Ondřej Perutka edited this page Apr 21, 2020 · 14 revisions

Arrow Client compilation is currently supported on Linux systems for majority of x86, x86_64, ARM and MIPS CPUs. Compilation for x86 and x86_64 is really straightforward and can be done directly on a particular machine. ARM and MIPS binaries can be compiled either directly or using a cross-compiler.

Note that we support only GNU and MUSL C libraries, uClibc is not supported. In order to use the Arrow Client on old systems based on uClibc, you can build a binary statically linked to MUSL (see below for more info).

Direct compilation

  1. Install Rust.
  2. Install dependencies.
  3. Build the Arrow Client.

Installing Rust

Download and install Rust build environment (in case you do not already have one) and make sure it is up to date. Follow the instructions at:

https://www.rust-lang.org/install.html

Installing dependencies

In order to build the Arrow Client, you need to install a development package for OpenSSL and optionally a development package for libpcap (if you want to use the network scanning feature). The exact method of installing these packages depends on your Linux distribution. Here you can see examples for Ubuntu and Fedora:

Ubuntu:

sudo apt update
sudo apt install libssl-dev libpcap-dev

Fedora:

sudo dnf install openssl-devel libpcap-devel

Building the Arrow Client

Clone this repository:

git clone https://github.com/angelcam/arrow-client.git arrow-client

Enter the directory:

cd arrow-client

And build the Arrow Client. Use the following command to build the Arrow Client without the network scanning feature:

cargo build --release

or this command to build the Arrow Client with the network scanning feature:

cargo build --release --features discovery

You will find the resulting binary in the target/release/ subdirectory. Run the application with no arguments to see its usage.

Optionally, you can strip all the symbols from the binary to make it smaller:

strip target/release/arrow-client

Cross-compilation

If your target system does not have enough resources to host the whole build process or you cannot use direct compilation for some reason, you will need to cross-compile the Arrow Client. There are two ways how to cross-compile the Arrow Client. You can either build a statically-linked binary or a dynamically-linked one.

We recommend building dynamically linked binaries unless your build target is not supported by Rust. Follow this link to see the list of all targets supported by Rust. If your target is not supported but your CPU is, you can link the Arrow Client statically with MUSL.

For example, let's say we need to build the Arrow Client for the arm-unknown-linux-uclibc target. The target is quite common for small devices with older systems but it is not supported by Rust. Fortunately, there is a similar build target - arm-unknown-linux-musleabi which is supported. We can use this fact and link our binary statically with MUSL. This way, we can build the Arrow Client for the arm-unknown-linux-musleabi Rust target using our old uClibc based toolchain. The resulting binary will have its own C library included and there will be no dynamic dependencies.

The same technique can be used for all arm-unknown-linux-* and mips(el)-unknown-linux-* build targets. See the "building a statically-linked binary" section below for more info.

Building a dynamically-linked binary

Please note that this is the preferred way. Do not build statically-linked binaries unless you have a good reason for doing that.

In order to build the Arrow Client, you will need a cross-compilation toolchain for your device and OpenSSL and optionally libpcap libraries for the target system (including development files). The libpcap library is only needed if you want to build the Arrow Client with the network scanning feature.

Unfortunately, getting the toolchain is very device specific and it is beyond the scope of this guide. Similarly, we cannot cover all possible ways of getting OpenSSL and libpcap libraries. You can either use libraries shipped with your target system or compile your own version.

For simplicity, we will focus here on building the Arrow Client for Raspberry Pi. You can modify these steps quite easily for other devices. Please note that there is also a detailed guide focused on building the Arrow Client for OpenWrt.

In order to build the Arrow Client for Raspberry Pi, follow these steps:

  1. Install Rust.
  2. Get a cross-compilation toolchain for Raspberry Pi.
  3. Get OpenSSL and libpcap libraries for Raspberry Pi.
  4. Build the Arrow Client.

Installing Rust

Download and install Rust build environment (in case you do not already have one) and make sure it is up to date. Follow the instructions at:

https://www.rust-lang.org/install.html

Once you have Rust installed, add arm-unknown-linux-gnueabihf Rust target using rustup:

rustup target add arm-unknown-linux-gnueabihf

Getting a cross-compilation toolchain for Raspberry Pi

You can download a cross-compilation toolchain for Raspberry Pi from here:

https://github.com/raspberrypi/tools

Simply type:

git clone https://github.com/raspberrypi/tools.git pi-tools

and add the toolchain to your PATH:

export PATH=`pwd`/pi-tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin:$PATH

Getting OpenSSL and libpcap libraries for Raspberry Pi

Install libssl-dev and libpcap-dev packages into your Raspberry Pi:

sudo apt update
sudo apt install libssl-dev libpcap-dev

and copy the following files from your RPi:

/usr/lib/arm-linux-gnueabihf/libssl.*
/usr/lib/arm-linux-gnueabihf/libcrypto.*
/usr/lib/arm-linux-gnueabihf/libpcap.*

to the following directory of your cross-compilation toolchain:

pi-tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/arm-linux-gnueabihf/lib/

Similarly, you will need to copy the following directory from your RPi:

/usr/include/openssl

to the following directory of your cross-compilation toolchain:

pi-tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/arm-linux-gnueabihf/include/

Building the Arrow Client

Clone this repository:

git clone https://github.com/angelcam/arrow-client.git arrow-client

Enter the directory:

cd arrow-client

Tell cargo what is the name of your cross linker and ar by adding the following lines into your .cargo/config:

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

Tell Rust the name of your cross C compiler for building C dependencies:

export CC_arm_unknown_linux_gnueabihf=arm-linux-gnueabihf-gcc

And finally build the Arrow Client. Use the following command to build the Arrow Client without the network scanning feature:

cargo build --release --target arm-unknown-linux-gnueabihf

or this command to build the Arrow Client with the network scanning feature:

cargo build --release --features discovery --target arm-unknown-linux-gnueabihf

You will find the resulting binary in the target/arm-unknown-linux-gnueabihf/release/ subdirectory. Put the binary into your device and run the application with no arguments to see its usage.

Optionally, you can strip all the symbols from the binary to make it smaller:

arm-linux-gnueabihf-strip target/arm-unknown-linux-gnueabihf/release/arrow-client

Building a statically-linked binary

Static linking of Rust binaries is quite complex topic and explaining the whole process would be pointless here. Luckily, we have automated the whole thing into a few simple steps. You will still need a cross-compilation toolchain for your device but that is pretty much everything you will need. Again, getting the toolchain is beyond the scope of this guide.

For simplicity, we will focus here on building a statically-linked Arrow Client using a cross-compilation toolchain for Raspberry Pi. You can modify these steps easily for other toolchains. The resulting binary will be usable in pretty much all Linux systems for ARM CPUs with hardware support for floating point operations. If you need to build a soft-float binary, you will need to use a different toolchain.

In order to build a statically-linked Arrow Client, follow these steps:

  1. Install Rust.
  2. Get a cross-compilation toolchain for Raspberry Pi.
  3. Build the Arrow Client.

Installing Rust

Download and install Rust build environment (in case you do not already have one) and make sure it is up to date. Follow the instructions at:

https://www.rust-lang.org/install.html

Once you have Rust installed, add arm-unknown-linux-musleabihf Rust target using rustup:

rustup target add arm-unknown-linux-musleabihf

Getting a cross-compilation toolchain for Raspberry Pi

You can download a cross-compilation toolchain for Raspberry Pi from here:

https://github.com/raspberrypi/tools

Simply type:

git clone https://github.com/raspberrypi/tools.git pi-tools

and add the toolchain to your PATH:

export PATH=`pwd`/pi-tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin:$PATH

Building the Arrow Client

Clone this repository:

git clone https://github.com/angelcam/arrow-client.git arrow-client

Enter the directory:

cd arrow-client

Modify the second section of build-static.sh to look like this:

BUILD_HOST=x86_64-unknown-linux-gnu

RUST_TARGET=arm-unknown-linux-musleabihf

OPENSSL_TARGET=linux-armv4

KERNEL_HEADERS_ARCH=arm

# change this to 0 if you do not need the network scanning feature
FEATURE_DISCOVERY=1

TOOLCHAIN_PREFIX=arm-linux-gnueabihf-
TOOLCHAIN_DIR=$SELF_DIR/../pi-tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64

and run the script:

bash build-static.sh

The script will download the MUSL, OpenSSL and libpcap libraries, build them, build the Arrow Client and link everything together. The script will also strip the resulting binary of all symbols to make it smaller. You will find the resulting binary in the target/arm-unknown-linux-musleabihf/release/ subdirectory. Put the binary into your device and run the application with no arguments to see its usage.

Please note that the resulting binary will be much bigger than a dynamically-linked one because it will contain also all the libraries.