Re: using sip-wheel on MacOS
Steve Borho <[email protected]> Wed, 29 Apr 2020 11:11:24 -0500
| Newsgroups | gmane.comp.python.pyqt-pykde |
|---|---|
| Message-ID | <[email protected]> |
> On Apr 29, 2020, at 3:02 AM, Phil Thompson <[email protected]> wrote: > > On 29/04/2020 02:52, Steve Borho wrote: >>> On Apr 28, 2020, at 3:46 PM, Phil Thompson <[email protected]> wrote: >>> On 28/04/2020 18:49, Steve Borho wrote: >>>>> On Apr 28, 2020, at 3:58 AM, Phil Thompson <[email protected]> wrote: >>>>> On 28/04/2020 04:55, Steve Borho wrote: >>>>>> Hello, >>>>>> On Linux and Windows I can use sip-wheel to build binary wheels that >>>>>> will gladly use the Qt libraries packaged by PyQt5, by compiling >>>>>> against the same local version of Qt. >>>>>> But when I try this on Mac, it is linking in the full paths to the >>>>>> local (homebrew) Qt libraries >>>>>> $ otool -L foo.cpython-37m-darwin.so >>>>>> foo.cpython-37m-darwin.so: >>>>>> /usr/local/opt/qt/lib/QtPrintSupport.framework/Versions/5/QtPrintSupport >>>>>> (compatibility version 5.14.0, current version 5.14.1) >>>>>> /usr/local/opt/qt/lib/QtOpenGL.framework/Versions/5/QtOpenGL >>>>>> (compatibility version 5.14.0, current version 5.14.1) >>>>>> /usr/local/opt/qt/lib/QtWidgets.framework/Versions/5/QtWidgets >>>>>> (compatibility version 5.14.0, current version 5.14.1) >>>>>> /usr/local/opt/qt/lib/QtDataVisualization.framework/Versions/5/QtDataVisualization >>>>>> (compatibility version 5.14.0, current version 5.14.1) >>>>>> /usr/local/opt/qt/lib/QtGui.framework/Versions/5/QtGui (compatibility >>>>>> version 5.14.0, current version 5.14.1) >>>>>> I see that sip-wheel has an option for: >>>>>> --target-qt-dir DIR the Qt libraries will be found in DIR when the wheel >>>>>> is installed >>>>>> but it is not clear how to target the PyQt5 packaged Qt libraries. >>>>>> Has anyone else tackled this? Thanks >>>>> Assuming you are going to package a Qt installation with your wheel using pyqt-bundle at a later stage then pass '--target-qt-dir Qt/lib'. >>>>> This will be documented in the next release of the PyQt docs. >>>> Ideally the binaries in the wheel would use the Qt libraries in >>>> ../PyQt5/Qt/lib/* from site-packages. >>>> Does my app need to package its own copy of the Qt libraries if it >>>> compiles its own shared library? >>>> I just realized my Linux wheels have the same issue. They are not >>>> using PyQt5/Qt/lib, they are relying on the Qt libraries being present >>>> where they were compiled. >>> I'm not sure what it is you are trying to achieve. The wheels on PyPI are created by running sip-wheel using the --target-qt-dir. The wheel is compiled against a local Qt installation but targeted for a bundled copy of Qt. That wheel, if installed, would not run. pyqt-bundle is then run to bundle a copy of that local Qt installation to create a new wheel (the one uploaded to PyPI). >> I have a PyQt application which implements some plotters in C++ and we >> compile these into a shared library that links against several Qt >> libraries. sip creates the Python bindings for it >> When the application is installed as a wheel, ideally the plotter >> shared library would link with the same Qt libraries that PyQt5 is >> using, under site-packages/PyQt5/Qt/lib. >> Any Qt libraries I package with my application could possibly be >> incompatible with those that PyQt5 was compiled against and shipped >> with. Is it typical for apps that use both PyQt5 from Python and the >> link to native Qt libraries to just ship the whole shebang (app + qt + >> pyqt) in one wheel? I’m curious how this is generally solved. > > If you are relying on the PyQt5 wheels from PyPI then obviously you need to build against a compatible version of Qt. If you are using Qt libraries that are not bundled with the PyQt5 wheels then you will need to bundle them yourself in your own wheels. > >> I actually have this almost working by adding this bit of shenanigans >> to the main.py script: >> import os >> # relaunch the executable with site-packages/PyQt5/Qt/lib in library path >> if 'APP_LIBPATH_HACK' not in os.environ: >> sitepackages = os.path.dirname(os.path.dirname(__file__)) >> import sys >> if sys.platform in ('linux', 'darwin'): >> pyqt5 = os.path.join(sitepackages, 'PyQt5', 'Qt', 'lib') >> else: >> pyqt5 = os.path.join(sitepackages, 'PyQt5', 'Qt', 'bin') >> if os.path.isdir(pyqt5): >> if sys.platform == 'linux': >> os.environ['LD_LIBRARY_PATH'] = pyqt5 >> elif sys.platform == 'darwin': >> os.environ['DYLD_FRAMEWORK_PATH'] = pyqt5 >> else: >> os.environ['PATH'] = os.pathsep.join((pyqt5, os.environ['PATH'])) >> os.environ['APP_LIBPATH_HACK'] = '1' >> os.execv(sys.argv[0], sys.argv) >> It feels dirty, and doesn’t quite work because our plotter is linking >> against QtDataVisualization and this Qt library is not packaged with >> PyQt5, I presume because there are no Python bindings for it yet. Is >> support for QtDataVisualization on the roadmap? > > PyQtDataVisualization was first released in March 2014. Perfect, thanks. I had found QScintilla in pypi, but didn’t think to look for that one. Everything works now. — Steve