Skip to content

Commit 6e68075

Browse files
CzarekCzarek
authored andcommitted
Added installer for Mac. Run the build_all.sh script
to create a Python Wheel package and a Distutils source package. Fixed wx.chromectrl examples. They didn't work with wxPython 3 on Mac. PySimpleApp is deprecated.
1 parent 85bd85f commit 6e68075

File tree

11 files changed

+470
-36
lines changed

11 files changed

+470
-36
lines changed

cefpython/cef3/mac/binaries_64bit/wxpython.py

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -191,14 +191,6 @@ def CreateMenu(self):
191191
self.SetMenuBar(menubar)
192192

193193
def OnClose(self, event):
194-
# Calling CloseBrowser will cause that OnClose event occurs again,
195-
# so self.browser must be checked if non-empty.
196-
if not self.browser:
197-
return
198-
199-
self.browser.StopLoad()
200-
self.browser.CloseBrowser()
201-
202194
# Remove all CEF browser references so that browser is closed
203195
# cleanly. Otherwise there may be issues for example with cookies
204196
# not being flushed to disk when closing app immediately
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
/cefpython3-*/
2+
dist/
3+
binaries_fat/
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
__all__ = ["cefpython", "wx"]
2+
__version__ = "%(APP_VERSION)s"
3+
__author__ = "The CEF Python authors"
4+
5+
import os
6+
import ctypes
7+
8+
package_dir = os.path.dirname(os.path.abspath(__file__))
9+
10+
# On Mac it works without setting library paths, but let's set it
11+
# just to be sure.
12+
os.environ["LD_LIBRARY_PATH"] = package_dir
13+
os.environ["DYLD_LIBRARY_PATH"] = package_dir
14+
15+
# This env variable will be returned by cefpython.GetModuleDirectory().
16+
os.environ["CEFPYTHON3_PATH"] = package_dir
17+
18+
# This loads the libcef.so library for the main python executable.
19+
# The libffmpegsumo.so library shouldn't be loaded here, it could
20+
# cause issues to load it in the browser process.
21+
libcef_so = os.path.join(package_dir, "libcef.dylib")
22+
ctypes.CDLL(libcef_so, ctypes.RTLD_GLOBAL)
23+
24+
import sys
25+
if 0x02070000 <= sys.hexversion < 0x03000000:
26+
from . import cefpython_py27 as cefpython
27+
else:
28+
raise Exception("Unsupported python version: " + sys.version)
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#!/bin/bash
2+
3+
if [ -z "$1" ]; then
4+
echo "ERROR: Provide an argument: version number eg. 31.2"
5+
exit 1
6+
fi
7+
8+
echo "Removing old directories"
9+
rm -rf cefpython3-*-setup/
10+
rm -rf dist/
11+
12+
echo "Running make-setup.py"
13+
python make-setup.py -v $1
14+
if [ $? -ne 0 ]; then echo "ERROR: make-setup.py" && exit 1; fi;
15+
16+
setup_dirs=(cefpython3-*-setup)
17+
setup_dir=${setup_dirs[0]}
18+
19+
echo "Packing setup directory to .tar.gz"
20+
tar -zcvf $setup_dir.tar.gz $setup_dir/
21+
if [ $? -ne 0 ]; then echo "ERROR: tar -zcvf $setup_dir..." && exit 1; fi;
22+
23+
echo "Moving setup.tar.gz to dist/"
24+
mkdir dist/
25+
mv $setup_dir.tar.gz dist/
26+
if [ $? -ne 0 ]; then echo "ERROR: mv $setup_dir..." && exit 1; fi;
27+
28+
echo "Installing the wheel package"
29+
pip install wheel
30+
if [ $? -ne 0 ]; then echo "ERROR: pip install wheel" && exit 1; fi;
31+
32+
echo "Creating a Python Wheel package"
33+
cd $setup_dir
34+
python setup.py bdist_wheel
35+
if [ $? -ne 0 ]; then echo "ERROR: python setup.py bdist_wheel" && exit 1; fi;
36+
37+
echo "Moving .whl package to dist/"
38+
mv dist/*.whl ../dist/
39+
if [ $? -ne 0 ]; then echo "ERROR: mv dist/*.whl..." && exit 1; fi;
40+
41+
cd ../
42+
43+
cd dist/
44+
echo "Files in the dist/ directory:"
45+
ls -l
46+
47+
echo "DONE"
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#!/bin/bash
2+
3+
# Stop on first error:
4+
# set -e
5+
6+
bash ./build_all.sh 99.99
7+
8+
if [ ! -d "dist/" ]; then echo "ERROR: dist/ does not exist" && exit 1; fi;
9+
cd dist/
10+
11+
cwd=$(pwd)
12+
yes | pip uninstall cefpython3
13+
14+
pip install --upgrade cefpython3 --no-index --find-links=file://$cwd
15+
if [ $? -ne 0 ]; then echo "ERROR: pip install cefpython3..." && exit 1; fi;
16+
cd ../
17+
18+
cd ../../wx-subpackage/examples/
19+
20+
python sample1.py
21+
#if [ $? -ne 0 ]; then echo "ERROR: python sample1.py" && exit 1; fi;
22+
23+
python sample2.py
24+
#if [ $? -ne 0 ]; then echo "ERROR: python sample2.py" && exit 1; fi;
25+
26+
python sample3.py
27+
#if [ $? -ne 0 ]; then echo "ERROR: python sample3.py" && exit 1; fi;
28+
29+
cd ../../mac/installer/
30+
31+
yes | pip uninstall cefpython3
Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved.
2+
# License: New BSD License.
3+
# Website: http://code.google.com/p/cefpython/
4+
5+
# Create a setup package.
6+
7+
import sys
8+
import os
9+
import platform
10+
import argparse
11+
import re
12+
import shutil
13+
import glob
14+
import sysconfig
15+
import subprocess
16+
import struct
17+
18+
BITS = "%sbit" % (8 * struct.calcsize("P"))
19+
20+
PACKAGE_NAME = "cefpython3"
21+
22+
INIT_TEMPLATE = os.getcwd()+r"/__init__.py.template"
23+
SETUP_TEMPLATE = os.getcwd()+r"/setup.py.template"
24+
PY_VERSION_DIGITS_ONLY = (str(sys.version_info.major) + ""
25+
+ str(sys.version_info.minor)) # "27" or "34"
26+
27+
def str_format(string, dictionary):
28+
orig_string = string
29+
for key, value in dictionary.iteritems():
30+
string = string.replace("%("+key+")s", value)
31+
if string == orig_string:
32+
raise Exception("Nothing to format")
33+
if re.search(r"%\([a-zA-Z0-9_]+\)s", string):
34+
raise Exception("Not all strings formatted")
35+
return string
36+
37+
def get_binaries_dir(b32, b64, bfat):
38+
pyver = PY_VERSION_DIGITS_ONLY
39+
if (os.path.exists(b32 + "/cefpython_py{}.so".format(pyver))
40+
and os.path.exists(b64 + "/cefpython_py{}.so".format(pyver))):
41+
create_fat_binaries(b32, b64, bfat)
42+
return bfat
43+
return os.path.abspath(installer_dir+"/../binaries_"+BITS+"/")
44+
45+
def create_fat_binaries(b32, b64, bfat):
46+
print("Creating fat binaries")
47+
if os.path.exists(bfat):
48+
shutil.rmtree(bfat)
49+
os.mkdir(bfat)
50+
res = os.system("cp -rf {}/* {}/".format(b32, bfat))
51+
assert res == 0
52+
files = os.listdir(b32)
53+
for fbase in files:
54+
if not (fbase.endswith(".dylib") or fbase.endswith(".so")
55+
or fbase.endswith("subprocess")):
56+
continue
57+
fname32 = os.path.join(b32, fbase)
58+
fname64 = os.path.join(b64, fbase)
59+
fnamefat = os.path.join(bfat, fbase)
60+
print("Creating fat binary: {}".format(fbase))
61+
res = os.system("lipo {} {} -create -output {}"
62+
.format(fname32, fname64, fnamefat))
63+
assert res == 0
64+
65+
def main():
66+
parser = argparse.ArgumentParser(usage="%(prog)s [options]")
67+
parser.add_argument("-v", "--version", help="cefpython version",
68+
required=True)
69+
args = parser.parse_args()
70+
assert re.search(r"^\d+\.\d+$", args.version), (
71+
"Invalid version string")
72+
73+
vars = {}
74+
vars["APP_VERSION"] = args.version
75+
# vars["PLATFORM"] = sysconfig.get_platform()
76+
vars["PLATFORM"] = "macosx"
77+
vars["PY_VERSION_DIGITS_ONLY"] = PY_VERSION_DIGITS_ONLY
78+
79+
print("Reading template: %s" % INIT_TEMPLATE)
80+
f = open(INIT_TEMPLATE)
81+
INIT_CONTENT = str_format(f.read(), vars)
82+
f.close()
83+
84+
print("Reading template: %s" % SETUP_TEMPLATE)
85+
f = open(SETUP_TEMPLATE)
86+
SETUP_CONTENT = str_format(f.read(), vars)
87+
f.close()
88+
89+
installer_dir = os.path.dirname(os.path.abspath(__file__))
90+
91+
setup_dir = installer_dir+"/"+PACKAGE_NAME+"-"+vars["APP_VERSION"]+"-"+vars["PLATFORM"]+"-setup"
92+
print("Creating setup dir: "+setup_dir)
93+
os.mkdir(setup_dir)
94+
95+
package_dir = setup_dir+"/"+PACKAGE_NAME
96+
print("Creating package dir")
97+
os.mkdir(package_dir)
98+
99+
print("Creating setup.py from template")
100+
with open(setup_dir+"/setup.py", "w") as f:
101+
f.write(SETUP_CONTENT)
102+
103+
# Create fat binaries if both 32bit and 64bit are available
104+
b32 = os.path.abspath(installer_dir+"/../binaries_32bit/")
105+
b64 = os.path.abspath(installer_dir+"/../binaries_64bit/")
106+
bfat = os.path.abspath(installer_dir+"/binaries_fat/")
107+
binaries_dir = get_binaries_dir(b32, b64, bfat)
108+
print("Copying binaries to package dir")
109+
ret = os.system("cp -rf "+binaries_dir+"/* "+package_dir)
110+
assert ret == 0
111+
112+
os.chdir(package_dir)
113+
print("Removing .log files from the package dir")
114+
ret = os.system("rm *.log")
115+
# assert ret == 0 - if there are no .log files this assert would fail.
116+
os.chdir(installer_dir)
117+
118+
print("Creating __init__.py from template")
119+
with open(package_dir+"/__init__.py", "w") as f:
120+
f.write(INIT_CONTENT)
121+
122+
print("Creating examples dir in package dir")
123+
os.mkdir(package_dir+"/examples/")
124+
125+
print("Creating wx dir in package dir")
126+
os.mkdir(package_dir+"/wx/")
127+
128+
print("Moving example scripts from package dir to examples dir")
129+
examples = glob.glob(package_dir+"/*.py")
130+
for example in examples:
131+
# Ignore: cefpython_py27.py - dummy API script
132+
if os.path.basename(example).startswith("cefpython_"):
133+
continue
134+
# Ignore: __init__.py
135+
if os.path.basename(example).startswith("__"):
136+
continue
137+
os.rename(example, package_dir+"/examples/"+os.path.basename(example))
138+
ret = os.system("mv "+package_dir+"/*.html "+package_dir+"/examples/")
139+
ret = os.system("mv "+package_dir+"/*.js "+package_dir+"/examples/")
140+
ret = os.system("mv "+package_dir+"/*.css "+package_dir+"/examples/")
141+
assert ret == 0
142+
143+
print("Copying wx-subpackage to wx dir in package dir")
144+
wx_subpackage_dir = os.path.abspath(installer_dir+"/../../wx-subpackage/")
145+
ret = os.system("cp -rf "+wx_subpackage_dir+"/* "+package_dir+"/wx/")
146+
assert ret == 0
147+
148+
print("Moving wx examples from wx/examples to examples/wx")
149+
shutil.move(package_dir+"/wx/examples", package_dir+"/wx/wx/")
150+
shutil.move(package_dir+"/wx/wx/", package_dir+"/examples/")
151+
152+
print("Copying package dir examples to setup dir")
153+
ret = os.system("cp -rf "+package_dir+"/examples/ "+setup_dir+"/examples/")
154+
assert ret == 0
155+
156+
# Create empty debug.log files so that package uninstalls cleanly
157+
# in case examples were launched. Issue 149.
158+
debug_log_dirs = [package_dir,
159+
package_dir+"/examples/",
160+
package_dir+"/examples/wx/"]
161+
for dir in debug_log_dirs:
162+
print("Creating empty debug.log in %s" % dir)
163+
with open(dir+"/debug.log", "w") as f:
164+
f.write("")
165+
# Set write permissions so that Wheel package files have it
166+
# right. So that examples may be run from package directory.
167+
subprocess.call("chmod 666 %s/debug.log" % dir, shell=True)
168+
169+
print("Setup Package created successfully.")
170+
171+
if __name__ == "__main__":
172+
main()
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
from setuptools import setup
2+
from setuptools.command.install import install as _install
3+
from setuptools.dist import Distribution
4+
5+
try:
6+
# Wheel platform tag gets complicated on Mac, see:
7+
# http://lepture.com/en/2014/python-on-a-hard-wheel
8+
from wheel.bdist_wheel import bdist_wheel
9+
class _bdist_wheel(bdist_wheel):
10+
def get_tag(self):
11+
tag = bdist_wheel.get_tag(self)
12+
platform = ("macosx_10_6_intel"
13+
".macosx_10_9_intel.macosx_10_9_x86_64"
14+
".macosx_10_10_intel.macosx_10_10_x86_64")
15+
tag = (tag[0], tag[1], platform)
16+
return tag
17+
cmdclass = {"bdist_wheel": _bdist_wheel}
18+
except ImportError:
19+
cmdclass = {}
20+
21+
import sys
22+
import os
23+
import subprocess
24+
25+
class BinaryDistribution(Distribution):
26+
def is_pure(self):
27+
return False
28+
29+
def get_package_data(directory, base_dir=""):
30+
""" Lists directory recursively. Includes only files. Empty
31+
directories are not included. File paths include the directory
32+
path passed to this function. """
33+
if base_dir:
34+
old_dir = os.getcwd()
35+
os.chdir(base_dir)
36+
files = os.listdir(directory)
37+
ret = []
38+
for f in files:
39+
f = os.path.join(directory, f)
40+
if os.path.isdir(f):
41+
ret = ret + get_package_data(f)
42+
else:
43+
ret.append(f)
44+
if base_dir:
45+
os.chdir(old_dir)
46+
return ret
47+
48+
setup(
49+
distclass=BinaryDistribution,
50+
cmdclass=cmdclass,
51+
name='cefpython3', # No spaces here, so that it works with deb packages.
52+
version='%(APP_VERSION)s',
53+
description='Python bindings for the Chromium Embedded Framework',
54+
license='BSD 3-Clause',
55+
author='Czarek Tomczak',
56+
author_email='czarek.tomczak@gmail.com',
57+
url='http://code.google.com/p/cefpython/',
58+
platforms=['%(PLATFORM)s'],
59+
packages=['cefpython3', 'cefpython3.wx'],
60+
package_data={'cefpython3': [
61+
'examples/*.py',
62+
'examples/*.html',
63+
'examples/*.js',
64+
'examples/*.css',
65+
'examples/wx/*.py',
66+
'examples/wx/*.html',
67+
'examples/wx/*.png',
68+
'wx/*.txt',
69+
'wx/images/*.png',
70+
'*.txt',
71+
'subprocess',
72+
'*.so',
73+
'*.dylib',
74+
'debug.log',
75+
'examples/debug.log',
76+
'examples/wx/debug.log',]
77+
+ get_package_data("Resources/", "cefpython3/")
78+
}
79+
)

0 commit comments

Comments
 (0)