Need help packaing FUTO's Grayjay desktop app

Hi! I’m a nix-noob and I need some help packaging the Grayjay desktop app FUTO recently released (in preview/early version).

You can find the download link for the application here: Grayjay App - Follow Creators Not Platforms

This is where I got so far:

  1. I’m running NixOS 24.11
  2. I created a “grayjay” folder with two files in there: grayjay.nix and default.nix (see contents below)
  3. I seem to be able to successfully build the package with nix-build -A grayjay as I get no errors and there is a “result” hardlink to the nix-store.
  4. I tried to install the package with a (pkgs.callPackage ../grayjay/grayjay.nix {}) line in my configuration.nix, but it fails with an error:
Could not start dynamically linked executable: ./result/bin/grayjay/Grayjay
NixOS cannot run dynamically linked executables intended for generic
linux environments out of the box. For more information, see:
https://nix.dev/permalink/stub-ld

I’m pretty sure I’m doing something wrong in the installPhase, as it seems from the zip file contents that this is a “CEF” (chromium embedded framework) based application. I was not able to find any directions on how to install/package such an application on nix.

Any pointers are greatly appreciated! Once I get this working (and cleanup and optimized) I want to publish the package to the nixos packages repo.

grayjay.nix

{
  stdenv,
  fetchzip,
  ffmpeg,
}:
stdenv.mkDerivation {
  pname = "Grayjay";
  version = "2";

  src = fetchzip {
    url = "https://updater.grayjay.app/Apps/Grayjay.Desktop/Grayjay.Desktop-linux-x64.zip";
    sha256 = "UqTDpPtl6kNg/4y3+HsQI+YBQ0vjvvm37xiYY90+gzw=";
  };

  buildInputs = [ffmpeg];

  doCheck = false;

  installPhase = ''
    ls -a
    mkdir -p $out/bin/grayjay
    install ./Grayjay $out/bin/grayjay
    chmod a+x $out/bin/grayjay
    runHook postInstall
  '';

  meta = {
    description = "Follow Creators, Not Platforms";
    homepage = "https://grayjay.app/";
    #license = licenses.unfree;
    #maintainers = with maintainers; [running-grass];
    platforms = ["x86_64-linux"];
  };
}

default.nix

# default.nix
let
  nixpkgs = fetchTarball "https://github.com/NixOS/nixpkgs/tarball/nixos-24.11";

  pkgs = import nixpkgs {
    config = {};
    overlays = [];
  };
in {
  grayjay = pkgs.callPackage ./grayjay.nix {};
}

You’re basically just asking nix to extract a zip file with pre-built binaries in it. The problem with this is exactly as your dynamic linker says:

NixOS cannot run dynamically linked executables intended for generic linux environments out of the box. For more information, see: Frequently Asked Questions — nix.dev documentation

If you open that link, it tells you how to solve it, even in order of preference. We can attempt building it from source first, for that you’d need to replace your current URL with a URL pointing to the source code, and then figure out the upstream build.

There’s not really a one-size-fits-all solution to building most software, so just knowing it uses CEF as a library isn’t very useful. Best thing to do is to check if they have build instructions, and if not, to sniff around the repo. Looks like they have a custom build script: Grayjay.Desktop/build.sh at 373cd8448cb0ede78a0a1f8a0cf25ca7666f56d4 · futo-org/Grayjay.Desktop · GitHub

That will likely be a very complex package. It uses npm and dotnet, both in somewhat nonstandard ways, so you’re going to have to figure out how to resolve dependencies with two different package managers. The npm project is vite-based, too, which adds yet another level of package manager hell.

Difficult, but doable, and worthwhile if you want to upstream this.

If you don’t want to put the effort in, though, you can also just rebundle the binary in an fhs env. They actually have a snippet for that in their repo: GitHub - futo-org/Grayjay.Desktop: Grayjay.Desktop Mirror

As an aside, if you rewrite your default.nix a little you can avoid evaluating two nixpkgs instances for no reason, and actually have it be reproducible and not rebuild every 2 hours:

# default.nix
{ pkgs ? import <nixpkgs> { }, ... }: {
  grayjay = pkgs.callPackage ./grayjay.nix {};
}
1 Like

Looks like there are some packaging efforts here.

The app itself does not currently make it easy to package because of some directory writability(is that a word? It is now) assumptions it makes.

2 Likes

In that case, this comment has a nice fully fledged fhs env you can just use: Package request: Grayjay Desktop · Issue #366543 · NixOS/nixpkgs · GitHub

Thank you so much! @TLATER thank you for the explanation! Also for the guidance on rewriting my default.nix. @VTimofeenko I’m going to join the efforts in the topic you linked.

I have the latest version of it in a flake: quasigod/nur - Codeberg.org

It’s built from source and doesn’t need an FHS env now. I’ll upstream it once some PRs are merged to fix the things I’m patching.

1 Like