From c3aff2b7d798925ee9f0598c5627e9bd09dd5a51 Mon Sep 17 00:00:00 2001 From: Thomas Watson Date: Fri, 5 Aug 2022 21:39:25 -0500 Subject: [PATCH] qgis, qgis-ltr: fix build A recent upgrade to PyQt5 broke the build due to incompatibilities with SIP < 5. Upstream QGIS has supported SIP >= 5 for a while now so this patch corrects the issue by using the latest SIP and adding the necessary dependencies. The logic to find the PyQt5 libraries and SIP files is different for SIP >= 5, so a patch is included to correctly supply them. This also adds wrapGAppsHook to prevent opening file dialogs from crashing on non-NixOS distributions. --- .../gis/qgis/set-pyqt-package-dirs.patch | 59 +++++++++++++++++++ pkgs/applications/gis/qgis/unwrapped-ltr.nix | 32 ++++++---- pkgs/applications/gis/qgis/unwrapped.nix | 32 ++++++---- 3 files changed, 97 insertions(+), 26 deletions(-) create mode 100644 pkgs/applications/gis/qgis/set-pyqt-package-dirs.patch diff --git a/pkgs/applications/gis/qgis/set-pyqt-package-dirs.patch b/pkgs/applications/gis/qgis/set-pyqt-package-dirs.patch new file mode 100644 index 000000000000..5553f80fbc5b --- /dev/null +++ b/pkgs/applications/gis/qgis/set-pyqt-package-dirs.patch @@ -0,0 +1,59 @@ +diff --git a/cmake/FindPyQt5.cmake b/cmake/FindPyQt5.cmake +index b51fd0075e..87ee317e05 100644 +--- a/cmake/FindPyQt5.cmake ++++ b/cmake/FindPyQt5.cmake +@@ -25,7 +25,7 @@ ELSE(EXISTS PYQT5_VERSION_STR) + IF(SIP_BUILD_EXECUTABLE) + # SIP >= 5.0 path + +- FILE(GLOB _pyqt5_metadata "${Python_SITEARCH}/PyQt5-*.dist-info/METADATA") ++ FILE(GLOB _pyqt5_metadata "@pyQt5PackageDir@/PyQt5-*.dist-info/METADATA") + IF(_pyqt5_metadata) + FILE(READ ${_pyqt5_metadata} _pyqt5_metadata_contents) + STRING(REGEX REPLACE ".*\nVersion: ([^\n]+).*$" "\\1" PYQT5_VERSION_STR ${_pyqt5_metadata_contents}) +@@ -34,8 +34,8 @@ ELSE(EXISTS PYQT5_VERSION_STR) + ENDIF(_pyqt5_metadata) + + IF(PYQT5_VERSION_STR) +- SET(PYQT5_MOD_DIR "${Python_SITEARCH}/PyQt5") +- SET(PYQT5_SIP_DIR "${Python_SITEARCH}/PyQt5/bindings") ++ SET(PYQT5_MOD_DIR "@pyQt5PackageDir@/PyQt5") ++ SET(PYQT5_SIP_DIR "@pyQt5PackageDir@/PyQt5/bindings") + FIND_PROGRAM(__pyuic5 "pyuic5") + GET_FILENAME_COMPONENT(PYQT5_BIN_DIR ${__pyuic5} DIRECTORY) + +diff --git a/cmake/FindQsci.cmake b/cmake/FindQsci.cmake +index 69e41c1fe9..5456c3d59b 100644 +--- a/cmake/FindQsci.cmake ++++ b/cmake/FindQsci.cmake +@@ -24,7 +24,7 @@ ELSE(QSCI_MOD_VERSION_STR) + IF(SIP_BUILD_EXECUTABLE) + # SIP >= 5.0 path + +- FILE(GLOB _qsci_metadata "${Python_SITEARCH}/QScintilla*.dist-info/METADATA") ++ FILE(GLOB _qsci_metadata "@qsciPackageDir@/QScintilla*.dist-info/METADATA") + IF(_qsci_metadata) + FILE(READ ${_qsci_metadata} _qsci_metadata_contents) + STRING(REGEX REPLACE ".*\nVersion: ([^\n]+).*$" "\\1" QSCI_MOD_VERSION_STR ${_qsci_metadata_contents}) +@@ -33,7 +33,7 @@ ELSE(QSCI_MOD_VERSION_STR) + ENDIF(_qsci_metadata) + + IF(QSCI_MOD_VERSION_STR) +- SET(QSCI_SIP_DIR "${PYQT5_SIP_DIR}") ++ SET(QSCI_SIP_DIR "@qsciPackageDir@/PyQt5/bindings") + SET(QSCI_FOUND TRUE) + ENDIF(QSCI_MOD_VERSION_STR) + +diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt +index 4cd19c3af4..668cc6a5e6 100644 +--- a/python/CMakeLists.txt ++++ b/python/CMakeLists.txt +@@ -206,7 +206,7 @@ if (WITH_GUI) + install(FILES ${QGIS_PYTHON_OUTPUT_DIRECTORY}/_gui.pyi DESTINATION ${QGIS_PYTHON_DIR}) + endif() + if(QSCI_SIP_DIR) +- set(SIP_EXTRA_OPTIONS ${SIP_EXTRA_OPTIONS} -I ${QSCI_SIP_DIR}) ++ set(SIP_BUILD_EXTRA_OPTIONS ${SIP_BUILD_EXTRA_OPTIONS} --include-dir=${QSCI_SIP_DIR}) + else() + message(STATUS "Qsci sip file not found - disabling bindings for derived classes") + set(SIP_DISABLE_FEATURES ${SIP_DISABLE_FEATURES} HAVE_QSCI_SIP) diff --git a/pkgs/applications/gis/qgis/unwrapped-ltr.nix b/pkgs/applications/gis/qgis/unwrapped-ltr.nix index e079d347181c..b5a407ef5335 100644 --- a/pkgs/applications/gis/qgis/unwrapped-ltr.nix +++ b/pkgs/applications/gis/qgis/unwrapped-ltr.nix @@ -38,6 +38,8 @@ , pdal , zstd , makeWrapper +, wrapGAppsHook +, substituteAll }: let @@ -64,7 +66,9 @@ let urllib3 pygments pyqt5 - sip_4 + pyqt-builder + sip + setuptools owslib six ]; @@ -116,29 +120,31 @@ in mkDerivation rec { ++ lib.optional withWebKit qtwebkit ++ pythonBuildInputs; - nativeBuildInputs = [ makeWrapper cmake flex bison ninja ]; + nativeBuildInputs = [ makeWrapper wrapGAppsHook cmake flex bison ninja ]; - # Force this pyqt_sip_dir variable to point to the sip dir in PyQt5 - # - # TODO: Correct PyQt5 to provide the expected directory and fix - # build to use PYQT5_SIP_DIR consistently. - postPatch = '' - substituteInPlace cmake/FindPyQt5.py \ - --replace 'sip_dir = cfg.default_sip_dir' 'sip_dir = "${py.pkgs.pyqt5}/${py.pkgs.python.sitePackages}/PyQt5/bindings"' - ''; + patches = [ + (substituteAll { + src = ./set-pyqt-package-dirs.patch; + pyQt5PackageDir = "${py.pkgs.pyqt5}/${py.pkgs.python.sitePackages}"; + qsciPackageDir = "${py.pkgs.qscintilla-qt5}/${py.pkgs.python.sitePackages}"; + }) + ]; cmakeFlags = [ "-DWITH_3D=True" "-DWITH_PDAL=TRUE" - "-DPYQT5_SIP_DIR=${py.pkgs.pyqt5}/${py.pkgs.python.sitePackages}/PyQt5/bindings" - "-DQSCI_SIP_DIR=${py.pkgs.qscintilla-qt5}/${py.pkgs.python.sitePackages}/PyQt5/bindings" ] ++ lib.optional (!withWebKit) "-DWITH_QTWEBKIT=OFF" ++ lib.optional withGrass "-DGRASS_PREFIX7=${grass}/grass78"; + dontWrapGApps = true; # wrapper params passed below + postFixup = lib.optionalString withGrass '' # grass has to be availble on the command line even though we baked in - # the path at build time using GRASS_PREFIX + # the path at build time using GRASS_PREFIX. + # using wrapGAppsHook also prevents file dialogs from crashing the program + # on non-NixOS wrapProgram $out/bin/qgis \ + "''${gappsWrapperArgs[@]}" \ --prefix PATH : ${lib.makeBinPath [ grass ]} ''; diff --git a/pkgs/applications/gis/qgis/unwrapped.nix b/pkgs/applications/gis/qgis/unwrapped.nix index fe53f0726b4e..ae35fb2ec269 100644 --- a/pkgs/applications/gis/qgis/unwrapped.nix +++ b/pkgs/applications/gis/qgis/unwrapped.nix @@ -38,6 +38,8 @@ , pdal , zstd , makeWrapper +, wrapGAppsHook +, substituteAll }: let @@ -64,7 +66,9 @@ let urllib3 pygments pyqt5 - sip_4 + pyqt-builder + sip + setuptools owslib six ]; @@ -116,29 +120,31 @@ in mkDerivation rec { ++ lib.optional withWebKit qtwebkit ++ pythonBuildInputs; - nativeBuildInputs = [ makeWrapper cmake flex bison ninja ]; + nativeBuildInputs = [ makeWrapper wrapGAppsHook cmake flex bison ninja ]; - # Force this pyqt_sip_dir variable to point to the sip dir in PyQt5 - # - # TODO: Correct PyQt5 to provide the expected directory and fix - # build to use PYQT5_SIP_DIR consistently. - postPatch = '' - substituteInPlace cmake/FindPyQt5.py \ - --replace 'sip_dir = cfg.default_sip_dir' 'sip_dir = "${py.pkgs.pyqt5}/${py.pkgs.python.sitePackages}/PyQt5/bindings"' - ''; + patches = [ + (substituteAll { + src = ./set-pyqt-package-dirs.patch; + pyQt5PackageDir = "${py.pkgs.pyqt5}/${py.pkgs.python.sitePackages}"; + qsciPackageDir = "${py.pkgs.qscintilla-qt5}/${py.pkgs.python.sitePackages}"; + }) + ]; cmakeFlags = [ "-DWITH_3D=True" "-DWITH_PDAL=TRUE" - "-DPYQT5_SIP_DIR=${py.pkgs.pyqt5}/${py.pkgs.python.sitePackages}/PyQt5/bindings" - "-DQSCI_SIP_DIR=${py.pkgs.qscintilla-qt5}/${py.pkgs.python.sitePackages}/PyQt5/bindings" ] ++ lib.optional (!withWebKit) "-DWITH_QTWEBKIT=OFF" ++ lib.optional withGrass "-DGRASS_PREFIX7=${grass}/grass78"; + dontWrapGApps = true; # wrapper params passed below + postFixup = lib.optionalString withGrass '' # grass has to be availble on the command line even though we baked in - # the path at build time using GRASS_PREFIX + # the path at build time using GRASS_PREFIX. + # using wrapGAppsHook also prevents file dialogs from crashing the program + # on non-NixOS wrapProgram $out/bin/qgis \ + "''${gappsWrapperArgs[@]}" \ --prefix PATH : ${lib.makeBinPath [ grass ]} '';