[PyQt] How to compile with PyQt5?
Kovid Goyal
kovid at kovidgoyal.net
Fri Jul 25 04:36:40 BST 2014
1600 lines? That's crazy. Here's an extract from calibre's build system.
To get all the data for building in PyQt5:
qraw = subprocess.check_output([QMAKE, '-query']).decode('utf-8')
def readvar(name):
return re.search('%s:(.+)$' % name, qraw, flags=re.M).group(1).strip()
pyqt = {x:readvar(y) for x, y in (
('inc', 'QT_INSTALL_HEADERS'), ('lib', 'QT_INSTALL_LIBS')
)}
qt = {x:readvar(y) for x, y in {'libs':'QT_INSTALL_LIBS', 'plugins':'QT_INSTALL_PLUGINS'}.iteritems()}
c = sipconfig.Configuration()
pyqt['sip_bin'] = c.sip_bin + ('.exe' if iswindows and not c.sip_bin.endswith('.exe') else '')
from PyQt5.QtCore import PYQT_CONFIGURATION
pyqt['sip_flags'] = PYQT_CONFIGURATION['sip_flags']
def get_sip_dir(q):
for x in ('', 'PyQt5', 'sip/PyQt5'):
base = os.path.join(q, x)
if os.path.exists(os.path.join(base, 'QtWidgets')):
return base
return q
pyqt['pyqt_sip_dir'] = get_sip_dir(c.default_sip_dir)
pyqt['sip_inc_dir'] = c.sip_inc_dir
And to build pyqt extensions using that data on linux, os x and windows.
def build_pyqt_extension(self, ext, dest):
pyqt_dir = self.j(self.d(self.SRC), 'build', 'pyqt')
src_dir = self.j(pyqt_dir, ext.name)
if not os.path.exists(src_dir):
os.makedirs(src_dir)
sip = self.build_sip_files(ext, src_dir)
pro = textwrap.dedent(
'''\
TEMPLATE = lib
CONFIG += release plugin
QT += widgets
TARGET = {target}
HEADERS = {headers}
SOURCES = {sources}
INCLUDEPATH += {sipinc} {pyinc}
VERSION = {ver}
win32 {{
LIBS += {py_lib}
TARGET_EXT = .dll
}}
macx {{
QMAKE_LFLAGS += "-undefined dynamic_lookup"
}}
''').format(
target=sip['target'], headers=' '.join(sip['headers'] + ext.headers), sources=' '.join(ext.sources + sip['sources']),
sipinc=pyqt['sip_inc_dir'], pyinc=sysconfig.get_python_inc(), py_lib=py_lib,
ver=__version__
)
for incdir in ext.inc_dirs:
pro += '\nINCLUDEPATH += ' + incdir
if not iswindows and not isosx:
# Ensure that only the init symbol is exported
pro += '\nQMAKE_LFLAGS += -Wl,--version-script=%s.exp' % sip['target']
with open(os.path.join(src_dir, sip['target'] + '.exp'), 'wb') as f:
f.write(('{ global: init%s; local: *; };' % sip['target']).encode('utf-8'))
if ext.qt_private_headers:
qph = ' '.join(x + '-private' for x in ext.qt_private_headers)
pro += '\nQT += ' + qph
proname = '%s.pro' % sip['target']
with open(os.path.join(src_dir, proname), 'wb') as f:
f.write(pro.encode('utf-8'))
cwd = os.getcwdu()
qmc = []
if iswindows:
qmc += ['-spec', 'win32-msvc2008']
fext = 'dll' if iswindows else 'dylib' if isosx else 'so'
name = '%s%s.%s' % ('release/' if iswindows else 'lib', sip['target'], fext)
try:
os.chdir(src_dir)
if self.newer(dest, sip['headers'] + sip['sources'] + ext.sources + ext.headers):
self.check_call([QMAKE] + qmc + [proname])
self.check_call([make]+([] if iswindows else ['-j%d'%(cpu_count or 1)]))
shutil.copy2(os.path.realpath(name), dest)
if iswindows:
shutil.copy2(name + '.manifest', dest + '.manifest')
finally:
os.chdir(cwd)
You will find this code in the master and qt5 brnaches of calibre in
setup/build_environment.py and setup/extensions.py
Kovid.
On Thu, Jul 24, 2014 at 09:07:02PM -0400, Jacob Floyd wrote:
> Hello everybody,
>
> I'm trying to get sip bindings[1] for FakeVim[2] (Vim emulation in
> QTextEdit, QPlainTextEdit and similar Qt widgets), so of course it will be
> built on PyQt. However, I'm having a hard time getting a build system to
> reliably build those sip bindings on both PyQt4 and PyQt5.
>
> With PyQt4, pyqtconfig made for a fairly simple configure.py, but I need it
> to work with both PyQt4 and PyQt5, so pyqtconfig is no longer an option.
>
> The docs[3][4] list QScintilla as a good example of something that builds
> on PyQt.
> Plus, according to Phil[5], I should just copy/paste/modify QScintilla's
> configure.py.
> So, I copy/paste QScintilla's Python/configure*.py and then ran it through
> sed[6][7] to remove all of the QScintilla stuff.
>
> When I showed what I did to hluk, the maintainer of FakeVim, he said[8]:
> > The new configure.py file has over 1600 lines. This starts to be overly
> complicated.
> > There must be simpler way to do this, otherwise it would be hell to
> maintain.
>
> So, after searching docs, the ml, and the web in general, I'm looking for
> advice here: Isn't there a simpler way? A simple build system for modules
> that support extending both PyQt4 & PyQt5? There's only one sip file right
> now, so it seems like 1600 lines is quite a bit of overhead to compile so
> few sip bindings.
>
> At least in its current state (run build.sh in the qscintilla folder[9]) my
> test can't import FakeVim, so I'm left wondering where the build system, or
> maybe the test script, needs to be tweaked.
>
> What should I do next in my quest for FakeVim sip bindings for both PyQt 4
> and PyQt 5? Is there a simpler build system than the one provided in
> QScintilla?
>
> Thanks,
> Jacob Floyd
>
> [1] https://github.com/hluk/FakeVim/issues/5
> [2] https://github.com/hluk/FakeVim
> [3] http://pyqt.sourceforge.net/Docs/PyQt4/build_system.html
> [4] http://pyqt.sourceforge.net/Docs/PyQt5/extension_api.html
> [5] http://article.gmane.org/gmane.comp.python.pyqt-pykde/27125
> [6] https://github.com/hluk/FakeVim/issues/5#issuecomment-50088032
> [7]
> https://github.com/cognifloyd/FakeVim/blob/python/qscintilla/sed-configure.sh
> Aside: One of the issues that this sed script takes care of is changing
> qscintilla's hardcoded sip files that are hardcoded outside of the
> "editable" section.
> There is an assumption that sip files will always be in sip/ which should
> be editable.
> [8] https://github.com/hluk/FakeVim/issues/5#issuecomment-50054483
> [9] https://github.com/cognifloyd/FakeVim/tree/python/qscintilla
>
>
> !DSPAM:3,53d1b37b16783439398687!
> _______________________________________________
> PyQt mailing list PyQt at riverbankcomputing.com
> http://www.riverbankcomputing.com/mailman/listinfo/pyqt
>
> !DSPAM:3,53d1b37b16783439398687!
--
_____________________________________
Dr. Kovid Goyal
http://www.kovidgoyal.net
http://calibre-ebook.com
_____________________________________
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 181 bytes
Desc: not available
URL: <http://www.riverbankcomputing.com/pipermail/pyqt/attachments/20140725/5c5a3be9/attachment.sig>
More information about the PyQt
mailing list