Creating my first package (i3-gnome) in NixOS

Hello, hope you have had a great weekend.

I am trying to create a derivation for a package that is really important for me GitHub - i3-gnome/i3-gnome: Use i3wm/i3-gaps with GNOME Session infrastructure.. I have attempted to create a first attempt with the following derivation:

with import <nixpkgs> {};

stdenv.mkDerivation {
  name = "i3-gnome";
  version = "3.36.0";
  src = fetchFromGitHub {
    owner = "i3-gnome";
    repo = "i3-gnome";
    rev = "3.36.0";
    sha256 = "04hq9r4j2sm2blxd3w7sd82n9camb1m0jzhq8fgwszr192c2yg9b";
  };
  system = builtins.currentSystem;
  buildInputs = [gnome3.gnome-flashback i3-gaps gnome3.gnome-settings-daemon];
}

However when I try to do nix build I get the following error from make.

install -m0644 -D session/i3-gnome-xsession.desktop //usr/share/xsessions/i3-gnome.desktop
install: cannot create directory '//usr': Permission denied

What I am missing that makes me create the correct build?

And will this be enough to have everything ready as in other linux distro?

Thank you very much in advance

Hi @Guisanpea, try to add this:

  makeFlags = [
    "DESTDIR=${placeholder "out"}"
  ];

Hi @Guisanpea, how did you integrate this derivation such that you could launch i3-gnome? I’m curious to try it, but am n00b enough with Nix that I’m just stalled out.

@brogos Please do not use DESTDIR with Nix, set PREFIX instead. See also Do not set DESTDIR in makeFlags · Issue #65718 · NixOS/nixpkgs · GitHub

@tftio I think it might be sufficient to add the i3-gnome command:

services.xserver.desktopManager.gnome3.enable = true;
services.xserver.desktopManager.gnome3.flashback = {
  customSessions = [
    {
      wmName = "i3-gnome";
      wmLabel = "i3-gnome";
      wmCommand = "${pkgs.i3-gnome}/bin/i3-gnome";
    };
  ];
};

But the package above is likely incomplete and some wrapping/patching of paths might be needed.

Awesome. Now, I guess my question is, how do I integrate the derivation that @Guisanpea created into my nixos configuration?

Do I assign the whole mkDerivation part to a variable and then reference that var (i3-gnome or whatever)?

Yeah, that would work. Though it might be more convenient to import it from a separate file so that you could easily build the package for checking out the output.

I would also try just adding pure i3 to customSessions first. That might be good enough and much simpler. Or if that does not work, using the following as wmCommand:

# Taken from https://github.com/i3-gnome/i3-gnome/blob/663a67041b5c3c71f5709e2edab15ef465a9d954/session/i3-gnome
pkgs.writeScript "i3-gnome" ''
  export PATH=${lib.makeBinPath [ pkgs.dbus pkgs.i3 ]}
  # Register with gnome-session so that it does not kill the whole session thinking it is dead.
  test -n "$DESKTOP_AUTOSTART_ID" && {
      dbus-send --print-reply --session --dest=org.gnome.SessionManager "/org/gnome/SessionManager" org.gnome.SessionManager.RegisterClient "string:i3-gnome" "string:$DESKTOP_AUTOSTART_ID"
  }

  i3

  # Logout process.
  test -n "$DESKTOP_AUTOSTART_ID" && {
    dbus-send --print-reply --session --dest=org.gnome.SessionManager "/org/gnome/SessionManager" org.gnome.SessionManager.Logout "uint32:1"
  }
'';

Hello!

Sorry for the late responses. I got some problems with GPU (big navi) and had to stop using NixOS but now Im back and ready to get to the next level with Nix.

After the thread I have tried to get everything up and running with the following items.

  1. I have created the derivation for i3-gnome in /etc/nixos/packages/i3-gnome.nix
{ stdenv, fetchFromGitHub, gnome3, i3-gaps }:

stdenv.mkDerivation {
  pname = "i3-gnome";
  version = "3.36.0";
  src = fetchFromGitHub {
    owner = "i3-gnome";
    repo = "i3-gnome";
    rev = "3.36.0";
    sha256 = "04hq9r4j2sm2blxd3w7sd82n9camb1m0jzhq8fgwszr192c2yg9b";
  };

  installFlags = [ "PREFIX=$(out)" ];

  system = builtins.currentSystem;
  buildInputs = [gnome3.gnome-flashback i3-gaps gnome3.gnome-settings-daemon];
}
  1. I have added the package to my list of installed packages
  environment = {
    systemPackages = with pkgs; [
      neovim wget git nodejs
      (callPackage ./packages/i3-gnome.nix { })
    ];
    variables.EDITOR = "nvim";
  };
  1. I have added it to the flashback section
  services.xserver = {
    enable = true;
    displayManager.gdm.enable = true;
    desktopManager = {
      gnome3.enable = true;
      gnome3.flashback = {
        customSessions = [
          {
            wmName = "i3-gnome";
            wmLabel = "i3-gnome";
            wmCommand = "${pkgs.i3-gnome}/bin/i3-gnome";
          }
        ];
      };
    };
  };

Nevertheless when I try to build it I have the following error:

[nixie@nixos:/etc/nixos]$ sudo nixos-rebuild switch
building Nix...
building the system configuration...
error: attribute 'i3-gnome' missing, at /etc/nixos/configuration.nix:57:28
(use '--show-trace' to show detailed location information)

Being 57:28 the line which wmCommand has.

I got a bit lost in the conversation so I dont know if this was all that was missing.

Thanks a lot for your support @jtojnar

I think the problem is that you are using pkgs.i3-gnome, which means "use i3-gnome from the package set (usually nixpkgs), whereas you installed directly your package in systemPackages without registering the i3-gnome package in the package set (using an overlay).

So multiple solutions:

The quickest, create a variable:

let 
  i3-gnome = pkgs.callPackage./packages/i3-gnome.nix { };
in
{
  ...
  environment.systemPackages = with pkgs; [
    ...
    i3-gnome
  ];
  ...
    wmCommand = "${i3-gnome}/bin/i3-gnome";
}

or inject the callPackage call in an overlay:

{
  ...
  nixpkgs.overlays = [
    (self: super: {
      i3-gnome = super.callPackage ./packages/i3-gnome.nix {};
    })
  ];
}
2 Likes

Ah, this is great. Sadly, I’m now on unstable (because I like pain?) and I’m getting failures because gnome-flashback is trying to copy a non-existent file (a systemd target).