Cross compile Rust to FreeBSD using Nix


24 December 2025

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}"
          ];
        };
      }
    );
}