1

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?

gelonida
  • 5,327
  • 2
  • 23
  • 41

4 Answers4

1

As alternative, a solution could be found in PyInstaller bug 5400 Here the steps:

1- download the PyInstaller helper in CEFpython named hook-cefpython3.py from: https://github.com/cztomczak/cefpython/tree/master/examples/pyinstaller and put in the root directory of your project

2- In that file, replace the line:

from PyInstaller.compat import is_win, is_darwin, is_linux, is_py2

with:

from PyInstaller.compat import is_win, is_darwin, is_linux
is_py2 = False

3- in your PyInstaller .spec file, add the '.' to the hookspath, e.g. hookspath=['.']. I think it is also possible to add it as PyInstaller command line option.

These steps should solve the problem, until CEFPython deliver a correct version of the hook file.

Giacomo Catenazzi
  • 8,519
  • 2
  • 24
  • 32
  • thanks for your answer will try asap. This looks definitely cleaner than my approach – gelonida Jan 15 '21 at 14:13
  • Doesn't work for me. Can you please post the exact versions of pyinstaller / cefpython / python and check if it works for you? – gelonida Jan 15 '21 at 23:43
  • @gelonida: PyInstaller 4.1, cef: the last, which it is getting older, python 3.7 (just because cef doesn't support newer Pythons). For now I just tested in Windows (I come last week to this page, but not valid in Windows, so I continued searching). But still not much test (and I need to build also for other OS). -- Maybe I missed a point. Monday (at work) I should be able to verify. – Giacomo Catenazzi Jan 16 '21 at 12:05
  • With my question's example and the versions I tried I never had issues with windows. (On windows it worked just as expected) But as mentioned in my question: I used PyInstaller 3.2.1 What I guess is, that your fix is required for newer versions of PyInstaller and fixes for windows. Unfortunately it doesn't seem to fix for Linux. When I have more time I will try your fix with a newer version of pyinstaller and Linux. Perhaps this combination will work. – gelonida Jan 17 '21 at 09:03
  • just tried with linux python3.5, cefpython3==66.0 and pyinstaller==4.1 (and also pyinstaller==4.2) Still same error. :-( – gelonida Jan 17 '21 at 09:37
0

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?

gelonida
  • 5,327
  • 2
  • 23
  • 41
  • accepting my own answer as no other answer showed up for over one month. Will change the accepted answer as soon as a better one shows up. – gelonida Dec 04 '20 at 00:03
  • See also: https://github.com/pyinstaller/pyinstaller/issues/5400 – Giacomo Catenazzi Jan 14 '21 at 12:08
  • @GiacomoCatenazzi I tried to understand the discussion. Did I understand well? Is this the right synthesis? There is still no solution, but that the discussion is ongoing and a fix to cefpython is the suggestion to fix the situation. – gelonida Jan 14 '21 at 16:12
  • But there is an other workaround: 1- copy the installation file from cef, 2- remove the python2 import/condition 3- adapt the spec file so that hook are read. Then we have a working version. Compared to your solution, that one works in Windows (it has no symlink). – Giacomo Catenazzi Jan 15 '21 at 08:03
  • @GiacomoCatenazzi Can you post this as answer and I will accept it. I just posted and accepted my answer as nothing better existed. Your solution sounds already better until the problem is fixed at the root. – gelonida Jan 15 '21 at 11:35
0

To solve this, you need to set this in your spec file:

hookspath=[r'YOUR_ENV_SITE_PACKAGES\cefpython3\examples\pyinstaller\']

And then rebuild, you will have things in the right place.

wuerfelfreak
  • 2,363
  • 1
  • 14
  • 29
Trappa
  • 1
0

The following steps solved the issue for me on Windows 10, Python 3.9.5 32-bit, PyInstaller 4.3, and CEFPython 66.1:

  1. Download the hook-cefpython3.py file from here and put it into your project root directory.

  2. Run the pyinstaller command as usual but add the --additional-hooks-dir . command line option, so the command will look like this:

    pyinstaller --additional-hooks-dir . <main-file.py>

As opposed to other answers here, this anser neither requires changes of hookspath directive in pyinstaller's spec file and, as of now, nor any changes to the downloaded hook-cefpython3.py file.

Adam
  • 1,926
  • 23
  • 21