1{ 2 lib, 3 stdenv, 4 buildPythonPackage, 5 setuptools, 6 isPy27, 7 fetchPypi, 8 pkg-config, 9 dbus, 10 lndir, 11 dbus-python, 12 sip, 13 pyqt5-sip, 14 pyqt-builder, 15 libsForQt5, 16 enableVerbose ? true, 17 withConnectivity ? false, 18 withMultimedia ? false, 19 withWebKit ? false, 20 withWebSockets ? false, 21 withLocation ? false, 22 withSerialPort ? false, 23 withTools ? false, 24 pkgsBuildTarget, 25 buildPackages, 26 dbusSupport ? !stdenv.isDarwin, 27}: 28 29buildPythonPackage rec { 30 pname = "pyqt5"; 31 version = "5.15.9"; 32 format = "pyproject"; 33 34 disabled = isPy27; 35 36 src = fetchPypi { 37 pname = "PyQt5"; 38 inherit version; 39 hash = "sha256-3EHoQBqQ3D4raStBG9VJKrVZrieidCTu1L05FVZOxMA="; 40 }; 41 42 patches = [ 43 # Fix some wrong assumptions by ./project.py 44 # TODO: figure out how to send this upstream 45 ./pyqt5-fix-dbus-mainloop-support.patch 46 # confirm license when installing via pyqt5-sip 47 ./pyqt5-confirm-license.patch 48 ]; 49 50 postPatch = 51 # be more verbose 52 '' 53 cat >> pyproject.toml <<EOF 54 '' 55 + lib.optionalString enableVerbose '' 56 [tool.sip.project] 57 verbose = true 58 '' 59 # Due to bug in SIP .whl name generation we have to bump minimal macos sdk upto 11.0 for 60 # aarch64-darwin. This patch can be removed once SIP will fix it in upstream, 61 # see https://github.com/NixOS/nixpkgs/pull/186612#issuecomment-1214635456. 62 + lib.optionalString (stdenv.isDarwin && stdenv.isAarch64) '' 63 minimum-macos-version = "11.0" 64 '' 65 + '' 66 EOF 67 '' 68 69 # pyqt-builder tries to compile *and run* these programs. This 70 # is really sad because the only thing they do is print out a 71 # flag based on whether or not some compile-time symbol was 72 # defined. This could all be done without having to *execute* 73 # cross-compiled programs! 74 # 75 # Here is the complete list of things checked: 76 # 77 # QT_NO_PRINTDIALOG => PyQt_PrintDialog 78 # QT_NO_PRINTER => PyQt_Printer 79 # QT_NO_PRINTPREVIEWDIALOG => PyQt_PrintPreviewDialog 80 # QT_NO_PRINTPREVIEWWIDGET => PyQt_PrintPreviewWidget 81 # QT_NO_SSL => PyQt_SSL 82 # QT_SHARED || QT_DLL => shared (otherwise static) 83 # QT_NO_PROCESS => PyQt_Process 84 # QT_NO_FPU || Q_PROCESSOR_ARM || Q_OS_WINCE => PyQt_qreal_double 85 # sizeof (qreal) != sizeof (double) => PyQt_qreal_double 86 # !Q_COMPILER_CONSTEXPR !Q_COMPILER_UNIFORM_INIT => PyQt_CONSTEXPR 87 # QT_NO_ACCESSIBILITY => PyQt_Accessibility 88 # QT_NO_OPENGL => PyQt_OpenGL PyQt_Desktop_OpenGL 89 # defined(QT_OPENGL_ES) || defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_ES_3) => PyQt_Desktop_OpenGL 90 # QT_NO_RAWFONT => PyQt_RawFont 91 # QT_NO_SESSIONMANAGER => PyQt_SessionManager 92 # 93 + lib.optionalString (!(stdenv.buildPlatform.canExecute stdenv.hostPlatform)) '' 94 rm config-tests/cfgtest_QtCore.cpp 95 rm config-tests/cfgtest_QtGui.cpp 96 rm config-tests/cfgtest_QtNetwork.cpp 97 rm config-tests/cfgtest_QtPrintSupport.cpp 98 ''; 99 100 enableParallelBuilding = true; 101 # HACK: paralellize compilation of make calls within pyqt's setup.py 102 # pkgs/stdenv/generic/setup.sh doesn't set this for us because 103 # make gets called by python code and not its build phase 104 # format=pyproject means the pip-build-hook hook gets used to build this project 105 # pkgs/development/interpreters/python/hooks/pip-build-hook.sh 106 # does not use the enableParallelBuilding flag 107 postUnpack = '' 108 export MAKEFLAGS+="''${enableParallelBuilding:+-j$NIX_BUILD_CORES}" 109 ''; 110 111 # tons of warnings from subpackages, no point in playing whack-a-mole 112 env = lib.optionalAttrs (!enableVerbose) { NIX_CFLAGS_COMPILE = "-w"; }; 113 114 outputs = [ 115 "out" 116 "dev" 117 ]; 118 119 dontWrapQtApps = true; 120 121 nativeBuildInputs = 122 [ pkg-config ] 123 ++ lib.optionals (stdenv.buildPlatform == stdenv.hostPlatform) [ libsForQt5.qmake ] 124 ++ [ 125 setuptools 126 lndir 127 sip 128 ] 129 ++ ( 130 with pkgsBuildTarget.targetPackages.libsForQt5; 131 [ ] 132 ++ lib.optionals (stdenv.buildPlatform != stdenv.hostPlatform) [ qmake ] 133 ++ [ 134 qtbase 135 qtsvg 136 qtdeclarative 137 qtwebchannel 138 ] 139 ++ lib.optional withConnectivity qtconnectivity 140 ++ lib.optional withMultimedia qtmultimedia 141 ++ lib.optional withWebKit qtwebkit 142 ++ lib.optional withWebSockets qtwebsockets 143 ++ lib.optional withLocation qtlocation 144 ++ lib.optional withSerialPort qtserialport 145 ++ lib.optional withTools qttools 146 ); 147 148 buildInputs = 149 with libsForQt5; 150 [ dbus ] 151 ++ lib.optionals (stdenv.buildPlatform == stdenv.hostPlatform) [ qtbase ] 152 ++ [ 153 qtsvg 154 qtdeclarative 155 pyqt-builder 156 ] 157 ++ lib.optional withConnectivity qtconnectivity 158 ++ lib.optional withWebKit qtwebkit 159 ++ lib.optional withWebSockets qtwebsockets 160 ++ lib.optional withLocation qtlocation 161 ++ lib.optional withSerialPort qtserialport 162 ++ lib.optional withTools qttools; 163 164 propagatedBuildInputs = [ 165 dbus-python 166 pyqt5-sip 167 ]; 168 169 passthru = { 170 inherit sip pyqt5-sip; 171 multimediaEnabled = withMultimedia; 172 webKitEnabled = withWebKit; 173 WebSocketsEnabled = withWebSockets; 174 connectivityEnabled = withConnectivity; 175 locationEnabled = withLocation; 176 serialPortEnabled = withSerialPort; 177 toolsEnabled = withTools; 178 }; 179 180 dontConfigure = true; 181 182 # Checked using pythonImportsCheck 183 doCheck = false; 184 185 pythonImportsCheck = 186 [ 187 "PyQt5" 188 "PyQt5.QtCore" 189 "PyQt5.QtQml" 190 "PyQt5.QtWidgets" 191 "PyQt5.QtGui" 192 ] 193 ++ lib.optional withWebSockets "PyQt5.QtWebSockets" 194 ++ lib.optional withWebKit "PyQt5.QtWebKit" 195 ++ lib.optional withMultimedia "PyQt5.QtMultimedia" 196 ++ lib.optional withConnectivity "PyQt5.QtBluetooth" 197 ++ lib.optional withLocation "PyQt5.QtPositioning" 198 ++ lib.optional withSerialPort "PyQt5.QtSerialPort" 199 ++ lib.optional withTools "PyQt5.QtDesigner"; 200 201 meta = with lib; { 202 description = "Python bindings for Qt5"; 203 homepage = "https://riverbankcomputing.com/"; 204 license = licenses.gpl3Only; 205 platforms = platforms.mesaPlatforms; 206 maintainers = with maintainers; [ sander ]; 207 }; 208}