I found that when attempting to build a complex Python application where itself and its dependencies uses matplotlib, it is possible to get this problem:
Found duplicated packages in closure for dependency 'matplotlib':
matplotlib 2.1.2 (/nix/store/38fz59rmqxq1l43y0k2v40d36vv6hr5w-python3.6-matplotlib-2.1.2/lib/python3.6/site-packages)
matplotlib 2.1.2 (/nix/store/bcrnikk3vfsl7vxzgvhjnlw7rlc72kkj-python3.6-matplotlib-2.1.2/lib/python3.6/site-packages)
Package duplicates found in closure, see above. Usually this happens if two packages depend on different version of the same dependency.
The main reason is when you use:
matplotlib.override { enableQt = true; }
In your propagatedBuildInputs.
The problem is that your dependencies may rely on the default pkgs.matplotlib, whereas your top level package may actually expect to use the qt backend.
I found that the solution to this was to create an override at the nixpkgs level:
let
pkgs = (import <nixpkgs>) {
config = {
packageOverrides = pkgs: {
python36 = pkgs.python36.override {
packageOverrides = self: super: {
matplotlib = super.matplotlib.override { enableQt = true; };
};
};
};
};
};
in
with pkgs;
From there, every subsequent expression will reuse the same pkgs, and all packages will be using the overridden matplotlib.
My question here is, is this way that's expected to work? Is there no better way to do this? It seems overly verbose to achieve this. Furthermore, this requires you to have the nixpkgs function, instead of the pkgs attribute. I could not find a way to override the pkgs attribute instead of passing it as a the config attribute to the nixpkgs function.
I found that when attempting to build a complex Python application where itself and its dependencies uses matplotlib, it is possible to get this problem:
The main reason is when you use:
In your
propagatedBuildInputs.The problem is that your dependencies may rely on the default
pkgs.matplotlib, whereas your top level package may actually expect to use theqtbackend.I found that the solution to this was to create an override at the
nixpkgslevel:From there, every subsequent expression will reuse the same
pkgs, and all packages will be using the overridden matplotlib.My question here is, is this way that's expected to work? Is there no better way to do this? It seems overly verbose to achieve this. Furthermore, this requires you to have the
nixpkgsfunction, instead of thepkgsattribute. I could not find a way to override thepkgsattribute instead of passing it as a theconfigattribute to thenixpkgsfunction.