Setting up a new Rust Target with a cross compiler

In this Blog post I'll be showing you how to setup a new rust target on a platform that requires GCC to link binaries. specifically making a illumos ARM target

This instructions are can be simplified by providing a precompiled libstd and libc as target. But for now it outlines the process needed to get a standard rust compiler to compile undefined illumos and arch combinations like sparcv9-unknown-illumos aarch64-unknown-illumos and riscv64-unknown-illumos 

Note: if your crate needs an external C Library you will have to fiddle with it a bit to properly set the include and cross build directives that crate supports.

  1. Get Rustup via the normal channels (goto copy and paste OSX instructions)
  2. Install Nightly toolchain rustup toolchain add nightly
  3. print an already existing illumos rustc target and adjust to the target CPU rustc +nightly -Z unstable-options --target=aarch64-unknown-freebsd --print target-spec-json 
  4. check other OS’s spec files for that CPU to see what is OS specific (most) and what is CPU specific
  5. use to adjust data-layout key according to platform. all other OS’s should use the same layout on that cou architecture if not they are at least equally bugged
  6. Set llvm-target to <arch>-unknown-solaris2.11 where arch is the same as used in the arch key in the json
  7. put any linker flags that are system independant in pre-link-args  like -std=c99
  8. Setup Cross compile capable GCC plus LD and illumos gate sysroot as usual (Checkout solarm-sysroot for packaging details)
  9. Use a path from to write either user specific cargo overrides or system based ones. (basically override the linker on the desired arch in .cargo/config.toml in the desired location)
  10. Patch the dependency tree to use fixed libc crate from
  11. run cargo update -p libc after that to update Cargo.lock
  12. export OPENSSL_DIR to point to sysroot if needed (basically if your package links to openssl)
  13. Use this invocation to compile your crate cargo +nightly build -Z build-std --target=/path/to/aarch64-unknown-illumos.json

Example files:


  "arch": "aarch64",
  "data-layout": "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128",
  "dynamic-linking": true,
  "eh-frame-header": false,
  "frame-pointer": "always",
  "has-rpath": true,
  "is-like-solaris": true,
  "late-link-args": {
    "gcc": [
  "limit-rdylib-exports": false,
  "linker-is-gnu": false,
  "llvm-target": "aarch64-unknown-solaris2.11",
  "max-atomic-width": 128,
  "os": "illumos",
  "pre-link-args": {
    "gcc": [
  "supported-sanitizers": [
  "target-family": [
  "target-pointer-width": "64"

cross compile cargo config for gcc with custom sysroot

#target-dir = "/export/home/vagrant/.cargo/target" # Set this to instruct cargo to place the compile artifacts into the specified directory (usefull for NFS mounted directories)

linker = "/opt/solarm/bin/aarch64-unknown-solaris2.11-gcc" # Path of the gcc binary to use as linker (calls our LD in the background but $LD cannot be set)
rustflags = "-Clink-arg=--sysroot=/opt/solarm/braich" # Any linker args that are usually set in $LDFLAGS go here