Skip to content

Commit d635eff

Browse files
committed
Merge branch 'master' of github.com:cztomczak/cefpython
2 parents df6c0ca + 15102ee commit d635eff

File tree

3 files changed

+81
-42
lines changed

3 files changed

+81
-42
lines changed

examples/pyinstaller/README-pyinstaller.md

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,8 @@ Table of contents:
1212

1313
This is an example of using [PyInstaller](http://www.pyinstaller.org/)
1414
packager to build executable from one of CEF Python's examples
15-
(wxpython.py). Although this pyinstaller example supports only packaging
16-
on Windows, CEF can be packaged on all platforms without problems, but
17-
this specific packaging example just wasn't tested on other platforms.
18-
Pull requests are welcome.
15+
(wxpython.py). This pyinstaller example supports packaging
16+
on Windows, Linux and Darwin but was mainly tested on Windows platform.
1917

2018
To install required packages type:
2119
```

examples/pyinstaller/hook-cefpython3.py

Lines changed: 74 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"""
22
This is PyInstaller hook file for CEF Python. This file
3-
helps pyinstaller find CEF Python dependencies that are
3+
helps PyInstaller find CEF Python dependencies that are
44
required to run final executable.
55
66
See PyInstaller docs for hooks:
@@ -13,7 +13,8 @@
1313
import re
1414
import sys
1515
import PyInstaller
16-
from PyInstaller.utils.hooks import is_module_satisfies
16+
from PyInstaller.utils.hooks import is_module_satisfies, get_package_paths
17+
from PyInstaller.compat import is_win, is_darwin, is_linux, is_py2
1718
from PyInstaller import log as logging
1819

1920
# Constants
@@ -24,24 +25,20 @@
2425
# TODO: use this code to work cross-platform:
2526
# > from PyInstaller.utils.hooks import get_package_paths
2627
# > get_package_paths("cefpython3")
27-
CEFPYTHON3_DIR = os.path.join(
28-
os.path.dirname(sys.executable),
29-
'Lib', 'site-packages', 'cefpython3')
3028

31-
if platform.system() == "Windows":
32-
CYTHON_MODULE_EXT = ".pyd"
33-
else:
34-
CYTHON_MODULE_EXT = ".so"
29+
CEFPYTHON3_DIR = get_package_paths("cefpython3")[1]
30+
31+
CYTHON_MODULE_EXT = ".pyd" if is_win else ".so"
3532

3633
# Globals
3734
logger = logging.getLogger(__name__)
3835

3936

4037
# Functions
4138
def check_platforms():
42-
if platform.system() != "Windows":
43-
raise SystemExit("Error: Currently only Windows platform is "
44-
" supported, see Issue #135.")
39+
if not is_win and not is_darwin and not is_linux:
40+
raise SystemExit("Error: Currently only Windows, Linux and Darwin "
41+
"platforms are supported, see Issue #135.")
4542

4643

4744
def check_pyinstaller_version():
@@ -51,7 +48,7 @@ def check_pyinstaller_version():
5148
# Example version string for dev version of pyinstaller:
5249
# > 3.3.dev0+g5dc9557c
5350
version = PyInstaller.__version__
54-
match = re.search(r"^\d+\.\d+", version)
51+
match = re.search(r"^\d+\.\d+(\.\d+)?", version)
5552
if not (match.group(0) >= PYINSTALLER_MIN_VERSION):
5653
raise SystemExit("Error: pyinstaller %s or higher is required"
5754
% PYINSTALLER_MIN_VERSION)
@@ -97,8 +94,8 @@ def get_excluded_cefpython_modules():
9794

9895

9996
def get_cefpython3_datas():
100-
"""Returning all cefpython binaries as DATAS, because
101-
pyinstaller does strange things and fails if these are
97+
"""Returning almost all of cefpython binaries as DATAS (see exception
98+
below), because pyinstaller does strange things and fails if these are
10299
returned as BINARIES. It first updates manifest in .dll files:
103100
>> Updating manifest in chrome_elf.dll
104101
@@ -114,32 +111,70 @@ def get_cefpython3_datas():
114111
as pyinstaller would fail to find binary depdendencies on
115112
these files.
116113
114+
One exception is subprocess (subprocess.exe on Windows) executable
115+
file, which is passed to pyinstaller as BINARIES in order to collect
116+
its dependecies.
117+
117118
DATAS are in format: tuple(full_path, dest_subdir).
118119
"""
119120
ret = list()
120121

122+
if is_win:
123+
cefdatadir = "."
124+
elif is_darwin or is_linux:
125+
cefdatadir = "."
126+
else:
127+
assert False, "Unsupported system {}".format(platform.system())
128+
121129
# Binaries, licenses and readmes in the cefpython3/ directory
122130
for filename in os.listdir(CEFPYTHON3_DIR):
123131
# Ignore Cython modules which are already handled by
124132
# pyinstaller automatically.
125-
if filename[:-4] in get_cefpython_modules():
133+
if filename[:-len(CYTHON_MODULE_EXT)] in get_cefpython_modules():
126134
continue
135+
127136
# CEF binaries and datas
128-
if filename[-4:] in [".exe", ".dll", ".so", ".pak", ".dat", ".bin",
129-
".txt"]\
130-
or filename in ["License", "subprocess"]:
131-
logger.info("Include cefpython3 data: %s" % filename)
132-
ret.append((os.path.join(CEFPYTHON3_DIR, filename),
133-
""))
134-
135-
# The .pak files in cefpython3/locales/ directory
136-
locales_dir = os.path.join(CEFPYTHON3_DIR, "locales")
137-
assert os.path.exists(locales_dir), "locales/ dir not found in cefpython3"
138-
for filename in os.listdir(locales_dir):
139-
logger.info("Include cefpython3 data: %s/%s" % (
140-
os.path.basename(locales_dir), filename))
141-
ret.append((os.path.join(locales_dir, filename),
142-
"locales"))
137+
extension = os.path.splitext(filename)[1]
138+
if extension in \
139+
[".exe", ".dll", ".pak", ".dat", ".bin", ".txt", ".so", ".plist"] \
140+
or filename.lower().startswith("license"):
141+
logger.info("Include cefpython3 data: {}".format(filename))
142+
ret.append((os.path.join(CEFPYTHON3_DIR, filename), cefdatadir))
143+
144+
if is_darwin:
145+
# "Chromium Embedded Framework.framework/Resources" with subdirectories
146+
# is required. Contain .pak files and locales (each locale in separate
147+
# subdirectory).
148+
resources_subdir = \
149+
os.path.join("Chromium Embedded Framework.framework", "Resources")
150+
base_path = os.path.join(CEFPYTHON3_DIR, resources_subdir)
151+
assert os.path.exists(base_path), \
152+
"{} dir not found in cefpython3".format(resources_subdir)
153+
for path, dirs, files in os.walk(base_path):
154+
for file in files:
155+
absolute_file_path = os.path.join(path, file)
156+
dest_path = os.path.relpath(path, CEFPYTHON3_DIR)
157+
ret.append((absolute_file_path, dest_path))
158+
logger.info("Include cefpython3 data: {}".format(dest_path))
159+
elif is_win or is_linux:
160+
# The .pak files in cefpython3/locales/ directory
161+
locales_dir = os.path.join(CEFPYTHON3_DIR, "locales")
162+
assert os.path.exists(locales_dir), \
163+
"locales/ dir not found in cefpython3"
164+
for filename in os.listdir(locales_dir):
165+
logger.info("Include cefpython3 data: {}/{}".format(
166+
os.path.basename(locales_dir), filename))
167+
ret.append((os.path.join(locales_dir, filename),
168+
os.path.join(cefdatadir, "locales")))
169+
170+
# Optional .so/.dll files in cefpython3/swiftshader/ directory
171+
swiftshader_dir = os.path.join(CEFPYTHON3_DIR, "swiftshader")
172+
if os.path.isdir(swiftshader_dir):
173+
for filename in os.listdir(swiftshader_dir):
174+
logger.info("Include cefpython3 data: {}/{}".format(
175+
os.path.basename(swiftshader_dir), filename))
176+
ret.append((os.path.join(swiftshader_dir, filename),
177+
os.path.join(cefdatadir, "swiftshader")))
143178
return ret
144179

145180

@@ -162,7 +197,6 @@ def get_cefpython3_datas():
162197
# TODO: Write a tool script that would find such imports in
163198
# .pyx files automatically.
164199
hiddenimports = [
165-
"base64",
166200
"codecs",
167201
"copy",
168202
"datetime",
@@ -179,16 +213,21 @@ def get_cefpython3_datas():
179213
"urllib",
180214
"weakref",
181215
]
182-
if sys.version_info.major == 2:
216+
if is_py2:
183217
hiddenimports += [
184218
"urlparse",
185219
]
186220

187221
# Excluded modules
188222
excludedimports = get_excluded_cefpython_modules()
189223

190-
# Include binaries
191-
binaries = []
224+
# Include binaries requiring to collect its dependencies
225+
if is_darwin or is_linux:
226+
binaries = [(os.path.join(CEFPYTHON3_DIR, "subprocess"), ".")]
227+
elif is_win:
228+
binaries = [(os.path.join(CEFPYTHON3_DIR, "subprocess.exe"), ".")]
229+
else:
230+
binaries = []
192231

193232
# Include datas
194233
datas = get_cefpython3_datas()

examples/pyinstaller/pyinstaller.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,15 @@
2525
EXE_EXT = ".exe"
2626
elif platform.system() == "Darwin":
2727
EXE_EXT = ".app"
28+
elif platform.system() == "Linux":
29+
EXE_EXT = ""
2830

2931

3032
def main():
3133
# Platforms supported
32-
if platform.system() != "Windows":
33-
raise SystemExit("Error: Only Windows platform is currently "
34-
"supported. See Issue #135 for details.")
34+
if platform.system() not in ["Windows", "Darwin", "Linux"]:
35+
raise SystemExit("Error: Only Windows, Linux and Darwin platforms are "
36+
"currently supported. See Issue #135 for details.")
3537

3638
# Make sure nothing is cached from previous build.
3739
# Delete the build/ and dist/ directories.

0 commit comments

Comments
 (0)