无法在 Linux 上使用 pyinstaller 和 cefpython 创建可执行文件(ICU 数据的文件描述符无效)
Posted
技术标签:
【中文标题】无法在 Linux 上使用 pyinstaller 和 cefpython 创建可执行文件(ICU 数据的文件描述符无效)【英文标题】:failed to create executable with pyinstaller and cefpython on Linux (Invalid file descriptor to ICU data) 【发布时间】:2020-10-13 16:13:30 【问题描述】:我有一些简单的 cefpython 代码打开一个 url,并试图用 pyinstaller 创建一个独立的可执行文件:
我将文件从https://github.com/cztomczak/cefpython/tree/master/examples/pyinstaller 复制到名为pyinstaller
的目录中
我对 pyinstaller.spec 做了以下小改动
+SECRET_CIPHER = ""
...
- ["../wxpython.py"],
+ ["../hello.py"],
...
- icon="../resources/wxpython.ico")
+ )
我可以在 windows 上使用 python 成功编译我的应用程序 在具有 python 3.5.4 64 位和以下 virtualenv 的同一台机器上:
cefpython3==66.0
future==0.18.2
PyInstaller==3.2.1
pypiwin32==223
pywin32==228
我也可以用 python 3.6.4 64 和以下 virtualenv 编译 windows:
altgraph==0.17
cefpython3==66.0
future==0.18.2
macholib==1.14
pefile==2019.4.18
PyInstaller==3.3.1
pyinstaller-hooks-contrib==2020.9
pypiwin32==223
pywin32==228
pywin32-ctypes==0.2.0
在 Linux 上编译也可以,但可执行文件无法运行。
我得到以下输出和错误:
CEF Python 66.0
Chromium 66.0.3359.181
CEF 3.3359.1774.gd49d25f
Python 3.5.2 64bit
[1013/180954.001980:ERROR:icu_util.cc(133)] Invalid file descriptor to ICU data received.
Trace/breakpoint trap (core dumped)
版本是python 3.5.2 64bit,virtualenv是:
cefpython3==66.0
pkg-resources==0.0.0
PyInstaller==3.2.1
可能是什么原因?
我尝试编译的代码如下:
import platform
import sys
from cefpython3 import cefpython as cef
def check_versions():
ver = cef.GetVersion()
print("CEF Python ver".format(ver=ver["version"]))
print("Chromium ver".format(ver=ver["chrome_version"]))
print("CEF ver".format(ver=ver["cef_version"]))
print("Python ver arch".format(
ver=platform.python_version(),
arch=platform.architecture()[0]))
assert cef.__version__ >= "57.0", "CEF Python v57.0+ required to run this"
def main(url="https://www.***.com"):
sys.excepthook = cef.ExceptHook
check_versions()
settings =
switches =
browser_settings =
cef.Initialize(settings=settings, switches=switches)
cef.CreateBrowserSync(
url=url,
window_title="CEF_HELLO: ",
settings=browser_settings,
)
cef.MessageLoop()
cef.Shutdown()
if __name__ == "__main__":
main()
附录:2020-10-14:
在 linux 上与其他版本相同的错误: 到目前为止,我尝试了 python 3.5 和 3.7
是否有人成功创建了可执行文件? 我可能是,这只是示例项目及其配置的问题?
【问题讨论】:
【参考方案1】:作为替代方案,可以在PyInstaller bug 5400 中找到解决方案 步骤如下:
1- 在 CEFpython 中下载名为 hook-cefpython3.py
的 PyInstaller 帮助程序:
https://github.com/cztomczak/cefpython/tree/master/examples/pyinstaller 放到你项目的根目录下
2- 在该文件中,替换以下行:
from PyInstaller.compat import is_win, is_darwin, is_linux, is_py2
与:
from PyInstaller.compat import is_win, is_darwin, is_linux
is_py2 = False
3- 在您的 PyInstaller .spec
文件中,将 '.'
添加到 hookspath
,例如hookspath=['.']
。我认为也可以将其添加为 PyInstaller 命令行选项。
这些步骤应该可以解决问题,直到 CEFPython 提供正确版本的挂钩文件。
【讨论】:
感谢您的回答,我们会尽快尝试。这看起来绝对比我的方法更干净 对我不起作用。您能否发布 pyinstaller / cefpython / python 的确切版本并检查它是否适合您? @gelonida:PyInstaller 4.1,cef:最后一个,它越来越旧,python 3.7(只是因为 cef 不支持较新的 Python)。现在我只是在 Windows 中测试(我上周来到这个页面,但在 Windows 中无效,所以我继续搜索)。但仍然没有太多测试(我还需要为其他操作系统构建)。 ——也许我错过了一点。星期一(上班)我应该可以验证。 通过我的问题示例和我尝试过的版本,我从来没有遇到过 Windows 问题。 (在 Windows 上它按预期工作)但正如我的问题中提到的:我使用了 PyInstaller 3.2.1 我猜是,更新版本的 PyInstaller 和 Windows 修复需要您的修复。不幸的是,它似乎无法修复 Linux。当我有更多时间时,我会尝试使用更新版本的 pyinstaller 和 Linux 进行修复。也许这种组合会奏效。 刚刚尝试使用 linux python3.5、cefpython3==66.0 和 pyinstaller==4.1(还有 pyinstaller==4.2)还是同样的错误。 :-(【参考方案2】:这并不是我真正愿意接受的答案,但它至少是一种解决方案并包含信息,可能会导致更好的解决方案,更好的答案。
在使用 strace 调试后,我发现可执行文件搜索了许多文件,例如 icudtl.dat
、v8_context_snapshot.bin
、locales/*
'dist/cefapp/cefpython3but were copied to
dist/cefapp/`
一个丑陋的解决方法是在编译后执行以下操作
cd dist/cefapp/cefpython3
ln -s ../* .
并且可执行文件有效。
我确信还有一个更好的非暴力解决方案,但暂时我想回答一下,以防其他人也被卡住
也许这可以在规范文件中修复,但是我们需要一个用于 linux 的规范文件和一个用于 Windows 的规范文件吗? 也许还有一个选项可以告诉可执行文件搜索这些文件更高一级?
【讨论】:
接受我自己的答案,因为一个多月没有出现其他答案。一旦出现更好的答案,将立即更改已接受的答案。 另见:github.com/pyinstaller/pyinstaller/issues/5400 @GiacomoCatenazzi 我试图理解讨论。我理解的好吗?这是正确的合成吗?仍然没有解决方案,但讨论仍在进行中,对 cefpython 的修复是解决这种情况的建议。 但还有其他解决方法:1- 从 cef 复制安装文件,2- 删除 python2 导入/条件 3- 调整规范文件以便读取挂钩。然后我们有一个工作版本。与您的解决方案相比,该解决方案适用于 Windows(它没有符号链接)。 @GiacomoCatenazzi 你能把这个作为答案发布,我会接受。我刚刚发布并接受了我的答案,因为没有比这更好的了。在问题从根本上解决之前,您的解决方案听起来已经更好了。【参考方案3】:要解决这个问题,您需要在规范文件中进行设置:
hookspath=[r'YOUR_ENV_SITE_PACKAGES\cefpython3\examples\pyinstaller\']
然后重建,你会在正确的地方有东西。
【讨论】:
【参考方案4】:以下步骤解决了我在 Windows 10、Python 3.9.5 32 位、PyInstaller 4.3 和 CEFPython 66.1 上的问题:
下载hook-cefpython3.py file from here并将其放入您的项目根目录。
像往常一样运行 pyinstaller 命令,但添加 --additional-hooks-dir .
命令行选项,因此命令将如下所示:
pyinstaller --additional-hooks-dir 。
与此处的其他答案相反,此分析器既不需要更改 pyinstaller 的规范文件中的 hookspath
指令,也不需要更改下载的 hook-cefpython3.py 文件。
【讨论】:
谢谢。会尝试。但请注意,我遇到的问题只是 Linux以上是关于无法在 Linux 上使用 pyinstaller 和 cefpython 创建可执行文件(ICU 数据的文件描述符无效)的主要内容,如果未能解决你的问题,请参考以下文章
PyInstaller Winerror3:系统无法找到指定的路径
使用 Fbs/PyInstaller 冻结我的应用程序导致在另一台电脑上启动时无法执行 pyi_rth_qt5plugins