#!/usr/bin/env python3
from mss import mss
with mss() as sct:
sct.shot()
with
let
my-python = python3.withPackages (python-packages:
with python-packages; [
mss
]);
in {
home.packages = with pkgs; [
my-python
];
}
but I’m getting:
[I] ➜ .config/nixpkgs/bin/minimal.py
Traceback (most recent call last):
File ".config/nixpkgs/bin/minimal.py", line 5, in <module>
with mss() as sct:
File "/nix/store/k296zqidarw3fpwz2qlscxkj7v6bcwla-python3-3.8.9-env/lib/python3.8/site-packages/mss/factory.py", line 41, in mss
return linux.MSS(**kwargs)
File "/nix/store/k296zqidarw3fpwz2qlscxkj7v6bcwla-python3-3.8.9-env/lib/python3.8/site-packages/mss/linux.py", line 291, in __init__
raise ScreenShotError("No X11 library found.")
mss.exception.ScreenShotError: No X11 library found.
Tried installing xlib libX11 libraries but it has to be somehow linked in the lib package if I got that right. Copied that package file and tried pasting xorg.libX11 in different *buildInput locations but not really an idea what I am doing.
If someone could give me a pointer would be great.
Thanks
{ lib, buildPythonPackage, fetchPypi, isPy3k, xorg }:
buildPythonPackage rec {
pname = "mss";
version = "6.1.0";
disabled = !isPy3k;
src = fetchPypi {
inherit pname version;
sha256 = "aebd069f3e05667fe9c7b9fa4b1771fe42a4710ce1058ce0236936ce06fa5394";
};
# By default it attempts to build Windows-only functionality
prePatch = ''
rm mss/windows.py
'';
buildInputs = [ xorg.libX11 ];
# Skipping tests due to most relying on DISPLAY being set
pythonImportsCheck = [ "mss" ];
meta = with lib; {
description = "Cross-platform multiple screenshots module in pure Python";
homepage = "https://github.com/BoboTiG/python-mss";
license = licenses.mit;
maintainers = with maintainers; [ austinbutler ];
};
}
Usually this is done at runtime, so your build-time config likely doesn’t matter. Nix will automatically also install build inputs if their files appear in the built binaries, but since python finds your library at runtime this won’t work.
This isn’t true for all python packages though, and often the library resolution is broken in ways that are exposed on NixOS (e.g. because it assumes “Linux” = current Ubuntu LTS and the library is in a specific location with a specific name), so let’s see what this package does.
So, this package uses ctypes.find_library. This is good, since it’s a standard library feature, and in the worst case patched on NixOS. It’s still done at runtime, so we need to make sure the dependency is propagated.
Luckily, this is quite easy, and the python build docs even recommend it somewhere in here (we desperately need to move to readthedocs) - just replace your buildInputs in the package with propagatedBuildInputs
Hi and thank you for your detailed answer. Very much appreciate it.
But unfortunately this also does also not work within propagatedBuildInputs. (though I figured out the difference now
Tried to use it from the python interpreter and found that this:
#!/usr/bin/env python3
import ctypes.util
x11 = ctypes.util.find_library("X11")
if not x11:
print("No X11.")
Needs LD_LIBRARY_PATH to be set correctly:
[I] ➜ .config/nixpkgs/bin/minimal.py
No X11.
[I] ➜ LD_LIBRARY_PATH=/nix/store/7gxlcshan16fym2ay98zmpi9gz7sjkdx-libX11-1.7.0/lib .config/nixpkgs/bin/minimal.py
And then i found out running it like this makes it work:
I’ll then just set this in the script calling it.
But I’m confused.
Where should this be set?
In the lib package? I tried this but didn’t have an effect:
In that case, the way to fix this currently is something like this:
postPatchPhase = ''
sed -i 's|ctypes.util.find_library("X11")|"${xorg.libX11}/lib/libX11.so"|' mss/linux.py
'';
This is a bit horrible
You can also try setting DYLD_LIBRARY_PATH="${lib.makeLibraryPath propagatedBuildInputs}";, but it seems that people on the issue aren’t getting results from that.