From b397af5d9cfa685d2a41ede488e027561035087c Mon Sep 17 00:00:00 2001 From: Sinan Date: Fri, 27 Mar 2020 09:42:58 -0700 Subject: Package/qscintilla: python bindings via extend path (#15599) * build python bindings within qscintilla package via extend_path trick * add todo * reflect new setup also in py-pyqt4 package * get rid of qscintilla dependency * also tweak qgis for the new setup * generalize the building of python bindings * generalize building of pythong bindings to all qt versions * add qsci_api variant * add qsci_variant for pyqt4 package as well; add comment * pyqt dependency should build with +qsci_api variant enabled * fix bugs * improve style * reflect recent changes * flake8 * improve style * more flake8 * more flake8 Co-authored-by: Sinan81 --- .../repos/builtin/packages/py-pyqt4/package.py | 64 ++---------------- .../repos/builtin/packages/py-pyqt5/package.py | 67 ++----------------- var/spack/repos/builtin/packages/qgis/package.py | 6 +- .../repos/builtin/packages/qscintilla/package.py | 78 +++++++++++++++++++++- 4 files changed, 89 insertions(+), 126 deletions(-) (limited to 'var') diff --git a/var/spack/repos/builtin/packages/py-pyqt4/package.py b/var/spack/repos/builtin/packages/py-pyqt4/package.py index d1a90042d9..6c5af83cb2 100644 --- a/var/spack/repos/builtin/packages/py-pyqt4/package.py +++ b/var/spack/repos/builtin/packages/py-pyqt4/package.py @@ -4,7 +4,6 @@ # SPDX-License-Identifier: (Apache-2.0 OR MIT) from spack import * -import os class PyPyqt4(SIPPackage): @@ -29,21 +28,13 @@ class PyPyqt4(SIPPackage): version('4.11.3', sha256='853780dcdbe2e6ba785d703d059b096e1fc49369d3e8d41a060be874b8745686', url='http://sourceforge.net/projects/pyqt/files/PyQt4/PyQt-4.11.3/PyQt-x11-gpl-4.11.3.tar.gz') - variant('qsci', default=False, description='Build with QScintilla python bindings') + # API files can be installed regardless if QScintilla is installed or not + variant('qsci_api', default=False, description='Install PyQt API file for QScintilla') # Supposedly can also be built with Qt 5 compatibility layer depends_on('qt@:4') - depends_on('qscintilla', when='+qsci') depends_on('py-sip module=PyQt4.sip') - # For building Qscintilla python bindings - resource(name='qscintilla', - url='https://www.riverbankcomputing.com/static/Downloads/QScintilla/2.10.2/QScintilla_gpl-2.10.2.tar.gz', - sha256='14b31d20717eed95ea9bea4cd16e5e1b72cee7ebac647cba878e0f6db6a65ed0', - destination='spack-resource-qscintilla', - when='^qscintilla@2.10.2' - ) - # https://www.riverbankcomputing.com/static/Docs/PyQt4/installation.html def configure_file(self): return 'configure-ng.py' @@ -54,52 +45,7 @@ class PyPyqt4(SIPPackage): '--sipdir', self.prefix.share.sip.PyQt4, '--stubsdir', join_path(site_packages_dir, 'PyQt4') ] - if '+qsci' in self.spec: - args.extend(['--qsci-api-destdir', self.prefix.share.qsci]) + if '+qsci_api' in self.spec: + args.extend(['--qsci-api', + '--qsci-api-destdir', self.prefix.share.qsci]) return args - - @run_after('install') - def make_qsci(self): - if '+qsci' in self.spec: - rsrc_py_path = os.path.join( - self.stage.source_path, - 'spack-resource-qscintilla/QScintilla_gpl-' + - str(self.spec['qscintilla'].version), 'Python') - with working_dir(rsrc_py_path): - pydir = join_path(site_packages_dir, 'PyQt4') - python = self.spec['python'].command - python('configure.py', - '--sip=' + self.spec['py-sip'].prefix.bin.sip, - '--qsci-incdir=' + - self.spec['qscintilla'].prefix.include, - '--qsci-libdir=' + self.spec['qscintilla'].prefix.lib, - '--qsci-sipdir=' + self.prefix.share.sip.PyQt4, - '--apidir=' + self.prefix.share.qsci, - '--destdir=' + pydir, - '--pyqt-sipdir=' + self.prefix.share.sip.PyQt4, - '--sip-incdir=' + - join_path(self.spec['py-sip'].prefix.include, - 'python' + - str(self.spec['python'].version.up_to(2))), - '--stubsdir=' + pydir) - - # Fix build errors - # "QAbstractScrollArea: No such file or directory" - # "qprinter.h: No such file or directory" - # ".../Qsci.so: undefined symbol: _ZTI10Qsci...." - qscipro = FileFilter('Qsci/Qsci.pro') - link_qscilibs = 'LIBS += -L' + self.prefix.lib +\ - ' -lqscintilla2_qt4' - qscipro.filter('TEMPLATE = lib', - 'TEMPLATE = lib\nQT += widgets' + - '\nQT += printsupport\n' + link_qscilibs) - - make() - - # Fix installation prefixes - makefile = FileFilter('Makefile') - makefile.filter(r'\$\(INSTALL_ROOT\)', '') - makefile = FileFilter('Qsci/Makefile') - makefile.filter(r'\$\(INSTALL_ROOT\)', '') - - make('install') diff --git a/var/spack/repos/builtin/packages/py-pyqt5/package.py b/var/spack/repos/builtin/packages/py-pyqt5/package.py index bc37d4dcab..e26c66a891 100644 --- a/var/spack/repos/builtin/packages/py-pyqt5/package.py +++ b/var/spack/repos/builtin/packages/py-pyqt5/package.py @@ -4,7 +4,6 @@ # SPDX-License-Identifier: (Apache-2.0 OR MIT) from spack import * -import os class PyPyqt5(SIPPackage): @@ -30,7 +29,8 @@ class PyPyqt5(SIPPackage): version('5.13.0', sha256='0cdbffe5135926527b61cc3692dd301cd0328dd87eeaf1313e610787c46faff9') version('5.12.3', sha256='0db0fa37debab147450f9e052286f7a530404e2aaddc438e97a7dcdf56292110') - variant('qsci', default=False, description='Build with QScintilla python bindings') + # API files can be installed regardless if Qscintilla is installed or not + variant('qsci_api', default=False, description='Install PyQt API file for QScintilla') # Without opengl support, I got the following error: # sip: QOpenGLFramebufferObject is undefined @@ -39,15 +39,6 @@ class PyPyqt5(SIPPackage): depends_on('py-enum34', type=('build', 'run'), when='^python@:3.3') depends_on('py-sip module=PyQt5.sip', type=('build', 'run')) depends_on('py-sip@:4.19.18 module=PyQt5.sip', type=('build', 'run'), when='@:5.13.0') - depends_on('qscintilla', when='+qsci') - - # For building Qscintilla python bindings - resource(name='qscintilla', - url='https://www.riverbankcomputing.com/static/Downloads/QScintilla/2.10.2/QScintilla_gpl-2.10.2.tar.gz', - sha256='14b31d20717eed95ea9bea4cd16e5e1b72cee7ebac647cba878e0f6db6a65ed0', - destination='spack-resource-qscintilla', - when='^qscintilla@2.10.2' - ) # https://www.riverbankcomputing.com/static/Docs/PyQt5/installation.html def configure_args(self): @@ -59,55 +50,7 @@ class PyPyqt5(SIPPackage): self.spec['python'].package.site_packages_dir, 'PyQt5'), ] - if '+qsci' in self.spec: - args.extend(['--qsci-api-destdir', self.prefix.share.qsci]) + if '+qsci_api' in self.spec: + args.extend(['--qsci-api', + '--qsci-api-destdir', self.prefix.share.qsci]) return args - - @run_after('install') - def make_qsci(self): - if '+qsci' in self.spec: - rsrc_py_path = os.path.join( - self.stage.source_path, - 'spack-resource-qscintilla/QScintilla_gpl-' + - str(self.spec['qscintilla'].version), 'Python') - with working_dir(rsrc_py_path): - pydir = join_path( - self.prefix, - self.spec['python'].package.site_packages_dir, - 'PyQt5') - python = self.spec['python'].command - python('configure.py', '--pyqt=PyQt5', - '--sip=' + self.spec['py-sip'].prefix.bin.sip, - '--qsci-incdir=' + - self.spec['qscintilla'].prefix.include, - '--qsci-libdir=' + self.spec['qscintilla'].prefix.lib, - '--qsci-sipdir=' + self.prefix.share.sip.PyQt5, - '--apidir=' + self.prefix.share.qsci, - '--destdir=' + pydir, - '--pyqt-sipdir=' + self.prefix.share.sip.PyQt5, - '--sip-incdir=' + - join_path(self.spec['py-sip'].prefix.include, - 'python' + - str(self.spec['python'].version.up_to(2))), - '--stubsdir=' + pydir) - - # Fix build errors - # "QAbstractScrollArea: No such file or directory" - # "qprinter.h: No such file or directory" - # ".../Qsci.so: undefined symbol: _ZTI10Qsci...." - qscipro = FileFilter('Qsci/Qsci.pro') - link_qscilibs = 'LIBS += -L' + self.prefix.lib +\ - ' -lqscintilla2_qt5' - qscipro.filter('TEMPLATE = lib', - 'TEMPLATE = lib\nQT += widgets' + - '\nQT += printsupport\n' + link_qscilibs) - - make() - - # Fix installation prefixes - makefile = FileFilter('Makefile') - makefile.filter(r'\$\(INSTALL_ROOT\)', '') - makefile = FileFilter('Qsci/Makefile') - makefile.filter(r'\$\(INSTALL_ROOT\)', '') - - make('install') diff --git a/var/spack/repos/builtin/packages/qgis/package.py b/var/spack/repos/builtin/packages/qgis/package.py index 4a6d6a3583..89536068da 100644 --- a/var/spack/repos/builtin/packages/qgis/package.py +++ b/var/spack/repos/builtin/packages/qgis/package.py @@ -74,9 +74,9 @@ class Qgis(CMakePackage): depends_on('qwtpolar') depends_on('expat@1.95:') depends_on('qca@2.2.1') - depends_on('py-pyqt4 +qsci', when='@2') - depends_on('py-pyqt5@5.3: +qsci', when='@3') - depends_on('qscintilla') + depends_on('py-pyqt4', when='@2') + depends_on('py-pyqt5@5.3:', when='@3') + depends_on('qscintilla +python') depends_on('qjson') depends_on('py-requests', type=('build', 'run')) # TODO: is build dependency necessary? depends_on('py-psycopg2', type=('build', 'run')) # TODO: is build dependency necessary? diff --git a/var/spack/repos/builtin/packages/qscintilla/package.py b/var/spack/repos/builtin/packages/qscintilla/package.py index 9bee719c13..ec20257676 100644 --- a/var/spack/repos/builtin/packages/qscintilla/package.py +++ b/var/spack/repos/builtin/packages/qscintilla/package.py @@ -20,10 +20,14 @@ class Qscintilla(QMakePackage): version('2.10.2', sha256='14b31d20717eed95ea9bea4cd16e5e1b72cee7ebac647cba878e0f6db6a65ed0', preferred=True) variant('designer', default=False, description="Enable pluging for Qt-Designer") - # No 'python' variant, since Python bindings will be - # built by PyQt5+qsci instead + variant('python', default=False, description="Build python bindings") depends_on('qt') + depends_on('py-pyqt5 +qsci_api', type=('build', 'run'), when='+python ^qt@5') + depends_on('py-pyqt4 +qsci_api', type=('build', 'run'), when='+python ^qt@4') + depends_on('python', type=('build', 'run'), when='+python') + + extends('python', when='+python') @run_before('qmake') def chdir(self): @@ -66,3 +70,73 @@ class Qscintilla(QMakePackage): makefile.filter(r'\$\(INSTALL_ROOT\)' + self.spec['qt'].prefix, '$(INSTALL_ROOT)') make('install') + + @run_after('install') + def make_qsci(self): + if '+python' in self.spec: + if '^py-pyqt4' in self.spec: + py_pyqtx = 'py-pyqt4' + pyqtx = 'PyQt4' + elif '^py-pyqt5' in self.spec: + py_pyqtx = 'py-pyqt5' + pyqtx = 'PyQt5' + + with working_dir(join_path(self.stage.source_path, 'Python')): + pydir = join_path( + self.prefix, + self.spec['python'].package.site_packages_dir, + pyqtx) + mkdirp(os.path.join(self.prefix.share.sip, pyqtx)) + python = self.spec['python'].command + python('configure.py', '--pyqt=' + pyqtx, + '--sip=' + self.spec['py-sip'].prefix.bin.sip, + '--qsci-incdir=' + self.spec.prefix.include, + '--qsci-libdir=' + self.spec.prefix.lib, + '--qsci-sipdir=' + + os.path.join(self.prefix.share.sip, pyqtx), + '--apidir=' + self.prefix.share.qsci, + '--destdir=' + pydir, + '--pyqt-sipdir=' + os.path.join( + self.spec[py_pyqtx].prefix.share.sip, pyqtx), + '--sip-incdir=' + + join_path(self.spec['py-sip'].prefix.include, + 'python' + + str(self.spec['python'].version.up_to(2))), + '--stubsdir=' + pydir) + + # Fix build errors + # "QAbstractScrollArea: No such file or directory" + # "qprinter.h: No such file or directory" + # ".../Qsci.so: undefined symbol: _ZTI10Qsci...." + qscipro = FileFilter('Qsci/Qsci.pro') + if '^qt@4' in self.spec: + qtx = 'qt4' + elif '^qt@5' in self.spec: + qtx = 'qt5' + + link_qscilibs = 'LIBS += -L' + self.prefix.lib +\ + ' -lqscintilla2_' + qtx + qscipro.filter('TEMPLATE = lib', + 'TEMPLATE = lib\nQT += widgets' + + '\nQT += printsupport\n' + link_qscilibs) + + make() + + # Fix installation prefixes + makefile = FileFilter('Makefile') + makefile.filter(r'\$\(INSTALL_ROOT\)', '') + makefile = FileFilter('Qsci/Makefile') + makefile.filter(r'\$\(INSTALL_ROOT\)', '') + + make('install') + + @run_after('install') + def extend_path_setup(self): + # See github issue #14121 and PR #15297 + module = self.spec['py-sip'].variants['module'].value + if module != 'sip': + module = module.split('.')[0] + with working_dir(site_packages_dir): + with open(os.path.join(module, '__init__.py'), 'w') as f: + f.write('from pkgutil import extend_path\n') + f.write('__path__ = extend_path(__path__, __name__)\n') -- cgit v1.2.3-70-g09d2