Adjusting a derivation for inclusion in nixpkgs (touchegg)

Hello!
I have recently been trying to create/update a derivation for the application called touchegg (see here).

I am almost ready to submit a PR to nixpkgs, but I have a couple of questions. This is what I have right now: (EDITED)

pkgs:
with pkgs;

stdenv.mkDerivation rec {
  name = "touchegg";
  pname = "${name}";
  version = "2.0.8.1";
  src = fetchFromGitHub {
    owner = "JoseExposito";
    repo = "${name}";
    rev = "f6c64bbd6d00564a980bf4379dcc1178de294c85";
    sha256 = "1v1sskyxmvbc6j4l31zbabiklfmy2pm77bn0z0baj1dl3wy7xcj2";
  };

  PKG_CONFIG_SYSTEMD_SYSTEMDSYSTEMUNITDIR = "${placeholder "out"}/lib/systemd/system";

  buildInputs = [
    systemd
    libinput
    pugixml
    cairo
    xorg.libX11
    xorg.libXtst
    xorg.libXrandr
    xorg.libXi
    xorg.libXdmcp
    xorg.libpthreadstubs
    xorg.libxcb
    gtk3-x11
    pcre
  ];

  nativeBuildInputs = [ pkg-config cmake ];
 }

Question 1: I am a bit confused about the parameters.
The expression above works when I call it like touchegg = import ./touchegg.nix pkgs; in my configuration.nix. The current touchegg nixpkg has the following parameter:

{ lib, stdenv, fetchurl, xorg, xorgserver, qt4, libGLU, libGL, geis, qmake4Hook }:

What should the paramaters be in my case? Maybe something like this?

{ pkgs, stdenv, fetchFromGitHub, ... }:

Question 2: With parameters like above, how can I build the package with nix-build then? How should I call it from my configuration? I have seen most packages in nixpkgs use parameters like those, so how can I generally build packages from nixpkgs with nix-build or from inside my configutaion?

Question 3: Since this package is primarily used as a service, I would also like to include a service in in the PR. I have tried to also make expression for a service here, does this look about right?

{config, lib, pkgs, ...}:

with lib;

let 
  cfg = config.services.touchegg;
  touchegg = import ./touchegg.nix pkgs; # my local derivation, the one in the top
in {
  options.services.touchegg = {
    enable = mkEnableOption "Whether to enable touchegg.";
  };

  config = mkIf cfg.enable {
    systemd.services.touchegg = {
      description = "Touchégg Daemon";
      documentation = [ "https://github.com/JoseExposito/touchegg/tree/master/installation#readme" ];
      wantedBy = [ "multi-user.target" ];
      serviceConfig = {
        Type = "simple";
        Group = "input";
        ExecStart = "${touchegg}/bin/touchegg --daemon";
        Restart = "on-failure";
        RestartSec = "5s";
      };
    };
    environment.systemPackages = [ touchegg ];
  };
}

Thanks for any help!

Not the answer to any of your questions, but ideally you should split inputs between nativeBuildInputs (things which need to run at compile time, such as cmake and pkg-config, but aren’t required by the resultant packages) and buildInputs (things which are required at runtime, most of the other packages). It’s possible for it to work without the nativeBuildInputs / buildInputs split, but it is important if it is to be possible to cross-compile the package. Also, is gcc explicitly required for some reason? If it’s just there to compile it, stdenv.mkDerivation brings its own toolchain with it.

That is a very good point, thank you! I edited my post.

When nixpkgs computes the package definition, it calls callPackage, which somehow pulls the relevant attributes from pkgs and provides them as inputs, so your inputs would be closer to what is there at the moment, with your changes:

{stdenv, fetchFromGitHub, systemd, libinput, ..., xorg}:

Right, and you can use pkgs.callPackage ./touchegg.nix {} instead of import ./touchegg.nix pkgs in your configuration.nix.

And you can also use nix-build -E "with import <nixpkgs> {}; callPackage ./path/to/touchegg.nix {}" to build the package.

Instead of systemd.services.touchegg, you can just add the package to systemd.packages option in your configuration.nix and that will use the service file from the package and enable it.

@afontaine, @jtojnar okay great, callPackage works its magic. Thanks for the tips. I have updated it like so

{ stdenv, fetchFromGitHub, systemd, 
libinput, pugixml, cairo, xorg, gtk3-x11, pcre, pkg-config, cmake }:

@jtojnar I was using the systemd.packages in my personal config, but did not realise it could work as a service. I tried giving it a shot, but systemctl status touchegg.service reported it as being inactive and only worked after systemctl start touchegg.service. Maybe I missed something.

{config, lib, pkgs, ...}:

with lib;
let 
  cfg = config.services.touchegg;
  touchegg = pkgs.callPackage ./touchegg.nix {}; # my local derivation
in {
  options.services.touchegg = {
    enable = mkEnableOption "Whether to enable touchegg.";
  };
  config = mkIf cfg.enable {
    environment.systemPackages = [ touchegg ];
    systemd.packages = [ touchegg ];
  };
}

Thank you all.

1 Like