about summary refs log tree commit diff
path: root/pkgs/development/python-modules/pyqt/5.x.nix
blob: ed0264c816dd6fc6b95c258c86b48fc11b67e33c (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
{
  lib,
  stdenv,
  buildPythonPackage,
  setuptools,
  isPy27,
  fetchPypi,
  pkg-config,
  dbus,
  lndir,
  dbus-python,
  sip,
  pyqt5-sip,
  pyqt-builder,
  libsForQt5,
  enableVerbose ? true,
  withConnectivity ? false,
  withMultimedia ? false,
  withWebKit ? false,
  withWebSockets ? false,
  withLocation ? false,
  withSerialPort ? false,
  withTools ? false,
  pkgsBuildTarget,
  buildPackages,
  dbusSupport ? !stdenv.isDarwin,
}:

buildPythonPackage rec {
  pname = "pyqt5";
  version = "5.15.9";
  format = "pyproject";

  disabled = isPy27;

  src = fetchPypi {
    pname = "PyQt5";
    inherit version;
    hash = "sha256-3EHoQBqQ3D4raStBG9VJKrVZrieidCTu1L05FVZOxMA=";
  };

  patches = [
    # Fix some wrong assumptions by ./project.py
    # TODO: figure out how to send this upstream
    ./pyqt5-fix-dbus-mainloop-support.patch
    # confirm license when installing via pyqt5-sip
    ./pyqt5-confirm-license.patch
  ];

  postPatch =
    # be more verbose
    ''
      cat >> pyproject.toml <<EOF
    ''
    + lib.optionalString enableVerbose ''
      [tool.sip.project]
      verbose = true
    ''
    # Due to bug in SIP .whl name generation we have to bump minimal macos sdk upto 11.0 for
    # aarch64-darwin. This patch can be removed once SIP will fix it in upstream,
    # see https://github.com/NixOS/nixpkgs/pull/186612#issuecomment-1214635456.
    + lib.optionalString (stdenv.isDarwin && stdenv.isAarch64) ''
      minimum-macos-version = "11.0"
    ''
    + ''
      EOF
    ''

    # pyqt-builder tries to compile *and run* these programs.  This
    # is really sad because the only thing they do is print out a
    # flag based on whether or not some compile-time symbol was
    # defined.  This could all be done without having to *execute*
    # cross-compiled programs!
    #
    # Here is the complete list of things checked:
    #
    # QT_NO_PRINTDIALOG                                                           => PyQt_PrintDialog
    # QT_NO_PRINTER                                                               => PyQt_Printer
    # QT_NO_PRINTPREVIEWDIALOG                                                    => PyQt_PrintPreviewDialog
    # QT_NO_PRINTPREVIEWWIDGET                                                    => PyQt_PrintPreviewWidget
    # QT_NO_SSL                                                                   => PyQt_SSL
    # QT_SHARED || QT_DLL                                                         => shared (otherwise static)
    # QT_NO_PROCESS                                                               => PyQt_Process
    # QT_NO_FPU || Q_PROCESSOR_ARM || Q_OS_WINCE                                  => PyQt_qreal_double
    # sizeof (qreal) != sizeof (double)                                           => PyQt_qreal_double
    # !Q_COMPILER_CONSTEXPR !Q_COMPILER_UNIFORM_INIT                              => PyQt_CONSTEXPR
    # QT_NO_ACCESSIBILITY                                                         => PyQt_Accessibility
    # QT_NO_OPENGL                                                                => PyQt_OpenGL PyQt_Desktop_OpenGL
    # defined(QT_OPENGL_ES) || defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_ES_3) => PyQt_Desktop_OpenGL
    # QT_NO_RAWFONT                                                               => PyQt_RawFont
    # QT_NO_SESSIONMANAGER                                                        => PyQt_SessionManager
    #
    + lib.optionalString (!(stdenv.buildPlatform.canExecute stdenv.hostPlatform)) ''
      rm config-tests/cfgtest_QtCore.cpp
      rm config-tests/cfgtest_QtGui.cpp
      rm config-tests/cfgtest_QtNetwork.cpp
      rm config-tests/cfgtest_QtPrintSupport.cpp
    '';

  enableParallelBuilding = true;
  # HACK: paralellize compilation of make calls within pyqt's setup.py
  # pkgs/stdenv/generic/setup.sh doesn't set this for us because
  # make gets called by python code and not its build phase
  # format=pyproject means the pip-build-hook hook gets used to build this project
  # pkgs/development/interpreters/python/hooks/pip-build-hook.sh
  # does not use the enableParallelBuilding flag
  postUnpack = ''
    export MAKEFLAGS+="''${enableParallelBuilding:+-j$NIX_BUILD_CORES}"
  '';

  # tons of warnings from subpackages, no point in playing whack-a-mole
  env = lib.optionalAttrs (!enableVerbose) { NIX_CFLAGS_COMPILE = "-w"; };

  outputs = [
    "out"
    "dev"
  ];

  dontWrapQtApps = true;

  nativeBuildInputs =
    [ pkg-config ]
    ++ lib.optionals (stdenv.buildPlatform == stdenv.hostPlatform) [ libsForQt5.qmake ]
    ++ [
      setuptools
      lndir
      sip
    ]
    ++ (
      with pkgsBuildTarget.targetPackages.libsForQt5;
      [ ]
      ++ lib.optionals (stdenv.buildPlatform != stdenv.hostPlatform) [ qmake ]
      ++ [
        qtbase
        qtsvg
        qtdeclarative
        qtwebchannel
      ]
      ++ lib.optional withConnectivity qtconnectivity
      ++ lib.optional withMultimedia qtmultimedia
      ++ lib.optional withWebKit qtwebkit
      ++ lib.optional withWebSockets qtwebsockets
      ++ lib.optional withLocation qtlocation
      ++ lib.optional withSerialPort qtserialport
      ++ lib.optional withTools qttools
    );

  buildInputs =
    with libsForQt5;
    [ dbus ]
    ++ lib.optionals (stdenv.buildPlatform == stdenv.hostPlatform) [ qtbase ]
    ++ [
      qtsvg
      qtdeclarative
      pyqt-builder
    ]
    ++ lib.optional withConnectivity qtconnectivity
    ++ lib.optional withWebKit qtwebkit
    ++ lib.optional withWebSockets qtwebsockets
    ++ lib.optional withLocation qtlocation
    ++ lib.optional withSerialPort qtserialport
    ++ lib.optional withTools qttools;

  propagatedBuildInputs = [
    dbus-python
    pyqt5-sip
  ];

  passthru = {
    inherit sip pyqt5-sip;
    multimediaEnabled = withMultimedia;
    webKitEnabled = withWebKit;
    WebSocketsEnabled = withWebSockets;
    connectivityEnabled = withConnectivity;
    locationEnabled = withLocation;
    serialPortEnabled = withSerialPort;
    toolsEnabled = withTools;
  };

  dontConfigure = true;

  # Checked using pythonImportsCheck
  doCheck = false;

  pythonImportsCheck =
    [
      "PyQt5"
      "PyQt5.QtCore"
      "PyQt5.QtQml"
      "PyQt5.QtWidgets"
      "PyQt5.QtGui"
    ]
    ++ lib.optional withWebSockets "PyQt5.QtWebSockets"
    ++ lib.optional withWebKit "PyQt5.QtWebKit"
    ++ lib.optional withMultimedia "PyQt5.QtMultimedia"
    ++ lib.optional withConnectivity "PyQt5.QtBluetooth"
    ++ lib.optional withLocation "PyQt5.QtPositioning"
    ++ lib.optional withSerialPort "PyQt5.QtSerialPort"
    ++ lib.optional withTools "PyQt5.QtDesigner";

  meta = with lib; {
    description = "Python bindings for Qt5";
    homepage = "https://riverbankcomputing.com/";
    license = licenses.gpl3Only;
    platforms = platforms.mesaPlatforms;
    maintainers = with maintainers; [ sander ];
  };
}