1{ lib
2, stdenv
3, fetchPypi
4, writeText
5, buildPythonPackage
6, pythonOlder
7
8# https://github.com/matplotlib/matplotlib/blob/main/doc/devel/dependencies.rst
9# build-system
10, pkg-config
11, pybind11
12, setuptools
13, setuptools-scm
14
15# native libraries
16, ffmpeg-headless
17, fontconfig
18, freetype
19, imagemagick
20, qhull
21
22# propagates
23, contourpy
24, cycler
25, fonttools
26, kiwisolver
27, numpy
28, packaging
29, pillow
30, pyparsing
31, python-dateutil
32
33# optional
34, importlib-resources
35
36# GTK3
37, enableGtk3 ? false
38, cairo
39, gobject-introspection
40, gtk3
41, pycairo
42, pygobject3
43
44# Tk
45, enableTk ? !stdenv.isDarwin # darwin has its own "MacOSX" backend
46, tcl
47, tk
48, tkinter
49
50# Ghostscript
51, enableGhostscript ? true
52, ghostscript
53
54# Qt
55, enableQt ? false
56, pyqt5
57
58# Webagg
59, enableWebagg ? false
60, tornado
61
62# nbagg
63, enableNbagg ? false
64, ipykernel
65
66# darwin
67, Cocoa
68
69# required for headless detection
70, libX11
71, wayland
72}:
73
74let
75 interactive = enableTk || enableGtk3 || enableQt;
76in
77
78buildPythonPackage rec {
79 version = "3.7.0";
80 pname = "matplotlib";
81 format = "pyproject";
82
83 disabled = pythonOlder "3.8";
84
85 src = fetchPypi {
86 inherit pname version;
87 hash = "sha256-j279MTQw1+9wo4oydigcsuhkazois7IesifaIOFeaBM=";
88 };
89
90 env.XDG_RUNTIME_DIR = "/tmp";
91
92 # Matplotlib tries to find Tcl/Tk by opening a Tk window and asking the
93 # corresponding interpreter object for its library paths. This fails if
94 # `$DISPLAY` is not set. The fallback option assumes that Tcl/Tk are both
95 # installed under the same path which is not true in Nix.
96 # With the following patch we just hard-code these paths into the install
97 # script.
98 postPatch =
99 let
100 tcl_tk_cache = ''"${tk}/lib", "${tcl}/lib", "${lib.strings.substring 0 3 tk.version}"'';
101 in
102 lib.optionalString enableTk ''
103 sed -i '/self.tcl_tk_cache = None/s|None|${tcl_tk_cache}|' setupext.py
104 '' + lib.optionalString (stdenv.isLinux && interactive) ''
105 # fix paths to libraries in dlopen calls (headless detection)
106 substituteInPlace src/_c_internal_utils.c \
107 --replace libX11.so.6 ${libX11}/lib/libX11.so.6 \
108 --replace libwayland-client.so.0 ${wayland}/lib/libwayland-client.so.0
109 '' +
110 # bring our own system libraries
111 # https://github.com/matplotlib/matplotlib/blob/main/doc/devel/dependencies.rst#c-libraries
112 ''
113 echo "[libs]
114 system_freetype=true
115 system_qhull=true" > mplsetup.cfg
116 '';
117
118 nativeBuildInputs = [
119 pkg-config
120 pybind11
121 setuptools-scm
122 ];
123
124 buildInputs = [
125 ffmpeg-headless
126 freetype
127 qhull
128 ] ++ lib.optionals enableGhostscript [
129 ghostscript
130 ] ++ lib.optionals enableGtk3 [
131 cairo
132 gobject-introspection
133 gtk3
134 ] ++ lib.optionals enableTk [
135 libX11
136 tcl
137 tk
138 ] ++ lib.optionals stdenv.isDarwin [
139 Cocoa
140 ];
141
142 # clang-11: error: argument unused during compilation: '-fno-strict-overflow' [-Werror,-Wunused-command-line-argument]
143 hardeningDisable = lib.optionals stdenv.isDarwin [
144 "strictoverflow"
145 ];
146
147 propagatedBuildInputs = [
148 # explicit
149 contourpy
150 cycler
151 fonttools
152 kiwisolver
153 numpy
154 packaging
155 pillow
156 pyparsing
157 python-dateutil
158 ] ++ lib.optionals (pythonOlder "3.10") [
159 importlib-resources
160 ] ++ lib.optionals enableGtk3 [
161 pycairo
162 pygobject3
163 ] ++ lib.optionals enableQt [
164 pyqt5
165 ] ++ lib.optionals enableWebagg [
166 tornado
167 ] ++ lib.optionals enableNbagg [
168 ipykernel
169 ] ++ lib.optionals enableTk [
170 tkinter
171 ];
172
173 passthru.config = {
174 directories = { basedirlist = "."; };
175 libs = {
176 system_freetype = true;
177 system_qhull = true;
178 } // lib.optionalAttrs stdenv.isDarwin {
179 # LTO not working in darwin stdenv, see #19312
180 enable_lto = false;
181 };
182 };
183
184 env.MPLSETUPCFG = writeText "mplsetup.cfg" (lib.generators.toINI {} passthru.config);
185
186 # Matplotlib needs to be built against a specific version of freetype in
187 # order for all of the tests to pass.
188 doCheck = false;
189
190 meta = with lib; {
191 description = "Python plotting library, making publication quality plots";
192 homepage = "https://matplotlib.org/";
193 changelog = "https://github.com/matplotlib/matplotlib/releases/tag/v${version}";
194 license = with licenses; [ psfl bsd0 ];
195 maintainers = with maintainers; [ lovek323 veprbl ];
196 };
197}