Nixops cross-building Packages

While implementing a nix pkg for the traccar server (https://www.traccar.org/) I came across the following problem.
The traccar web frontend depends on a binary only package, which is already included in nixpkgs (pkgs/applications/networking/instant-messengers/rambox/sencha).
The sencha package is only needed at build time of the web frontend.
The problem is, the web frontend package is deployed to a raspberry pi via nixops but sencha is only available for x86.
I’m sure there is some way to have the web frontend be built on an x86 machine and then copied to the pi.
The machine I run nixops on is an x86 one.
For reference, here is the web frontend package:

{ callPackage, stdenv, fetchFromGitHub, tree }:
let
  extjs = fetchFromGitHub {
    owner = "bjornharrtell";
    repo = "extjs";
    rev = "f0bce4cc246dbcf69990893b7cf92aa3fca55fd6";
    sha256 = "00n8amwdk2cz59vr289q3jm50ryxn5ij4q0j7s7x70r2nkmmbrbd";
  };
  sencha = callPackage <nixpkgs/pkgs/applications/networking/instant-messengers/rambox/sencha> {};
in
stdenv.mkDerivation rec {
  pname = "traccar-web";
  version = "v4.6";
  src = fetchFromGitHub {
    owner = "traccar";
    repo = "traccar-web";
    rev = version;
    sha256 = "0qw80zgnfrq05r8w1xl56xjpmsgch51a80ixml7czxgjzk638b5a";
  };

  buildInputs = [ sencha ];

  buildPhase = ''
    EXTJS_PATH=${extjs} tools/minify.sh
  '';

  installPhase = ''
    mkdir -p $out/
    cp -r web/* $out/
  '';
}

Here is the error from nixops:


nixops deploy                             
building all machine configurations...
error: Package ‘sencha-bare-6.6.0.13’ in ...nixpkgs/pkgs/applications/networking/instant-messengers/rambox/sencha/bare.nix:18 is not supported on ‘aarch64-linux’, refusing to evaluate.

I’m not confident, but based on this blog post by Matthew Bauer and the usage instructions in the nixpkgs manual section on cross-compiling I was at least able to get past that error message.

First, I cloned nixpkgs, then saved the package file you wrote in as pkgs/servers/traccar-web/default.nix. I also added the line traccar-web = callPackage ../servers/traccar-web { }; to /pkgs/top-level/all-packages.nix. This allowed it to build on my x86 machine by running the following command:

$ export NIXPKGS_ALLOW_UNFREE=1; nix-build -A traccar-web

I still get a failed build when cross compiling, but by changing buildInputs = [ sencha ]; to nativeBuildInputs = [ sencha ] on line 21 it no longer seems to care that sencha is not supported on arm. I used the following command to kick off the build:

$ export NIXPKGS_ALLOW_UNFREE=1; nix-build --arg crossSystem '(import <nixpkgs/lib>).systems.examples.aarch64-multiplatform' -A traccar-web

As far as I understand, buildInputs is for dependencies that might be needed at build time, but primarily for run-time dependencies. nativeBuildInputs are build time dependencies, and explicitly not guaranteed to be available at run time. By declaring sencha as a nativeBuildInput nix is able to understand that as long as it is supported on the build machine, it can ignore lack of support on the target. Honestly, though, dependencies in nix are still too complex for me to have a solid grasp of and I could be mistaken on what is going on here.

In the end, I still have a failing build due to an error thrown in the compilation of /nix/store/lqjkj6dc17xbvaclamd12b454q6iimnl-glibc-2.27-aarch64-unknown-linux-gnu.drv, but I hope this gets you a little closer to solving your problem.

If it’s just needed at build time, then change this to nativeBuildInputs = [ sencha ];. If it’s needed at runtime, then remove it as a build dependency and you will need to wrap the program similar to https://github.com/NixOS/nixpkgs/blob/a52195355312d2a9f5e71d4ff742bcc30c6f90ec/pkgs/servers/zookeeper/default.nix#L25

this would be something to the tune of

  wrapProgram $out/bin/server \
    --prefix PATH : "${sencha}/bin/sencha"
1 Like