PyQt 静态构建在 make 时失败
Posted
技术标签:
【中文标题】PyQt 静态构建在 make 时失败【英文标题】:PyQt static build fails at make 【发布时间】:2017-04-29 21:44:41 【问题描述】:我拥有 Qt 和 PyQt 的商业许可证,并且正在尝试构建所有必需软件的静态版本,以生成我目前正在使用 Python3 和 PyQt 编写的独立可执行程序。我计划使用 VirtualBox 本地构建,并且可能会针对 Linux 和 Windows。我目前正在尝试设置 Linux 构建环境。
完成此操作的第一步是构建系统根目录,如下所述:http://pyqt.sourceforge.net/Docs/pyqtdeploy/build_sysroot.html
我正在使用 build-sysroot.py,此处介绍:https://www.riverbankcomputing.com/hg/pyqtdeploy/file/tip/Developers/build-sysroot.py
按照第一个链接中的说明,我创建了一个根目录 (sysroot-linux),其中包含一个名为 src 的目录,其中包含 Qt5、PyQt5、sip、PyQtChart 和 Python 的 g 压缩源代码文件夹。
我在 VBox 中使用 Xubuntu 16.04 64 位,以及商业 PyQt-5.8、商业 PyQtChart-5.8、Python-3.6.1、商业 Qt-5.8.0 和 sip-4.19.2。我将我的 Qt 许可证信息复制到位于 /home/(user)/.qt-license 的文件中。我将我的 PyQt 许可证文件复制到 g 压缩的 PyQt/sip 目录中。
当我在终端中运行以下命令时:
python3 build-sysroot.py --build qt python sip pyqt5 pyqtchart --sysroot /home/(user)/(path-to)/sysroot-linux
其中 (user) 是用户名, (path-to) 是系统根目录的路径。
在这个过程大约 1.5 小时后,我在 PyQt 构建过程中收到一个错误
Makefile:953: recipe for target 'sipQtNetworkpart1.o' failed
make[1]: \*** [sipQtNetworkpart1.o] Error 1
make[1]: Leaving directory '/home/(user)/(path-to)/sysroot-linux/build/PyQt5_commercial-5.8/QtNetwork'
Makefile:414: recipe for target 'sub-QtNetwork-make_first-ordered' failed
make: \*** [sub-QtNetwork-make_first-ordered] Error 2
Traceback (most recent call last):
File "build-sysroot.py", line 1073, in <module>
build_pyqt5(host, target, args.all, args.debug)
File "build-sysroot.py", line 735, in build_pyqt5
host.run(host.make)
File "build-sysroot.py", line 313, in run
subprocess.check_call(args)
File "/usr/lib/python3.5/subprocess.py", line 581, in check_call
raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command '('make',)' returned non-zero exit status 2
销售 PyQt 的公司告诉我,我的 Qt 版本不支持 SSL,但我的 PyQt 配置文件已启用它。
所以我尝试使用 build-sysroot.py 中的“disable=QtNetwork”在 PyQt 配置中禁用 QtNetwork,在“args”中使用函数“build_pyqt5”(python 列表类型;参见第一个链接的第 721 行),但无济于事- 该选项似乎已被忽略,并且无论如何都会尝试构建 QtNetwork。
我与销售 PyQt 的公司保持联系,但我想联系更广泛的编程社区,看看过去是否有人成功地做到了这一点,或许可以提供见解。非常感谢任何帮助。
谢谢, 克里斯
编辑 1 这是完整的错误输出,仅修改了目录路径:
make[1]: Entering directory '/home/(user)/(path-to)/sysroot-linux/build/PyQt5_commercial-5.8/QtNetwork'
g++ -c -pipe -O2 -fPIC -std=gnu++11 -fvisibility=hidden -fvisibility-inlines-hidden -fno-exceptions -Wall -W -D_REENTRANT -DSIP_PROTECTED_IS_PUBLIC -Dprotected=public -DQT_NO_EXCEPTIONS -DQT_NO_DEBUG -DQT_NETWORK_LIB -DQT_CORE_LIB -I. -I. -I../../../include/python3.6 -I../../../Qt/include -I../../../Qt/include/QtNetwork -I../../../Qt/include/QtCore -I. -I../../../Qt/mkspecs/linux-g++ -o sipQtNetworkpart1.o sipQtNetworkpart1.cpp
/home/(user)/(path-to)/sysroot-linux/build/PyQt5_commercial-5.8/QtNetwork/sipQtNetworkpart1.cpp: In function ‘PyObject* meth_QNetworkReply_sslConfiguration(PyObject*, PyObject*)’:
/home/(user)/(path-to)/sysroot-linux/build/PyQt5_commercial-5.8/QtNetwork/sipQtNetworkpart1.cpp:1094:55: error: ‘const class QNetworkReply’ has no member named ‘sslConfiguration’
sipRes = new ::QSslConfiguration(sipCpp->sslConfiguration());
^
/home/(user)/(path-to)/sysroot-linux/build/PyQt5_commercial-5.8/QtNetwork/sipQtNetworkpart1.cpp:1094:73: error: invalid use of incomplete type ‘class QSslConfiguration’
sipRes = new ::QSslConfiguration(sipCpp->sslConfiguration());
^
In file included from ../../../Qt/include/QtNetwork/QNetworkRequest:1:0,
from ../../../Qt/include/QtNetwork/qnetworkreply.h:48,
from /home/(user)/(path-to)/sysroot-linux/build/PyQt5_commercial-5.8/sip/QtNetwork/qnetworkreply.sip:18:
../../../Qt/include/QtNetwork/qnetworkrequest.h:52:7: note: forward declaration of ‘class QSslConfiguration’
class QSslConfiguration;
^
/home/(user)/(path-to)/sysroot-linux/build/PyQt5_commercial-5.8/QtNetwork/sipQtNetworkpart1.cpp: In function ‘PyObject* meth_QNetworkReply_setSslConfiguration(PyObject*, PyObject*)’:
/home/(user)/(path-to)/sysroot-linux/build/PyQt5_commercial-5.8/QtNetwork/sipQtNetworkpart1.cpp:1120:21: error: ‘class QNetworkReply’ has no member named ‘setSslConfiguration’
sipCpp->setSslConfiguration(*a0);
^
/home/(user)/(path-to)/sysroot-linux/build/PyQt5_commercial-5.8/QtNetwork/sipQtNetworkpart1.cpp: In function ‘PyObject* meth_QNetworkReply_ignoreSslErrors(PyObject*, PyObject*)’:
/home/(user)/(path-to)/sysroot-linux/build/PyQt5_commercial-5.8/QtNetwork/sipQtNetworkpart1.cpp:1162:40: error: no matching function for call to ‘QNetworkReply::ignoreSslErrors(const QList<QSslError>&)’
sipCpp->ignoreSslErrors(*a0);
^
In file included from /home/(user)/(path-to)/sysroot-linux/build/PyQt5_commercial-5.8/sip/QtNetwork/qnetworkreply.sip:18:0:
../../../Qt/include/QtNetwork/qnetworkreply.h:154:18: note: candidate: virtual void QNetworkReply::ignoreSslErrors()
virtual void ignoreSslErrors();
^
../../../Qt/include/QtNetwork/qnetworkreply.h:154:18: note: candidate expects 0 arguments, 1 provided
/home/(user)/(path-to)/sysroot-linux/build/PyQt5_commercial-5.8/QtNetwork/sipQtNetworkpart1.cpp: In function ‘PyObject* meth_QNetworkAccessManager_connectToHostEncrypted(PyObject*, PyObject*, PyObject*)’:
/home/(user)/(path-to)/sysroot-linux/build/PyQt5_commercial-5.8/QtNetwork/sipQtNetworkpart1.cpp:12735:45: error: incomplete type ‘QSslConfiguration’ used in nested name specifier
sipName_PutOperation, static_cast<int>( ::QNetworkAccessManager::PutOperation), 55,
^
/home/(user)/(path-to)/sysroot-linux/build/PyQt5_commercial-5.8/QtNetwork/sipQtNetworkpart1.cpp:12747:21: error: ‘class QNetworkAccessManager’ has no member named ‘connectToHostEncrypted’
"encrypted(QNetworkReply*)", "\1encrypted(self, QNetworkReply)", 0, 0,
^
Makefile:953: recipe for target 'sipQtNetworkpart1.o' failed
make[1]: *** [sipQtNetworkpart1.o] Error 1
make[1]: Leaving directory '/home/(user)/(path-to)/sysroot-linux/build/PyQt5_commercial-5.8/QtNetwork'
Makefile:414: recipe for target 'sub-QtNetwork-make_first-ordered' failed
make: *** [sub-QtNetwork-make_first-ordered] Error 2
Traceback (most recent call last):
File "build-sysroot.py", line 1073, in <module>
build_pyqt5(host, target, args.all, args.debug)
File "build-sysroot.py", line 735, in build_pyqt5
host.run(host.make)
File "build-sysroot.py", line 313, in run
subprocess.check_call(args)
File "/usr/lib/python3.5/subprocess.py", line 581, in check_call
raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command '('make',)' returned non-zero exit status 2
【问题讨论】:
请包含更多制作过程的输出。您的输出显示了哪个文件不起作用,但没有显示原因。 make 之前应该有编译器错误;包括他们。 @Sam Hartman,很抱歉 - 我提供了制作过程的更多输出。 【参考方案1】:我会继续分享我的解决方法,以防其他人遇到此问题。
目前 build-sysroot.py 脚本使用 pyqtdeploycli 生成构建 PyQt 的配置文件,其中包含不能静态构建的 Qt 模块,例如 QtWebEngine。无论如何,我最终为 PyQt5 制作了一个配置文件,并将其放入 PyQt5 源代码的顶部 g-zip 压缩文件夹中:
/home/(user)/(path-to)/sysroot-linux/src/PyQt5_commercial-5.8.2.tar.gz/PyQt5_commercial-5.8.2/pyqt5-linux-64.cfg
PyQt5配置文件(pyqt5-linux-64.cfg):
# The configuration for building PyQt5 for Linux.
# The target Python installation.
py_platform = linux
py_inc_dir = %(sysroot)/include/python%(py_major).%(py_minor)
py_pylib_dir = %(sysroot)/lib
py_pylib_lib = python%(py_major).%(py_minor)m
# The target PyQt installation.
pyqt_module_dir = %(sysroot)/lib/python%(py_major).%(py_minor)/site-packages
pyqt_sip_dir = %(sysroot)/share/sip/PyQt5
# Qt configuration common to all versions.
qt_shared = False
[Qt 5.6]
pyqt_modules = QtCore QtGui QtWidgets
[Qt 5.5]
pyqt_modules = QtCore QtGui QtWidgets
[Qt 5.4]
pyqt_modules = QtCore QtGui QtWidgets
[Qt 5.3]
pyqt_modules = QtCore QtGui QtWidgets
[Qt 5.2]
pyqt_modules = QtCore QtGui QtWidgets
然后我修改了 build-sysroot.py build_pyqt5 函数,不再调用 pyqtdeploycli,而是直接使用手动创建的配置文件,如下:
def build_pyqt5(host, target, optional, debug):
""" Build a target static PyQt5. """
source = host.sysroot.find_source('PyQt5_*', optional=optional)
if source is None:
return
host.sysroot.unpack_source(source)
license_path = os.path.join(host.sysroot.src_dir, 'pyqt-commercial.sip')
if os.path.isfile(license_path):
shutil.copy(license_path, 'sip')
configuration = 'pyqt5-' + target.name + '.cfg'
# Disable the call to pyqtdeploycli here
# host.run(host.pyqtdeploycli, '--package', 'pyqt5', '--output',
# configuration, '--target', target.name, 'configure')
args = [host.interpreter, 'configure.py', '--static', '--qmake',
host.qmake, '--sysroot', str(host.sysroot), '--no-tools',
'--no-qsci-api', '--no-designer-plugin', '--no-python-dbus',
'--no-qml-plugin', '--no-stubs', '--configuration', configuration,
'--sip', host.sip, '--confirm-license', '-c', '-j2']
if debug:
args.append('--debug')
host.run(*args)
host.run(host.make)
host.run(host.make, 'install')
我只为 QtCore、QtGui 和 QtWidgets 提供了这个功能,但其他的可能是可行的。
【讨论】:
以上是关于PyQt 静态构建在 make 时失败的主要内容,如果未能解决你的问题,请参考以下文章
调用“make -j8 -l8”失败。构建ros工作区时ar_track_alvar包出错
ios iPhone / iPad - 带有 GData 静态库 libGDataTouchStaticLib.a 的项目在构建时失败(重复符号)