为什么 GitLab CI 上的 PySide6 会导致 ImportError?

Why does PySide6 on GitLab CI result in ImportError?

我正在尝试使用 docker hub python 3.8 image 在 CI 环境(公司内部 GitLab 实例)上安装 PySide6,但是从 PySide6 导入时遇到问题。下面是 .gitlab-ci.yml 文件的相关部分,其中 $IMAGE 引用上面提到的 docker 图像。

test-pyside6
  stage: testing
  image: $IMAGE
  script:
    - python -m venv .venv
    - . .venv/bin/activate
    - which python
    - python --version
    - python -m pip install --upgrade pip setuptools wheel
    - python -m pip install PySide6
    - python -c 'import PySide6; print(PySide6.__version__)'
    - ldd <snip>/.venv/lib/python3.8/site-packages/PySide6/Qt/lib/libQt6Core.so.6
    - python -c 'import PySide6.QtCore'

输出符合预期,除了最后一行在导入 QtCore 时出错。据我所知,ldd 的结果也很好(没有“未找到”消息)。请注意,import PySide6 工作得很好。

Executing "step_script" stage of the job script
$ python -m venv .venv
$ . .venv/bin/activate
$ which python
<snip>/.venv/bin/python
$ python --version
Python 3.8.10
$ python -m pip install --upgrade pip setuptools wheel
<snip>
Successfully installed pip-21.2.4 setuptools-58.0.4 wheel-0.37.0
$ python -m pip install PySide6
<snip>
Successfully installed PySide6-6.1.3 shiboken6-6.1.3
$ python -c 'import PySide6; print(PySide6.__version__)'
6.1.3
$ ldd <snip>/.venv/lib/python3.8/site-packages/PySide6/Qt/lib/libQt6Core.so.6
    linux-vdso.so.1 (0x00007ffd55f54000)
    libicui18n.so.56 => <snip>/.venv/lib/python3.8/site-packages/PySide6/Qt/lib/libicui18n.so.56 (0x00007f82c43ad000)
    libicuuc.so.56 => <snip>/.venv/lib/python3.8/site-packages/PySide6/Qt/lib/libicuuc.so.56 (0x00007f82c3ff5000)
    libicudata.so.56 => <snip>/.venv/lib/python3.8/site-packages/PySide6/Qt/lib/libicudata.so.56 (0x00007f82c2612000)
    libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f82c2604000)
    libglib-2.0.so.0 => /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0 (0x00007f82c24e5000)
    libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f82c24c2000)
    libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007f82c22a4000)
    libgthread-2.0.so.0 => /usr/lib/x86_64-linux-gnu/libgthread-2.0.so.0 (0x00007f82c229f000)
    librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007f82c2295000)
    libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f82c2111000)
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f82c1f8e000)
    libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f82c1f74000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f82c1db1000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f82c4e46000)
    libpcre.so.3 => /lib/x86_64-linux-gnu/libpcre.so.3 (0x00007f82c1d3d000)
$ python -c 'import PySide6.QtCore'
Traceback (most recent call last):
  File "<string>", line 1, in <module>
ImportError: libQt6Core.so.6: cannot open shared object file: No such file or directory

我还尝试了很多其他的东西,都出现了同样的错误信息:

接下来,我安装了strace并将最后一行更改为:

    - strace -o output.txt python -c 'from PySide6 import QtCore' || true
    - cat "output.txt"

下面是输出的片段

$ strace -s 300 -o output.txt python -c 'from PySide6 import QtCore' || true
Traceback (most recent call last):
  File "<string>", line 1, in <module>
ImportError: libQt6Core.so.6: cannot open shared object file: No such file or directory
$ cat "output.txt"
<snip>
openat(AT_FDCWD, "<snip>/.venv/lib/python3.8/site-packages/PySide6/libpyside6.abi3.so.6.1", O_RDONLY|O_CLOEXEC) = 3
read(3, "7ELF[=14=][=14=][=14=][=14=][=14=][=14=][=14=][=14=][=14=]>[=14=][=14=][=14=][=14=]01[=14=][=14=][=14=][=14=][=14=][=14=]"..., 832) = 832
lseek(3, 335872, SEEK_SET)              = 335872
read(3, "[=14=][=14=][=14=][=14=][=14=][=14=][=14=][=14=][=14=][=14=][=14=][=14=][=14=][=14=][=14=][=14=][=14=][=14=][=14=][=14=][=14=][=14=][=14=][=14=][=14=][=14=][=14=][=14=][=14=][=14=]"..., 448) = 448
fstat(3, {st_mode=S_IFREG|0755, st_size=354424, ...}) = 0
lseek(3, 335872, SEEK_SET)              = 335872
read(3, "[=14=][=14=][=14=][=14=][=14=][=14=][=14=][=14=][=14=][=14=][=14=][=14=][=14=][=14=][=14=][=14=][=14=][=14=][=14=][=14=][=14=][=14=][=14=][=14=][=14=][=14=][=14=][=14=][=14=][=14=]"..., 448) = 448
mmap(NULL, 2377848, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7ffad0b64000
mprotect(0x7ffad0ba1000, 2109440, PROT_NONE) = 0
mmap(0x7ffad0da0000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x3c000) = 0x7ffad0da0000
mmap(0x7ffad0da3000, 1000, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7ffad0da3000
mmap(0x7ffad0da4000, 20480, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x52000) = 0x7ffad0da4000
close(3)                                = 0
openat(AT_FDCWD, "<snip>/.venv/lib/python3.8/site-packages/PySide6/libQt6Core.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "<snip>/.venv/lib/python3.8/site-packages/PySide6/Qt/lib/tls/haswell/x86_64/libQt6Core.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat("<snip>/.venv/lib/python3.8/site-packages/PySide6/Qt/lib/tls/haswell/x86_64", 0x7fff8bf4e570) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "<snip>/.venv/lib/python3.8/site-packages/PySide6/Qt/lib/tls/haswell/libQt6Core.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat("<snip>/.venv/lib/python3.8/site-packages/PySide6/Qt/lib/tls/haswell", 0x7fff8bf4e570) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "<snip>/.venv/lib/python3.8/site-packages/PySide6/Qt/lib/tls/x86_64/libQt6Core.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat("<snip>/.venv/lib/python3.8/site-packages/PySide6/Qt/lib/tls/x86_64", 0x7fff8bf4e570) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "<snip>/.venv/lib/python3.8/site-packages/PySide6/Qt/lib/tls/libQt6Core.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat("<snip>/.venv/lib/python3.8/site-packages/PySide6/Qt/lib/tls", 0x7fff8bf4e570) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "<snip>/.venv/lib/python3.8/site-packages/PySide6/Qt/lib/haswell/x86_64/libQt6Core.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat("<snip>/.venv/lib/python3.8/site-packages/PySide6/Qt/lib/haswell/x86_64", 0x7fff8bf4e570) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "<snip>/.venv/lib/python3.8/site-packages/PySide6/Qt/lib/haswell/libQt6Core.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat("<snip>/.venv/lib/python3.8/site-packages/PySide6/Qt/lib/haswell", 0x7fff8bf4e570) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "<snip>/.venv/lib/python3.8/site-packages/PySide6/Qt/lib/x86_64/libQt6Core.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat("<snip>/.venv/lib/python3.8/site-packages/PySide6/Qt/lib/x86_64", 0x7fff8bf4e570) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "<snip>/.venv/lib/python3.8/site-packages/PySide6/Qt/lib/libQt6Core.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "7ELF[=14=][=14=][=14=][=14=][=14=][=14=][=14=][=14=][=14=]>[=14=][=14=][=14=][=14=]0@\f[=14=][=14=][=14=][=14=][=14=]"..., 832) = 832
close(3)                                = 0
stat("<snip>/.venv/lib/python3.8/site-packages/PySide6/Qt/lib", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=35925, ...}) = 0
mmap(NULL, 35925, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7ffad0b5b000
close(3)                                = 0
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/tls/haswell/x86_64/libQt6Core.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat("/lib/x86_64-linux-gnu/tls/haswell/x86_64", 0x7fff8bf4e570) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/tls/haswell/libQt6Core.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat("/lib/x86_64-linux-gnu/tls/haswell", 0x7fff8bf4e570) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/tls/x86_64/libQt6Core.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat("/lib/x86_64-linux-gnu/tls/x86_64", 0x7fff8bf4e570) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/tls/libQt6Core.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat("/lib/x86_64-linux-gnu/tls", 0x7fff8bf4e570) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/haswell/x86_64/libQt6Core.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat("/lib/x86_64-linux-gnu/haswell/x86_64", 0x7fff8bf4e570) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/haswell/libQt6Core.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat("/lib/x86_64-linux-gnu/haswell", 0x7fff8bf4e570) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/x86_64/libQt6Core.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat("/lib/x86_64-linux-gnu/x86_64", 0x7fff8bf4e570) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libQt6Core.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat("/lib/x86_64-linux-gnu", {st_mode=S_IFDIR|0755, st_size=50, ...}) = 0
openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/tls/haswell/x86_64/libQt6Core.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat("/usr/lib/x86_64-linux-gnu/tls/haswell/x86_64", 0x7fff8bf4e570) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/tls/haswell/libQt6Core.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat("/usr/lib/x86_64-linux-gnu/tls/haswell", 0x7fff8bf4e570) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/tls/x86_64/libQt6Core.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat("/usr/lib/x86_64-linux-gnu/tls/x86_64", 0x7fff8bf4e570) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/tls/libQt6Core.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat("/usr/lib/x86_64-linux-gnu/tls", 0x7fff8bf4e570) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/haswell/x86_64/libQt6Core.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat("/usr/lib/x86_64-linux-gnu/haswell/x86_64", 0x7fff8bf4e570) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/haswell/libQt6Core.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat("/usr/lib/x86_64-linux-gnu/haswell", 0x7fff8bf4e570) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/x86_64/libQt6Core.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat("/usr/lib/x86_64-linux-gnu/x86_64", 0x7fff8bf4e570) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/libQt6Core.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat("/usr/lib/x86_64-linux-gnu", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
openat(AT_FDCWD, "/lib/tls/haswell/x86_64/libQt6Core.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat("/lib/tls/haswell/x86_64", 0x7fff8bf4e570) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib/tls/haswell/libQt6Core.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat("/lib/tls/haswell", 0x7fff8bf4e570) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib/tls/x86_64/libQt6Core.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat("/lib/tls/x86_64", 0x7fff8bf4e570) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib/tls/libQt6Core.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat("/lib/tls", 0x7fff8bf4e570)        = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib/haswell/x86_64/libQt6Core.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat("/lib/haswell/x86_64", 0x7fff8bf4e570) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib/haswell/libQt6Core.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat("/lib/haswell", 0x7fff8bf4e570)    = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib/x86_64/libQt6Core.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat("/lib/x86_64", 0x7fff8bf4e570)     = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib/libQt6Core.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat("/lib", {st_mode=S_IFDIR|0755, st_size=41, ...}) = 0
openat(AT_FDCWD, "/usr/lib/tls/haswell/x86_64/libQt6Core.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat("/usr/lib/tls/haswell/x86_64", 0x7fff8bf4e570) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/lib/tls/haswell/libQt6Core.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat("/usr/lib/tls/haswell", 0x7fff8bf4e570) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/lib/tls/x86_64/libQt6Core.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat("/usr/lib/tls/x86_64", 0x7fff8bf4e570) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/lib/tls/libQt6Core.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat("/usr/lib/tls", 0x7fff8bf4e570)    = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/lib/haswell/x86_64/libQt6Core.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat("/usr/lib/haswell/x86_64", 0x7fff8bf4e570) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/lib/haswell/libQt6Core.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat("/usr/lib/haswell", 0x7fff8bf4e570) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/lib/x86_64/libQt6Core.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat("/usr/lib/x86_64", 0x7fff8bf4e570) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/lib/libQt6Core.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat("/usr/lib", {st_mode=S_IFDIR|0755, st_size=30, ...}) = 0
munmap(0x7ffad0b5b000, 35925)           = 0
munmap(0x7ffad0da9000, 7836840)         = 0
munmap(0x7ffad0b64000, 2377848)         = 0
openat(AT_FDCWD, "<string>", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "<string>", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/local/lib/python38.zip/<string>", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/local/lib/python3.8/<string>", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/local/lib/python3.8/lib-dynload/<string>", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "<snip>/.venv/lib/python3.8/site-packages/<string>", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
write(2, "Traceback (most recent call last"..., 162) = 162
rt_sigaction(SIGINT, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7ffad26e4730}, {sa_handler=0x7ffad2835052, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7ffad26e4730}, 8) = 0
munmap(0x7ffad1523000, 262144)          = 0
sigaltstack(NULL, {ss_sp=0x558a1d689910, ss_flags=0, ss_size=16384}) = 0
sigaltstack({ss_sp=NULL, ss_flags=SS_DISABLE, ss_size=0}, NULL) = 0
exit_group(1)                           = ?
+++ exited with 1 +++

我相信它表明从下面的摘录中找到了库(这是文件存在的正确位置)。

openat(AT_FDCWD, "<snip>/.venv/lib/python3.8/site-packages/PySide6/Qt/lib/libQt6Core.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "7ELF[=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=][=15=]>[=15=][=15=][=15=][=15=]0@\f[=15=][=15=][=15=][=15=][=15=]"..., 832) = 832
close(3)                                = 0

为什么它在找到 libQt6Core.so.6 之后还在其他地方继续寻找?为什么它在找到时报告未找到?还有什么我可以尝试使这项工作成功的吗?对于它的价值,将 PySide6 更改为 PySide2 工作得很好。但显然,我正在尝试在这里使用 PySide6。最后,在我的个人 Ubuntu 机器上安装相同版本的 PySide6,也在虚拟环境中,工作正常。

我找到了解决方案,尽管我不得不承认我完全不知道这实际上是做什么的:

https://askubuntu.com/a/1163268

所以在虚拟环境中安装PySide6后,我在libQt6Core库上添加了strip命令如下图。然后导入工作正常。

test-pyside6
  stage: testing
  image: $IMAGE
  script:
    - python -m venv .venv
    - . .venv/bin/activate
    - which python
    - python --version
    - python -m pip install --upgrade pip setuptools wheel
    - python -m pip install PySide6
    - strip --remove-section=.note.ABI-tag <snip>/.venv/lib/python3.8/site-packages/PySide6/Qt/lib/libQt6Core.so.6
    - python -c 'import PySide6; print(PySide6.__version__)'
    - ldd <snip>/.venv/lib/python3.8/site-packages/PySide6/Qt/lib/libQt6Core.so.6
    - python -c 'import PySide6.QtCore'