Compiling Rust programs for Synology DS418j
Tags: synology, rust, tutorial
Published: 2021-04-20 00:00:00

---
title: "Compiling Rust programs for Synology DS418j"
date: "2021-04-20"
categories: ["synology", "ds418j", "rust"]
---

Rust is a great tool because it allows compiling native code.
This means you do not need to have a runtime installed on a target machine,
but it does mean that you need to compile the program targeted for the hardware
you expect it to run on ahead of time.
Given the strength of not needing a runtime, I wanted to use
Rust to compile some small executables for my Synology DS418j.

## Determining the Target

Rust has a good set of tools already to cross compile programs for a number of platforms.
Assuming that you use `rustup` command (which is the recommended way), the default target
installed when you install Rust is the one that matches your platform. You can see a list
of already built targets by running `rustup target list`.

The first step towards figuring out what I needed to target was determining the architecture that my NAS is running. I have the DS418j, which I know
is one that doesn't have one of the fancy Intel processors, and is likely a cheaper ARM processor.
After ssh'ing into the machine I was able to get this info by running `uname -a` on the NAS to get the following output:

```
Linux potabo 4.4.59+ #25556 SMP Thu Mar 4 17:52:53 CST 2021 aarch64 GNU/Linux synology_rtd1296_ds418j
```

The notable piece of information for me was the `aarch64`.

Looking at the list of targets available from `rustup`, the one
that most closely matches is `aarch64-unknown-linux-gnu`.
The breakdown of these targets is `<architecture>-<vendor>-<system>-<abi>`.

## Compiling a Project

If you don't already have a project to compile then running `cargo new <executable name>` will scaffold out the folder for you.

### Installing toolchain dependencies

We need to install some dependencies first in order to compile.

First, we need to get the base rust crates to compile our project against. This is done with `rustup`:

```
$ rustup target add aarch64-unknown-linux-gnu
```

This installs the crates into your dev environment allowing you to use this as a target across any project.

Second, we'll need to install the `gcc` tools to be able to have a linker that will link our binaries to the ones we expect to be on the target system. The real simple way to do this is installing all gcc-aarch64 tools with the following:

```
$ sudo apt-get install gcc-aarch64*
```

Now, the environment is all prepped.

### Configuring the project

The Rust project still needs a bit more information in order to find the right linker to use for the given target.
This is done through a cargo config file.
From the root of the Rust project you can create a `.cargo` folder, and a `config` file within it.

In the config file the following block needs to be added to tell cargo to use the specified linker when compiling for the given target:

```
[target.aarch64-unknown-linux-gnu]
linker = "aarch64-linux-gnu-gcc"
```

### Compiling!

Finally, the project is ready to compile

```
$ cargo build --target=aarch64-unknown-linux-gnu
```

After building you can copy the created binary from the `target/aarch64-unknown-linux-gnu/debug` folder to the target machine and run it to verify it works!