从源代码构建¶
重要
本页面主要介绍如何从源代码构建Qt for Python。 如果您只想安装PySide6,您需要运行:pip install pyside6。
一般要求¶
在构建Qt for Python之前,必须安装以下先决条件。
在Linux上,您可以通过操作系统的包管理器获取它们,在macOS上,
您可以通过brew
获取它们,而在Windows上,您可以从每个网站下载安装程序。
Python: 3.9+ [official Python website]
Qt: 6.8+ [在线安装程序]
CMake: 3.18+ [official CMake website]
Git: 2.0+. [official Git website]
libclang: libclang库,推荐版本:6.8+使用18+版本。每个操作系统的预构建版本可以在这里下载。
查看Qt支持的平台
每个平台的指南¶
您可以参考以下页面获取平台特定的说明:
重要
Qt for Python 目前还不支持 WebAssembly 和移动操作系统(Android 或 iOS)。 大多数基于 Linux 的嵌入式操作系统都通过其官方包管理器提供 PySide(例如,Raspbian 和 ArchlinuxARM)。
一个正常的构建命令将如下所示:
python setup.py install --qtpaths=/path/to/qtpaths \
--ignore-git \
--debug \
--build-tests \
--parallel=8 \
--verbose-build \
--module-subset=Core,Gui,Widgets
这将构建并安装带有调试符号的项目,包括测试,
使用ninja(而不是make),并且仅考虑QtCore
、QtGui
和QtWidgets
的模块子集。
CMake Unity Build Mode 默认用于加速。
- Other important options to consider are:
--cmake
,用于指定cmake二进制文件的路径,--reuse-build
,仅重建修改过的文件,--openssl=/path/to/openssl/bin
, 使用不同的路径来访问OpenSSL,--standalone
,将Qt库复制到最终包中,以便在其他机器上运行,--build-docs
,用于启用文档构建。--doc-build-online
, 使用在线模板构建文档(默认情况下使用离线模板)
测试安装¶
安装完成后,您将能够执行我们的任何示例:
python examples/widgets/widgets/tetrix/tetrix.py
运行测试¶
使用 --build-tests
选项将使我们能够在项目内运行所有自动测试:
python testrunner.py test > testlog.txt
注意
在Windows上,不要忘记将qtpaths添加到你的路径中 (set PATH=C:\Path\to\Qt\6.4.0\msvc2019_64\bin;%PATH%)
你也可以通过运行以下命令来运行特定的测试(例如 qpainter_test
):
ctest -R qpainter_test --verbose
交叉编译¶
从6.3版本开始,可以交叉编译Shiboken(模块)和PySide。此功能仍处于技术预览阶段,这意味着在未来的版本中可能会有所变化。
重要
唯一支持的配置是使用主机Linux机器交叉编译到Linux目标平台。
跨平台编译软件是许多项目依赖的有效用例,然而,这是一个复杂的过程,可能会由于多种原因而失败。
在开始这个过程之前,了解构建系统的细节以及交叉编译的目标是很重要的。
在构建过程中,Host
是您当前用于编译的计算机,而 Target
是您为其编译的嵌入式设备。
Qt for Python 正在使用 setuptools 构建,并依赖于一个 setup.py
文件
该文件被递归调用以构建 Shiboken(模块)、
Shiboken(生成器)和 PySide。由于生成器正在创建
绑定的包装器,它不会为目标进行交叉编译。
只有 Shiboken(模块)和 PySide 是交叉编译的。
构建过程需要在主机和目标上安装Qt和Python解释器。两个平台上使用的Qt版本应具有相同的次要版本。也就是说,Qt 6.3(主机)不能与Qt 6.2(目标)一起使用,反之亦然。
注意
建议在主机和目标上使用相同版本的Qt,以避免可能出现的不常见错误。
先决条件¶
首先,您需要访问目标设备,因为您需要复制几个系统文件(sysroot)。我们推荐使用具有最新Qt版本的Linux操作系统,例如Manjaro ARM或Archlinux ARM。
(target) 使用包管理器在系统上安装 Qt 6.3+。
(host) 使用包管理器或Qt安装程序在系统上安装Qt 6.3+。
(target, host) 安装提供C++头文件、链接器、库和编译器的库和开发包。
(target, host) 安装 Python 解释器 v3.7 或更高版本
(target, host) 安装 CMake 3.17+
安装这些先决条件后,将target
sysroot复制到您的host
计算机上。这个过程很棘手,因为从另一台计算机复制系统文件可能会导致符号链接出现问题。在这里,您有两种选择来实现这一点。
选项A:复制文件¶
创建一个目录来复制目标设备的系统根目录,
例如 rpi-sysroot
,并在您的主机电脑上执行复制操作:
rsync -vR --progress -rl --delete-after --safe-links \
USERNAME@TARGET_IP:/{lib,usr,opt/vc/lib} rpi-sysroot/
请确保将USERNAME
和TARGET_IP
替换为适合您系统的值。
选项 B:打包文件系统¶
为你的目标系统根目录创建一个包:
tar cfJ ~/sysroot.tar.xz /lib /usr /opt/vc/lib
将包从目标复制到您的主机:
rsync -vR --progress USERNAME@TARGET_IP:sysroot.tar.xz .
一旦你有了tar文件,请在rpi-sysroot
目录内解压它。
修复符号链接¶
建议运行以下脚本来修复您在符号链接中发现的大部分问题:
import sys
from pathlib import Path
import os
# Take a sysroot directory and turn all the absolute symlinks and turn them into
# relative ones such that the sysroot is usable within another system.
if len(sys.argv) != 2:
print(f"Usage is {sys.argv[0]} <sysroot-directory>")
sys.exit(-1)
topdir = Path(sys.argv[1]).absolute()
def handlelink(filep, subdir):
link = filep.readlink()
if str(link)[0] != "/":
return
if link.startswith(topdir):
return
relpath = os.path.relpath((topdir / link).resolve(), subdir)
os.unlink(filep)
os.symlink(relpath, filep)
for f in topdir.glob("**/*"):
if f.is_file() and f.is_symlink():
handlelink(f, f.parent)
设置工具链¶
要进行交叉编译,您需要一组特殊的编译器、库和头文件,这些工具在主机架构上运行,但为目标架构生成(二进制文件/可执行文件)。例如,从x86_64到aarch64。
建议使用官方的10.2 ARM开发者交叉编译器,您可以在他们的官方网站上找到。在本教程中,我们选择aarch64
目标架构,并假设您已经下载了gcc-arm-10.2-2020.11-x86_64-aarch64-none-linux-gnu.tar.xz文件,并解压了它。
使用这些编译器,现在你需要一个CMake工具链文件。这是一个配置文件,用于设置编译器、系统根目录信息,以及编译标志等额外选项和其他细节。你可以使用以下文件作为示例,但请记住它们可能会有所不同:
# toolchain-aarch64.cmake
cmake_minimum_required(VERSION 3.18)
include_guard(GLOBAL)
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR aarch64)
set(TARGET_SYSROOT /path/to/your/target/sysroot)
set(CROSS_COMPILER /path/to/your/crosscompiling/compilers/)
set(CMAKE_SYSROOT ${TARGET_SYSROOT})
set(ENV{PKG_CONFIG_PATH} "")
set(ENV{PKG_CONFIG_LIBDIR} ${CMAKE_SYSROOT}/usr/lib/pkgconfig:${CMAKE_SYSROOT}/usr/share/pkgconfig)
set(ENV{PKG_CONFIG_SYSROOT_DIR} ${CMAKE_SYSROOT})
set(CMAKE_C_COMPILER ${CROSS_COMPILER}/aarch64-none-linux-gnu-gcc)
set(CMAKE_CXX_COMPILER ${CROSS_COMPILER}/aarch64-none-linux-gnu-g++)
set(QT_COMPILER_FLAGS "-march=armv8-a")
set(QT_COMPILER_FLAGS_RELEASE "-O2 -pipe")
set(QT_LINKER_FLAGS "-Wl,-O1 -Wl,--hash-style=gnu -Wl,--as-needed")
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
include(CMakeInitializeConfigs)
function(cmake_initialize_per_config_variable _PREFIX _DOCSTRING)
if (_PREFIX MATCHES "CMAKE_(C|CXX|ASM)_FLAGS")
set(CMAKE_${CMAKE_MATCH_1}_FLAGS_INIT "${QT_COMPILER_FLAGS}")
foreach (config DEBUG RELEASE MINSIZEREL RELWITHDEBINFO)
if (DEFINED QT_COMPILER_FLAGS_${config})
set(CMAKE_${CMAKE_MATCH_1}_FLAGS_${config}_INIT "${QT_COMPILER_FLAGS_${config}}")
endif()
endforeach()
endif()
if (_PREFIX MATCHES "CMAKE_(SHARED|MODULE|EXE)_LINKER_FLAGS")
foreach (config SHARED MODULE EXE)
set(CMAKE_${config}_LINKER_FLAGS_INIT "${QT_LINKER_FLAGS}")
endforeach()
endif()
_cmake_initialize_per_config_variable(${ARGV})
endfunction()
你需要调整这两行中的路径:
set(TARGET_SYSROOT /path/to/your/target/sysroot)
set(CROSS_COMPILER /path/to/your/crosscompiling/compilers/)
并将它们替换为sysroot目录(我们称之为rpi-sysroot
),
以及编译器(gcc-arm-10.2-2020.11-x86_64-aarch64-none-linux-gnu/bin
目录)。
交叉编译PySide¶
在您安装了先决条件并复制了必要的文件后,您应该有以下内容:
用于交叉编译的编译器 (
gcc-argm-10.2-...
),目标系统根目录 (
rpi-sysroot
),工具链 cmake 文件 (
toolchain-aarch64.cmake
),pyside-setup
仓库,
一个setup.py
调用的示例如下所示:
python setup.py bdist_wheel \
--parallel=8 --ignore-git --reuse-build --standalone --limited-api=yes \
--cmake-toolchain-file=/opt/toolchain-aarch64.cmake \
--qt-host-path=/opt/Qt/6.3.0/gcc_64 \
--plat-name=linux_aarch64
根据目标平台的不同,您可以使用 linux_armv7
、
linux_aarch64
等。
对于嵌入式平台,通常没有完全构建的Qt及其工具,可以使用选项--no-qt-tools
来防止工具的捆绑。
如果过程成功,您将在dist/
目录中找到目标轮子,例如:
PySide6-6.3.0-6.3.0-cp36-abi3-manylinux2014_aarch64.whl
shiboken6-6.3.0-6.3.0-cp36-abi3-manylinux2014_aarch64.whl
故障排除¶
如果自动检测机制无法找到目标设备中的Python或Qt安装,你可以使用两个额外的选项:
--python-target-path=...
以及:
--qt-target-path=...
如果主机Shiboken(生成器)的自动构建失败,您可以使用以下方式指定自定义路径:
--shiboken-host-path=...
构建文档¶
从6.3版本开始,默认情况下不再构建文档。
当使用本节中描述的第二个选项时,请确保使用
--build-docs
选项。
在你的Python虚拟环境中安装特定的文档要求:
pip install -r requirements-doc.txt
你可以在仓库的根目录中找到requirements-doc.txt
文件。
从5.15开始,有两种构建文档的选项:
1. 构建基础文档(无API)¶
解析Qt头文件以生成PySide API文档的过程可能需要几分钟,这意味着修改我们当前文档的特定部分可能会变得困难。您可能只关心基础文档,它包括除API文档之外的所有文档。
要生成这个,请执行以下命令:
python setup.py build_base_docs
这将生成一个html/
目录,其结构如下:
html
└── pyside6
├── index.html
├── ...
└── shiboken6
├── index.html
└── ...
所以你可以在浏览器中打开主页面 html/pyside6/index.html
来检查生成的文件。
这在更新文档的通用部分、添加教程、修改构建说明等方面非常有用。
注意
如果你只对生成示例库感兴趣,
你需要运行python tools/example_gallery/main.py
来
为库生成示例documentation
。这也会被
build_base_docs
目标内部使用。
2. 构建文档(基础 + API)¶
文档正在使用qdoc生成以获取API信息,同时使用sphinx生成本地Python相关笔记。
系统需要libxml2
和libxslt
库。
安装graphviz
(包含在requirements-doc.txt
文件中)后,
dot
命令需要在PATH中,否则,
该过程将失败。系统范围内安装graphviz
也是一个选项。
由于该过程依赖于Qt安装,您需要通过命令行选项--qt-src-dir
指定Qt源代码树中qtbase
目录的位置。
一旦常见的setup.py
构建过程完成(记得使用
--build-docs
来启用文档构建,以及--doc-build-online
来获取HTML文件),你可以前往生成的
build/
目录,并运行:
ninja apidoc
你可以添加-j X
,以使用X个进程并行执行构建过程。
注意
apidoc 构建目标默认生成离线文档,格式为 QCH
(Qt 压缩帮助)。你可以通过配置选项 --doc-build-online
切换到生成在线使用的文档。
目标执行以下几个步骤:
qdoc
工具在 Qt 源代码上运行,以生成 WebXML 格式的文档。shiboken6
用于从 WebXML 中提取存在绑定的函数并将其转换为 RST。sphinx
运行以生成HTML格式的文档。
重新运行命令不会执行步骤1,除非从构建树中删除文件
qdoc-output/webxml/qtcore-index.webxml
。
同样,步骤2也不会执行,除非删除文件 base/PySide6/QtCore/index.rst
。
最后,你将得到一个包含所有生成文档的html
目录。离线帮助文件PySide.qch
和Shiboken.qch
可以移动到您选择的任何目录。你可以在构建目录build/
中找到Shiboken.qch
。
如果你想暂时更改一个.rst
文件以检查对格式的影响,你可以在doc
目录中重新运行sphinx
:
sphinx-build base html
查看离线文档¶
离线文档(QCH)可以使用Qt Creator IDE或Qt Assistant查看,后者是一个用于查看QCH文件的独立应用程序。
要使用Qt Creator查看QCH,请按照使用Qt Creator帮助模式中概述的说明进行操作。 如果您选择使用Qt Assistant,请在启动Qt Assistant之前使用以下命令注册QCH文件:
assistant -register PySide.qch
故障排除文档¶
文档使用 intersphinx 从 PySide 链接到 Shiboken 文档。如果以下情况发生,可能会失败:
默认使用
QCH
格式;在这种情况下,不会生成所需的objects.inv
文件。请使用--doc-build-online
。基础文档和完整文档构建混合在一起,导致CMake文件中的intersphinx位置值错误。重新运行
cmake
以修复此问题。
使用内部工具¶
在pyside-setup
仓库中的tools/
目录下可以找到一组工具。
checklibs.py
: 用于分析Mach-O二进制文件的动态库依赖关系的脚本。 要使用此工具,只需运行:python checklibs.py /path/to/some.app/Contents/MacOS/Some
此脚本是从这个仓库获取的。
create_changelog.py
: 用于创建CHANGELOG的脚本,你可以在dist/
目录中找到它。使用方法:python create_changelog.py -r 6.0.1 -v v6.0.0..6.0 -t bug-fix
debug_windows.py
: 该脚本可用于找出PySide模块加载失败的原因,例如DLL缺失或DLL中缺少符号等错误。你可以将其视为Windows版本的ldd /
LD_DEBUG
。在底层,它使用了cdb.exe命令行调试器和gflags.exe工具,这些工具随最新的Windows Kit一起安装。
其目的是帮助开发人员调试在Windows上使用PySide导入时可能遇到的问题。用户应提供生成的日志文件。
顺便说一下,它也可以用于任何Windows可执行文件,而不仅仅是Python。要使用它,只需运行:
python debug_windows.py
missing_bindings.py
: 该脚本用于比较PySide和PyQt在可用模块和类方面的状态。此内容显示在我们的wiki页面上,并可以如下使用:python missing_bindings.py --qt-version 6.0.1 -w all
注意
该脚本依赖于BeautifulSoup来解析内容并生成缺失绑定的列表。