Packaging private rust libraries

Hi there, I’m hoping someone can help with this issue, I can’t seem to find any solution.

I’m trying to use nix build and flakes to build a rust package (in this case I’m trying to cross-compile as well) but I’m running into a wall where the package Cargo.toml pulls in a private library (libhelper) I wrote that is in a different directory.

The directory tree is as such:

root
libhelper
Cargo.toml
Cargo.lock
src/
myproject
Cargo.toml
Cargo.lock
src/
flake.nix
default.nix

And I’m running nix build inside of the myproject directory.

The error I’m getting is:

error: builder for '/nix/store/cdxv3gbprzy97zfvzizn02bwv28cak5s-myproject-deps-0.1.0.drv' failed with exit code 101;
       last 10 log lines:
       >   failed to load source for dependency `libhelper`
       >
       > Caused by:
       >   Unable to update /private/tmp/nix-build-myproject-deps-0.1.0.drv-0/libhelper
       >
       > Caused by:
       >   failed to read `/private/tmp/nix-build-myproject-deps-0.1.0.drv-0/libhelper/Cargo.toml`
       >
       > Caused by:
       >   No such file or directory (os error 2)
       For full logs, run 'nix log /nix/store/cdxv3gbprzy97zfvzizn02bwv28cak5s-myproject-deps-0.1.0.drv'.
error: 1 dependencies of derivation '/nix/store/fym38gzpxmkynrhdifl6wyvddpmsqdnd-myproject-0.1.0.drv' failed to build

I’m using the following flake.nix

{
  inputs = {
    nixpkgs.url = "nixpkgs/nixos-unstable";
    rust-overlay.url = "github:oxalica/rust-overlay";
  };

  outputs = {
    self,
    nixpkgs,
    rust-overlay,
  }: let
    system = "aarch64-darwin";
    overlays = [(import rust-overlay)];
    pkgs = import nixpkgs {
      inherit overlays system;
      crossSystem = {
        config = "x86_64-unknown-linux-musl";
        rustc.config = "x86_64-unknown-linux-musl";
        isStatic = true;
      };
    };
  in {
    packages.${system} = {
      default = self.outputs.packages.${system}.x86_64-linux-musl-example;
      x86_64-linux-musl-example = pkgs.callPackage ./. {};
    };
  };
}

And the associated default.nix

{rustPlatform}:
rustPlatform.buildRustPackage {
  name = "myproject";
  src = ./.;
  cargoLock.lockFile = ./Cargo.lock;
}

Forgot to git-add, probably

I’ve managed to solve the issue for anyone else trying this.

I couldn’t figure out a way to do it how I preferred but you can do it by creating a cargo workspace where your flake.nix would then sit.

The new directly tree would be like this:

workspace

  • Cargo.toml (workspace toml)
  • flake.nix
  • default.nix
  • myproject
    • Cargo.toml
  • libhelper
    • Cargo.toml

Everything then seemed to work.
The working flake and default are:

flake.nix

{
  inputs = {
    nixpkgs.url = "nixpkgs/nixos-unstable";
    rust-overlay.url = "github:oxalica/rust-overlay";
  };

  outputs = {
    self,
    nixpkgs,
    rust-overlay,
  }: let
    system = "x86_64-linux";
    overlays = [(import rust-overlay)];
    pkgs = import nixpkgs {
      inherit overlays system;
      crossSystem = {
        config = "x86_64-unknown-linux-musl";
        rustc.config = "x86_64-unknown-linux-musl";
        isStatic = true;
      };
    };
  in {
    packages.${system} = {
      default = self.outputs.packages.${system}.x86_64-linux-musl-example;
      x86_64-linux-musl-example = pkgs.callPackage ./. {};
    };
  };
}

(note I couldn’t get this to work on mac yet due to openssl issues)

default.nix

{rustPlatform, pkgs}:
rustPlatform.buildRustPackage {
  name = "workspace";
  src = ./.;
  cargoLock.lockFile = ./Cargo.lock;
  buildInputs = with pkgs; [
    openssl
  ];

  nativeBuildInputs = with pkgs; [ pkg-config ];

}