I’m trying to get OpenCV in python to show a GUI. I have a default.nix that I invoke with nix-shell:
with import <nixpkgs> {};
(let
foo="bar";
in
stdenv.mkDerivation {
name = "impurePythonEnv";
buildInputs = [
(python37.buildEnv.override {
extraLibs = [
pkgs.python37Packages.matplotlib
pkgs.python37Packages.numpy
pkgs.python37Packages.scipy
pkgs.python37Packages.gnureadline
pkgs.python37Packages.opencv4
];
ignoreCollisions = true;
})
];
shellHook = ''
# set SOURCE_DATE_EPOCH so that we can use python wheels
SOURCE_DATE_EPOCH=$(date +%s)
export LANG=en_US.UTF-8
'';
})
Unfortunately this doesn’t work:
Traceback (most recent call last):
File "test_webcam.py", line 18, in <module>
cv.imshow('frame', gray)
cv2.error: OpenCV(4.1.2) /build/source/modules/highgui/src/window.cpp:651: error: (-2:Unspecified error) The function is not implemented. Rebuild the library with Windows, GTK+ 2.x or Cocoa support. If you are on Ubuntu or Debian, install libgtk2.0-dev and pkg-config, then re-run cmake or configure script in function 'cvShowImage'
I’m trying to marshall the information in this:
into my default.nix above, but I don’t really have enough of a feel for nix-the-language for this to work. Could anyone help me please?
You are defining new python variable but you still use non-overridden python37 and pkgs.python37Packages in the derivation. Try replacing them with python and python.pkgs, respectively.
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.