[solved] Build OpenCV with gtk and python

If anyone comes here in search for how to spawn a nix-shell with opencv-python and GTK (UI) enabled (like I did), the simple solution is:

{ pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
  name = "opencv-python-gtk";
  buildInputs = with pkgs; [
    (python311.withPackages (ps: with ps; [
      (ps.opencv4.override {
        enableGtk3 = true;
      })
  ];
}

It will take some time to build depending on your hardware.

While we are here, if you plan to use mediapipe (not packaged for Nix yet), then you’ll need the following:

{ pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
  name = "opencv-python-gtk";
  buildInputs = with pkgs; [
    (python311.withPackages (ps: with ps; [
      (ps.opencv4.override {
        enableGtk3 = true;
    })

    zlib
    libGL
    glib
  ];

  LD_LIBRARY_PATH = "${pin.pkgs.zlib}/lib:${pin.pkgs.stdenv.cc.cc.lib}/lib:${pin.pkgs.libGL}/lib:${pin.pkgs.glib.out}/lib:/run/opengl-driver/lib";
}

Finally, since opencv will be rebuilt everytime you update your channels, you can pin it as follows:

{}:

let
  pin = rec {
    commit = "72c6ed328aa4e5d9151b1a512f6ad83aca7529fa"; # nixos-unstable @ 2023-03-28
    pkgsSrc = builtins.fetchTarball {
      url = "https://github.com/NixOS/nixpkgs/archive/${commit}.tar.gz";
      # Set to empty and wait for the error to tell you the right one
      sha256 = "1fzrqm29n6iq1c998ym5ijsj5x3z1l07qkc4xb48y9c22bl8cn11";
    };
    pkgs = import pkgsSrc {};
  };

in

pin.pkgs.mkShell {
  name = "opencv-python-gtk";
  buildInputs = with pin.pkgs; [
    (python311.withPackages (ps: with ps; [
      (ps.opencv4.override {
        enableGtk3 = true;
    })

    zlib
    libGL
    glib
  ];

  LD_LIBRARY_PATH = "${pin.pkgs.zlib}/lib:${pin.pkgs.stdenv.cc.cc.lib}/lib:${pin.pkgs.libGL}/lib:${pin.pkgs.glib.out}/lib:/run/opengl-driver/lib";
}

This way your opencv will built only once until you explicitly will want to upgrade.

1 Like