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.
This commit is contained in:
Thomas Watson 2022-08-05 21:39:25 -05:00
parent 0ddcba0ae4
commit c3aff2b7d7
3 changed files with 97 additions and 26 deletions

View file

@ -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)

View file

@ -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 ]}
'';

View file

@ -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 ]}
'';