pythonpyinstallercefpython

failed to create executable with pyinstaller and cefpython on Linux (Invalid file descriptor to ICU data)


I have some simple cefpython code opening a url and am trying to create a stand alone executable with pyinstaller:

I copied files from https://github.com/cztomczak/cefpython/tree/master/examples/pyinstaller to a a directry named pyinstaller

I made following minor changes to pyinstaller.spec

+SECRET_CIPHER = ""
...
-    ["../wxpython.py"],
+    ["../hello.py"],
...
-          icon="../resources/wxpython.ico")
+          )
 

I can successfully compile my application on windows with python On the same machine with python 3.5.4 64 bit and following virtualenv:

cefpython3==66.0
future==0.18.2
PyInstaller==3.2.1
pypiwin32==223
pywin32==228

I can also compile windows with python 3.6.4 64 and following virtualenv:

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

On Linux compilation works as well, but the executable is not operational.

I get following output and error:

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)

version is python 3.5.2 64bit and the virtualenv is:

cefpython3==66.0
pkg-resources==0.0.0
PyInstaller==3.2.1

What could be the cause?

The code, that I try to compile is below:

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.stackoverflow.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()

Addendum: 2020-10-14:

same error on linux with other versions: so far I tried python 3.5 and 3.7

Is there anybody who successfully created an executable? I could be, that this just an issue with the example project and its configuration?


Solution

  • This is not really the answer I would like to accept, but it is at least one solution and contains information, that might lead to a better fix, a better answer.

    After debugging with strace I found out, that the executable searches many files like for example icudtl.dat, v8_context_snapshot.bin, locales/* were searched in 'dist/cefapp/cefpython3but were copied todist/cefapp/`

    An ugly work around is to do following after compilation

    cd dist/cefapp/cefpython3
    ln -s ../* .
    

    and the executable works.

    I'm sure there is also a nicer non-brute-force solution, but for the time being I wanted to answer in case others are stuck as well

    Probably this can be fixed in the spec file but would we need one spec file for linux and one for windows then? Perhaps there's also an option to tell the excutable to search for these files one level higer?