Here’s a quick example of a flake.nix that sets up an environment suitable to cross-compile Rust from a Linux host to a FreeBSD target.
The example project uses Tokio and around 100 dependencies overall, but it likely requires additional work to support building
against and linking to arbitrary C libraries.
This was tested on a x86_64 Linux host. The target triple is x86_64-unknown-freebsd. The flake.nix builds a dev shell with:
- clang cross compiler
- FreeBSD 15.0 sysroot
See below for rust-toolchain.toml and flake.nix. With these files in place, and a Cargo.toml and some Rust source.
For the example, I’m using the
static-files example from Poem.
With that in place, the following should work:
$ nix develop
[nix]$ cargo build --target=x86_64-unknown-freebsd
[nix]$ file target/x86_64-unknown-freebsd/debug/example-static-files
target/x86_64-unknown-freebsd/debug/example-static-files:
ELF 64-bit LSB pie executable, x86-64, version 1 (FreeBSD),
dynamically linked, interpreter /libexec/ld-elf.so.1,
for FreeBSD 15.0 (1500068), FreeBSD-style,
with debug_info, not stripped
The binary can be copied and launched from an x86_64 FreeBSD system.
See this nixos wiki for additional ideas.
# rust-toolchain.toml
[toolchain]
channel = "stable"# flake.nix
{
description = "Rust development environment to cross-compile host linux to target freebsd";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
flake-utils.url = "github:numtide/flake-utils";
};
outputs = { self, nixpkgs, flake-utils }:
flake-utils.lib.eachDefaultSystem (system:
let
pkgs = nixpkgs.legacyPackages.${system};
pkgsCross = pkgs.pkgsCross.x86_64-freebsd;
overrides = (builtins.fromTOML (builtins.readFile (self + "/rust-toolchain.toml")));
target = "x86_64-unknown-freebsd";
sysroot = pkgs.fetchzip {
url = "https://download.freebsd.org/releases/amd64/15.0-RELEASE/base.txz";
hash = "sha256-OLnHge+hTwjvMNTiChI7YWOhkFUJKj2WQ33SaCa7h4E=";
stripRoot = false;
};
in
{
devShells.default = pkgs.mkShell rec {
nativeBuildInputs = [
pkgs.pkg-config
pkgsCross.clang
pkgsCross.cargo
];
RUSTC_VERSION = overrides.toolchain.channel;
shellHook = ''
export PATH=$PATH:''${CARGO_HOME:-~/.cargo}/bin
'';
RUSTFLAGS = [
"-Clinker=clang"
"-Clink-arg=--target=${target}"
"-Clink-arg=--sysroot=${sysroot}"
];
};
}
);
}