We are building a python desktop application that needs to runs on windows and mac. Many of the Python GUI libraries (such as Tkinter) gave the UI a look & feel like it was from the early 2000's. We also tried Kivy, and while it's not bad, after trying CEF, web technologies really do rule on the UI front.
So we have a python backend, and are using Wxpython to render the CEF window, which loads our apps UI (html/css/js).
Before building out further, we are trying to package it (to be safe). However we are having issues packaging using py2exe, py2app and pyInstaller. Are there any tutorials or documentation for packaging CEFpython into a windows and mac app?
Some examples to package one of the CEFpython examples would be helpful.
Any advice would be much appreciated.
--
You received this message because you are subscribed to the Google Groups "CEF Python" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cefpython+...@googlegroups.com.
Visit this group at http://groups.google.com/group/cefpython.
To view this discussion on the web visit https://groups.google.com/d/msgid/cefpython/45165014-9bfd-41b4-9795-f5f7ab8b9525%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
from distutils.sysconfig import get_python_lib
from os.path import join
import sys
from cx_Freeze import setup, Executable
from generic.version import COMMIT_REVISION
ADD_INCLUDES = []
if sys.platform == "win32":
ADD_INCLUDES = [join(get_python_lib(), "cefpython3", "locales"),
join(get_python_lib(), "cefpython3", "d3dcompiler_43.dll"),
join(get_python_lib(), "cefpython3", "d3dcompiler_46.dll"),
join(get_python_lib(), "cefpython3", "ffmpegsumo.dll"),
join(get_python_lib(), "cefpython3", "icudt.dll"),
join(get_python_lib(), "cefpython3", "libEGL.dll"),
join(get_python_lib(), "cefpython3", "libGLESv2.dll"),
join(get_python_lib(), "cefpython3", "cefclient.exe"),
(join(get_python_lib(), "cefpython3", "subprocess.exe"), "my_custom_sub_name.exe"),
join(get_python_lib(), "cefpython3", "cef.pak"),
join(get_python_lib(), "cefpython3", "devtools_resources.pak"),
]
# else .. for LINUX, MAC ans so.on
build_exe_options = {"icon": "res/icon.ico", # some icon for exe from res folder
"packages": ["generic",
"ui",
"requests",
"pickle",
"base64",
"threading",
"os",
"collections",
"PySide",
"cefpython3"
# and others project speciffic modules
],
"excludes": ["PySide.QWebKit"], # exclude QWebKide, it is installed but we don't need this
"optimize": 2,
"compressed": True,
"include_files": ["res"]+ADD_INCLUDES,
"include_msvcr": True,
}
base = None
if sys.platform.startswith("win"):
base = "Win32GUI" #Win32GUI/Console for show stdout and stderr
setup(
name = "Name",
version = str(COMMIT_REVISION / 10),
description = "Desc...",
options = {"build_exe": build_exe_options},
executables = [Executable("your_py", base=base),
]
)
I've used py2exe successfully on Windows and PyInstaller with less success on Linux and Mac. You can see the scripts, including CI build server scripts, I used on my repository: https://github.com/carlosperate/ardublockly/tree/master/package/wxcef_build Hopefully it can save you some of the headaches I had (mostly with wx, and shared libraries linked, not cefpython).
--
You received this message because you are subscribed to the Google Groups "CEF Python" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cefpython+...@googlegroups.com.
Visit this group at http://groups.google.com/group/cefpython.
To view this discussion on the web visit https://groups.google.com/d/msgid/cefpython/5178b1aa-054c-46f0-b19f-5ff3629c2584%40googlegroups.com.
I got it working back in July using py2app's alias mode (which leaves all the source and data files in place). I have since revisited this week, as it's packaging time for our app. Windows works beautifully fine using pyinstaller.
Mac is being more of a pain, but made some progress. I am using py2app, and have got it working to a point where it copies all the cefpython binaries across into the .app, and the app can boot on other macs (which do not have CEF installed), which is great. However I'm still experiencing some troubles in regards to certain binary paths, the icon not being added as the .app files icon, etc.
Have you managed to have much success with py2app in the past 14 hours? I plan on working more on it later this evening to try and solve some of these bugs.
On another note - Does anyone know how to change the path in which the .app looks for the cef binaries? I'm guessing I will have to add this flag somewhere in my code. At the moment after packaging, I have to manually copy/make these files/folders in my MacOS directly inside the .app...
/client.app/Contents/MacOS/subprocess
/client.app/Contents/MacOS/Resources/cef.pak
/client.app/Contents/MacOS/Resources/en.lproj/locale.pak
Where as the rest/all of the cefpython files are at...
I just can not build it.
First, it's always os error with stat() return code 20. Then I tried to manually unpack the library.zip and remove the zip in the App. My app manage to run and no error shown in console, but then it stopped working / crash
Since then, I really got stuck and have no idea what to do.
You said, you can run your app and I think that is great. Can you share what you've done in setup script and other steps necessary to make the app work ?
Thank you.
Here is the clue in my experiment using OSX 10.10 and Pyside:
1. Use Py2app standard mechanism to build the app structure
2. Browse the app structure to manually modify some files and folder
3. Extract the site_packages.zip in Contents/Resources/lib/python2.7/ and remove the zip file
4. In the new site_packages folder, there will be cefpython3 sub directory. Copy these files and folder from cefpython3 directory:
a. subprocess
b. Resources/en.lproj/locale.pak
c. Resources/cef.pak
d. Resources/devtools_resources.pak
and put them into Contents/MacOS/ . Sometimes I have to create the folder manually to prevent system not responding during copying.
5. Add executable permission to the subprocess in Contents/MacOS using chmod command : chmod +x subprocess .This will allow the application to launch the subprocess.
And we are ready to double click the app.
I also found that there will be at least 3 icon showns-up in the OSX bottom dock which I don't know why , maybe someone can explain it to me.
Also I am having trouble if I use local python HTTP server script. I want the cefpython to access the local HTTP server which is also embedded with the app as python script. Sometimes it makes the app to crash and sometimes the HTTP request never made it into the python HTTP server script.
I can help you fix the 3 icons appearing in the doc, which will also cut out steps 4 and 5 you listed above. May I ask you to post your setup.py file here so I can see?
Also may I ask how big your .app file is? And did you manage to successfully get a custom icon working?
My setup.py files is still the default generated by the py2applet, like this:
=============================================
from setuptools import setup
APP = ['player.py']
DATA_FILES = []
OPTIONS = {'argv_emulation': True}
setup(
app=APP,
data_files=DATA_FILES,
options={'py2app': OPTIONS},
setup_requires=['py2app'],
)
=============================================
So, how to fix the 3 icon in the OSX dock ?
My app result is more than 1 Gb in size after I put my custom data inside it.
About the dock icon , not yet test it, I will try it later and inform you.
My only problem now is the number of icons shown up in the dock. I need help for this problem.
Here is my setup.py script update:
=================================================
from setuptools import setup
import os
def get_cefpython_path():
import cefpython3 as cefpython
path = os.path.dirname(cefpython.__file__)
return path
def get_data_files():
current_dir=os.path.dirname(os.path.realpath(__file__))
cefp = get_cefpython_path()
data_files=[]
dir=os.listdir(os.path.join(current_dir,'localdocs'))
#add the custom folder : localdocs mechanism
temp_list=[]
for item in dir:
if item!='.DS_Store':
temp_list.append(os.path.join(current_dir,'localdocs',item))
data_files.append(['../MacOS/localdocs',temp_list])
#add the custom folder res mechanism
dir=os.listdir(os.path.join(current_dir,'res'))
temp_list=[]
for item in dir:
if item!='.DS_Store':
temp_list.append(os.path.join(current_dir,'res',item))
data_files.append(['../MacOS/res',temp_list])
#add the cefpython mechanism
data_files.append(['../MacOS/', [
'%s/subprocess' % cefp,
'%s/ffmpegsumo.so' % cefp,
'%s/libcef.dylib' % cefp,
'%s/libplugin_carbon_interpose.dylib' % cefp,
'%s/cefpython_py27.so' % cefp
]])
data_files.append(['../MacOS/Resources',[
'%s/Resources/cef.pak' % cefp,
'%s/Resources/devtools_resources.pak' % cefp
]])
data_files.append(['../MacOS/Resources/en.lproj',['%s/Resources/en.lproj/locale.pak' % cefp]])
return data_files
APP = ['player.py']
DATA_FILES = get_data_files()
OPTIONS = {
'argv_emulation': True,
'iconfile':'res/app_system.icns',
'plist':{
'CFBundleIdentifier':'com.sample',
'CFBundleShortVersionString':'1.0.0',
'CFBundleVersion':'1.0.0',
'NSHumanReadableCopyright':'Copyright (c) 2015',
}
}
setup(
app=APP,
data_files=DATA_FILES,
options={'py2app': OPTIONS},
setup_requires=['py2app'],
)
==================================================
The single process can do the trick, but the whole app will not run.
Any body alive ???
I'll give it a try , eventough I don't know how to bundle the subprocess yet.
And now I am facing another big problem after upgrading to OSX 10.11 .
My app just stop and not responding after showing up correctly.
Some say that OSX 10.11 is a big jump in concept and OS design.
Does anybody has succeeded in bundling the cefpython in OSX as .app ?
It seems that just few of cefpython dev are deploying on OSX , he he he.
In our wx.App class in python, if you add the following line when packaging (and only when packaging, comment it out the rest of the time), it specifies where the CEFPython subprocess file is, and when packaged you should only see 1 icon appearing in the doc.
if 'darwin' in sys.platform:
settings["browser_subprocess_path"] = os.getcwd()+"/lib/python2.7/cefpython3/subprocess"
That worked perfectly for me. If you boot your packaged app and check in activity monitor, only 1 subprocess of your app is running.
In regards to OS X 10.11 (el capitan), I haven't upgraded and then used py2app to package my CEFPython application. I am still using OS X Yosemite to package my application. However I have tried my packaged .app on OS X el capitan, and it worked beautifully without any errors or problems.
I hope this helps.
Here is my short story.
* OSX El-Capitan 10.11
* use new python from MacPorts (the original python won't do , because the rule from pyinstaller won't copy anything from OSX system path)
* use Homebrew bottle package if PySide UI toolkit is needed (in my case , I use the PySide UI toolkit)
* Always install python package using homebrew bottle package or set the python target other than non built-in. Use MacPorts python using port select command.
* Use PyInstaller , my version is 3.1.1. Get it using PIP or manual install. I've used the Py2App but somehow it's not stable in my build and always crashed.
If all of that requirement is good and obey, then I can guarantee that the next process will be good.
For the Cefpython setting, there are several rule that need to be set :
1. import the libcef library using "libcef.dylib" instead of "libcef.so" and use the cefpython example provided in Linux version, which will find the library in other path if the library is not in the default path
2. in "settings" area of the cefpython.initialize , NEVER put the subprocess path in "browser_subprocess_path" key, this way the original CEF core system will look for the "[app name] Helper.app". The original CEF client example also shows how to use the helper app , which is the subprocess app in out case.
3. Create custom app for the "[app name] Helper.app" with minimum rule how to create app in OSX, such as the minimum plist file, the minimum folder required , there are plenty of resource in google to create minimum app system. The structure of the subprocess must follow the site-package structure, like the lbcef, the resource, etc. This helper app will ensure that the icon showed in the dock will always be 1 (the real application icon) and hide the subprocess icon from the dock. For help about creating the plist for the helper, use the helper app bundle example from the original CEF client app bundle.
One thing I failed to do is using the cython compiled library for my source (the result always came up with segmentation fault 11), so all of my source is not cythonized. If someone is able to cythonize the script, then I would like to know how to do the compilation process.
The signing process for the app can also be done perfectly and use the --deep option to perform the signing.
There is my story about "my long process in creating OSX app bundle", it is such a very very very very uneasy job, he he he.
If anyone still have problem bundling their cefpython to OSX app bundle, I will be glad to help.
I am using macports for installing python and dependencies
sudo port install python27
sudo port select --set python python27
sudo port select --set pip pip27
sudo port install py27-pyinstaller
sudo pip install cefpython3==56.1
git clone https://github.com/cztomczak/cefpython.git
cd cefpython/examples
pyinstaller-2.7 --windowed hello_world.py
cd dist/hello_world
ls -al
OUTPUT of "ls -al":
=================================================================================
drwxr-xr-x 66 uidev staff 2244 Apr 18 17:33 .
drwxr-xr-x 4 uidev staff 136 Apr 18 17:33 ..
-rwxr-xr-x 1 uidev staff 23204 Apr 18 17:33 MacOS.so
-rwxr-xr-x 1 uidev staff 9028 Apr 18 17:33 Nav.so
-rwxr-xr-x 1 uidev staff 2065712 Apr 18 17:33 Python
-rwxr-xr-x 1 uidev staff 38760 Apr 18 17:33 _AE.so
-rwxr-xr-x 1 uidev staff 9048 Apr 18 17:33 _Ctl.so
-rwxr-xr-x 1 uidev staff 9048 Apr 18 17:33 _Dlg.so
-rwxr-xr-x 1 uidev staff 9048 Apr 18 17:33 _Evt.so
-rwxr-xr-x 1 uidev staff 47780 Apr 18 17:33 _File.so
-rwxr-xr-x 1 uidev staff 9056 Apr 18 17:33 _Menu.so
-rwxr-xr-x 1 uidev staff 9040 Apr 18 17:33 _Qd.so
-rwxr-xr-x 1 uidev staff 34332 Apr 18 17:33 _Res.so
-rwxr-xr-x 1 uidev staff 9048 Apr 18 17:33 _Win.so
-rwxr-xr-x 1 uidev staff 143580 Apr 18 17:33 _codecs_cn.so
-rwxr-xr-x 1 uidev staff 151264 Apr 18 17:33 _codecs_hk.so
-rwxr-xr-x 1 uidev staff 25920 Apr 18 17:33 _codecs_iso2022.so
-rwxr-xr-x 1 uidev staff 251380 Apr 18 17:33 _codecs_jp.so
-rwxr-xr-x 1 uidev staff 131236 Apr 18 17:33 _codecs_kr.so
-rwxr-xr-x 1 uidev staff 109636 Apr 18 17:33 _codecs_tw.so
-rwxr-xr-x 1 uidev staff 36864 Apr 18 17:33 _collections.so
-rwxr-xr-x 1 uidev staff 139476 Apr 18 17:33 _ctypes.so
-rwxr-xr-x 1 uidev staff 16696 Apr 18 17:33 _functools.so
-rwxr-xr-x 1 uidev staff 25056 Apr 18 17:33 _hashlib.so
-rwxr-xr-x 1 uidev staff 19992 Apr 18 17:33 _heapq.so
-rwxr-xr-x 1 uidev staff 162872 Apr 18 17:33 _io.so
-rwxr-xr-x 1 uidev staff 22320 Apr 18 17:33 _locale.so
-rwxr-xr-x 1 uidev staff 35792 Apr 18 17:33 _multibytecodec.so
-rwxr-xr-x 1 uidev staff 16500 Apr 18 17:33 _random.so
-rwxr-xr-x 1 uidev staff 16052 Apr 18 17:33 _scproxy.so
-rwxr-xr-x 1 uidev staff 80000 Apr 18 17:33 _socket.so
-rwxr-xr-x 1 uidev staff 93396 Apr 18 17:33 _ssl.so
-rwxr-xr-x 1 uidev staff 39676 Apr 18 17:33 _struct.so
-rwxr-xr-x 1 uidev staff 45328 Apr 18 17:33 array.so
-rwxr-xr-x 1 uidev staff 25908 Apr 18 17:33 binascii.so
-rwxr-xr-x 1 uidev staff 40140 Apr 18 17:33 bz2.so
-rwxr-xr-x 1 uidev staff 84612 Apr 18 17:33 cPickle.so
-rwxr-xr-x 1 uidev staff 23844 Apr 18 17:33 cStringIO.so
-rwxr-xr-x 1 uidev staff 2429916 Apr 18 17:33 cefpython3.cefpython_py27.so
-rwxr-xr-x 1 uidev staff 2451068 Apr 18 17:33 cefpython3.cefpython_py34.so
-rwxr-xr-x 1 uidev staff 2369312 Apr 18 17:33 cefpython3.cefpython_py35.so
-rwxr-xr-x 1 uidev staff 2410272 Apr 18 17:33 cefpython3.cefpython_py36.so
-rwxr-xr-x 1 uidev staff 97260 Apr 18 17:33 datetime.so
-rwxr-xr-x 1 uidev staff 15416 Apr 18 17:33 fcntl.so
-rwxr-xr-x 1 uidev staff 13572 Apr 18 17:33 gestalt.so
-rwxr-xr-x 1 uidev staff 1065994 Apr 18 17:33 hello_world
-rwxr-xr-x 1 uidev staff 64632 Apr 18 17:33 itertools.so
-rwxr-xr-x 1 uidev staff 78400 Apr 18 17:33 libbz2.1.0.dylib
-rwxr-xr-x 1 uidev staff 2061992 Apr 18 17:33 libcrypto.1.0.0.dylib
-rwxr-xr-x 1 uidev staff 163472 Apr 18 17:33 libedit.0.dylib
-rwxr-xr-x 1 uidev staff 1057000 Apr 18 17:33 libiconv.2.dylib
-rwxr-xr-x 1 uidev staff 54252 Apr 18 17:33 libintl.8.dylib
-rwxr-xr-x 1 uidev staff 309972 Apr 18 17:33 libncurses.6.dylib
-rwxr-xr-x 1 uidev staff 393280 Apr 18 17:33 libssl.1.0.0.dylib
-rwxr-xr-x 1 uidev staff 80924 Apr 18 17:33 libz.1.dylib
-rwxr-xr-x 1 uidev staff 41620 Apr 18 17:33 math.so
-rwxr-xr-x 1 uidev staff 39692 Apr 18 17:33 operator.so
-rwxr-xr-x 1 uidev staff 234088 Apr 18 17:33 pyexpat.so
-rwxr-xr-x 1 uidev staff 33952 Apr 18 17:33 readline.so
-rwxr-xr-x 1 uidev staff 15416 Apr 18 17:33 resource.so
-rwxr-xr-x 1 uidev staff 33832 Apr 18 17:33 select.so
-rwxr-xr-x 1 uidev staff 31440 Apr 18 17:33 strop.so
-rwxr-xr-x 1 uidev staff 20732 Apr 18 17:33 termios.so
-rwxr-xr-x 1 uidev staff 27368 Apr 18 17:33 time.so
-rwxr-xr-x 1 uidev staff 696636 Apr 18 17:33 unicodedata.so
-rwxr-xr-x 1 uidev staff 31012 Apr 18 17:33 zlib.so
=================================================================================
./hello_world
Traceback (most recent call last):
File "<string>", line 4, in <module>
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/PyInstaller/loader/pyimod03_importers.py", line 389, in load_module
exec(bytecode, module.__dict__)
File "site-packages/cefpython3/__init__.py", line 50, in <module>
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/PyInstaller/loader/pyimod03_importers.py", line 546, in load_module
module = imp.load_module(fullname, fp, filename, ext_tuple)
ImportError: dlopen(/Users/uidev/cefpython/examples/dist/hello_world/cefpython3.cefpython_py27.so, 2): Library not loaded: @loader_path/Chromium Embedded Framework
Referenced from: /Users/uidev/cefpython/examples/dist/hello_world/cefpython3.cefpython_py27.so
Reason: image not found
hello_world returned -1
otool -L hello_world
hello_world:
/System/Library/Frameworks/Carbon.framework/Versions/A/Carbon (compatibility version 2.0.0, current version 157.0.0)
/usr/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.5)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1213.0.0)
/System/Library/Frameworks/ApplicationServices.framework/Versions/A/ApplicationServices (compatibility version 1.0.0, current version 48.0.0)
Program is unable to load @loader_path/Chromium Embedded Framework
Chromium Embedded Framework is in the same dir as hello_world
I am not sure what is causing this. Any suggestions?
Got that working now with:
cd ~/cefpython/examples/dist/hello_world
cp -r /opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/cefpython3/Chromium\ Embedded\ Framework.framework/Chromium\ Embedded\ Framework .
But now I am facing following problem:
./hello_world
[hello_world.py] CEF Python 56.1
[hello_world.py] Python 2.7.13 64bit
[0418/192638.047046:ERROR:icu_util.cc(137)] icudtl.dat not found in bundle
[0418/192638.047096:ERROR:icu_util.cc(173)] Invalid file descriptor to ICU data received.
[1] 5298 illegal hardware instruction ./hello_world
After refering this (https://github.com/cztomczak/cefpython/issues/304) thread, I have changed the hello_world.py to have following code:
settings = {'framework_dir_path' : "./Chromium Embedded Framework"}
cef.Initialize(settings, debug=True)
After recompiling I am facing the same problem:
./hello_world
[hello_world.py] CEF Python 56.1
[hello_world.py] Python 2.7.13 64bit
[0418/193541.792417:ERROR:icu_util.cc(137)] icudtl.dat not found in bundle
[0418/193541.792462:ERROR:icu_util.cc(173)] Invalid file descriptor to ICU data received.
[1] 6642 illegal hardware instruction ./hello_world