Skip to content

Commit b199ab8

Browse files
committed
Added support for creating debian packages on Linux.
Updated the BuildOnLinux wiki page with instructions on how to run the make-deb.py script.
1 parent 52c4e2b commit b199ab8

File tree

7 files changed

+150
-31
lines changed

7 files changed

+150
-31
lines changed

cefpython/cef3/linux/installer/__init__.py.template

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,28 @@
11
import ctypes, os
22

3+
# If this is a debian package then package_dir is a symlink:
4+
# /usr/lib/pymodules/python2.7/cefpython3
5+
# Cefpython3 files including executables are located in:
6+
# /usr/share/pyshared/cefpython3
7+
# Cefpython3 .so libraries are located in:
8+
# /usr/lib/pyshared/python2.7/cefpython3
9+
310
package_dir = os.path.dirname(os.path.abspath(__file__))
411

512
# This loads the libcef.so library for the main python executable.
613
libcef_so = os.path.join(package_dir, "libcef.so")
714
ctypes.CDLL(libcef_so, ctypes.RTLD_GLOBAL)
15+
816
# Other .so libraries may also be required
917
libffmpegsumo_so = os.path.join(package_dir, "libffmpegsumo.so")
1018
ctypes.CDLL(libffmpegsumo_so, ctypes.RTLD_GLOBAL)
1119

1220
# This loads the libcef.so library for the subprocess executable.
1321
os.environ["LD_LIBRARY_PATH"] = package_dir
1422

23+
# This env variable will be returned by cefpython.GetModuleDirectory().
24+
os.environ["CEFPYTHON3_PATH"] = package_dir
25+
1526
import sys
1627
if 0x02070000 <= sys.hexversion < 0x03000000:
1728
from . import cefpython_py27 as cefpython
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
# Copyright (c) 2012-2013 The CEF Python authors. All rights reserved.
2+
# License: New BSD License.
3+
# Website: http://code.google.com/p/cefpython/
4+
5+
"""
6+
Create a Debian Package.
7+
8+
Required dependencies:
9+
sudo apt-get install python-support
10+
sudo apt-get install python-pip
11+
sudo pip install -U stdeb
12+
"""
13+
14+
import subprocess
15+
import os, sys
16+
import platform
17+
import argparse
18+
import re
19+
import shutil
20+
21+
BITS = platform.architecture()[0]
22+
assert (BITS == "32bit" or BITS == "64bit")
23+
PACKAGE_NAME = "cefpython3"
24+
PYTHON_VERSION_WITH_DOT = (str(sys.version_info.major) + "."
25+
+ str(sys.version_info.minor))
26+
27+
def replace_in_file(f_path, s_what, s_with):
28+
contents = ""
29+
with open(f_path, "r") as f:
30+
contents = f.read()
31+
assert contents, ("Failed reading file: %s" % f_path)
32+
contents = contents.replace(s_what, s_with)
33+
with open(f_path, "w") as f:
34+
f.write(contents)
35+
36+
def main():
37+
38+
# Options
39+
parser = argparse.ArgumentParser(usage="%(prog)s [options]")
40+
parser.add_argument("-v", "--version", help="cefpython version",
41+
required=True)
42+
args = parser.parse_args()
43+
assert re.search(r"^\d+\.\d+$", args.version), (
44+
"Invalid version string")
45+
46+
# Directories
47+
installer_dir = os.path.dirname(os.path.abspath(__file__))
48+
setup_dir = installer_dir+"/"+PACKAGE_NAME+"-"+args.version+"-linux-"+BITS+"-setup"
49+
50+
# Call make-setup.py
51+
if os.path.exists(setup_dir):
52+
print("Setup directory already exists, removing..")
53+
shutil.rmtree(setup_dir)
54+
subprocess.call("%s %s/make-setup.py -v %s" % \
55+
(sys.executable, installer_dir, args.version), shell=True)
56+
assert os.path.exists(setup_dir), "Setup directory not found"
57+
58+
# Create debian package
59+
os.chdir(setup_dir)
60+
shutil.copy("../stdeb.cfg.template", "stdeb.cfg")
61+
62+
# Create debian source package
63+
subprocess.call("%s setup.py --command-packages=stdeb.command sdist_dsc"\
64+
% (sys.executable,), shell=True)
65+
66+
# Set architecture
67+
if BITS == "32bit":
68+
architecture = "i386"
69+
elif BITS == "64bit":
70+
architecture = "amd64"
71+
control_file = setup_dir+"/deb_dist/"+PACKAGE_NAME+"-"+args.version+"/debian/control"
72+
replace_in_file(control_file, "Architecture: all", "Architecture: %s" % architecture)
73+
74+
# Create debian binary package
75+
os.chdir("deb_dist/%s-%s/" % (PACKAGE_NAME, args.version))
76+
# When creating .postinst file in the debian directory,
77+
# it will overwrite the default postinst script created
78+
# by dh_pysupport, its contents are:
79+
# -----------------------------------------------------
80+
# if which update-python-modules >/dev/null 2>&1; then
81+
# update-python-modules python-cefpython3.public
82+
# fi
83+
# -----------------------------------------------------
84+
# This command creates symbolic links for both shared/ and lib/
85+
# files. This is critical as this makes all files appear in single
86+
# directory, so that subprocess executable which is in shared/
87+
# can see libcef.so which is in lib/.
88+
with open("debian/python-%s.postinst" % (PACKAGE_NAME), "w") as f:
89+
f.write("#! /bin/sh\n")
90+
f.write("set -e\n")
91+
f.write("chmod 755 /usr/share/pyshared/%s/cefclient\n"\
92+
% (PACKAGE_NAME,))
93+
f.write("chmod 755 /usr/share/pyshared/%s/subprocess\n"\
94+
% (PACKAGE_NAME,))
95+
f.write("update-python-modules python-cefpython3.public\n")
96+
subprocess.call("dpkg-buildpackage -rfakeroot -uc -us", shell=True)
97+
98+
print("DONE")
99+
100+
if __name__ == "__main__":
101+
main()

cefpython/cef3/linux/installer/make-setup.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515

1616
BITS = platform.architecture()[0]
1717
assert (BITS == "32bit" or BITS == "64bit")
18-
1918
PACKAGE_NAME = "cefpython3"
2019

2120
README_TEMPLATE = os.getcwd()+r"/README.txt.template"

cefpython/cef3/linux/installer/setup.py.template

Lines changed: 28 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,34 @@
11
from distutils.core import setup
2+
from distutils.command.install import install as _install
3+
import sys
4+
import os
5+
import subprocess
6+
7+
def my_post_install():
8+
""" Chmod +x the subprocess and cefclient executables. """
9+
# We do not want to import from the local "cefpython3" directory.
10+
# Import the cefpython3 module from dist-packages/ directory.
11+
del sys.path[0]
12+
sys.path.append('')
13+
import cefpython3
14+
package_dir = os.path.dirname(cefpython3.__file__)
15+
# Make sure this is not a local package imported.
16+
assert not package_dir.startswith(
17+
os.path.dirname(os.path.abspath(__file__)))
18+
subprocess_exe = os.path.join(package_dir, "subprocess")
19+
cefclient_exe = os.path.join(package_dir, "cefclient")
20+
print("chmod +x " + subprocess_exe)
21+
subprocess.call("chmod +x "+subprocess_exe, shell=True)
22+
print("chmod +x " + cefclient_exe)
23+
subprocess.call("chmod +x "+cefclient_exe, shell=True)
24+
25+
class install(_install):
26+
def run(self):
27+
_install.run(self)
28+
my_post_install()
229

330
setup(
31+
cmdclass={'install': install},
432
name='cefpython3', # No spaces here, so that it works with deb packages.
533
version='%(APP_VERSION)s',
634
description='Python bindings for the Chromium Embedded Framework',
@@ -29,30 +57,3 @@ setup(
2957
'*.pak',
3058
]}
3159
)
32-
33-
# ------------------------------------------------------------------------------
34-
# Chmod +x the subprocess and cefclient executables.
35-
# ------------------------------------------------------------------------------
36-
37-
import sys
38-
import os
39-
import subprocess
40-
41-
# Import the cefpython3 module from dist-packages/ directory.
42-
# We do not want to import from the local "cefpython3" directory.
43-
del sys.path[0]
44-
sys.path.append('')
45-
import cefpython3
46-
47-
package_dir = os.path.dirname(cefpython3.__file__)
48-
# Make sure this is not a local package imported.
49-
assert not package_dir.startswith(os.path.dirname(os.path.abspath(__file__)))
50-
51-
subprocess_exe = os.path.join(package_dir, "subprocess")
52-
cefclient_exe = os.path.join(package_dir, "cefclient")
53-
54-
print("chmod +x " + subprocess_exe)
55-
subprocess.call("chmod +x "+subprocess_exe, shell=True)
56-
57-
print("chmod +x " + cefclient_exe)
58-
subprocess.call("chmod +x "+cefclient_exe, shell=True)
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[DEFAULT]
2+
Depends: libnss3-1d, libnspr4-0d
3+
XS-Python-Version: 2.7

cefpython/cef3/linux/setup/cefpython.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ __PYX_EXTERN_C DL_IMPORT(void) V8FunctionHandler_Execute(CefRefPtr<CefBrowser>,
1818
__PYX_EXTERN_C DL_IMPORT(void) RemovePythonCallbacksForFrame(int);
1919
__PYX_EXTERN_C DL_IMPORT(bool) ExecutePythonCallback(CefRefPtr<CefBrowser>, int, CefRefPtr<CefListValue>);
2020
__PYX_EXTERN_C DL_IMPORT(void) LifespanHandler_OnBeforeClose(CefRefPtr<CefBrowser>);
21-
__PYX_EXTERN_C DL_IMPORT(bool) LifespanHandler_OnBeforePopup(CefRefPtr<CefBrowser>, CefRefPtr<CefFrame>, CefString const &, CefString const &, const int, CefWindowInfo &, CefRefPtr<CefClient> &, CefBrowserSettings &, bool *);
21+
__PYX_EXTERN_C DL_IMPORT(bool) LifespanHandler_OnBeforePopup(CefRefPtr<CefBrowser>, CefRefPtr<CefFrame>, CefString const &, CefString const &, int const , CefWindowInfo &, CefRefPtr<CefClient> &, CefBrowserSettings &, bool *);
2222
__PYX_EXTERN_C DL_IMPORT(void) DisplayHandler_OnLoadingStateChange(CefRefPtr<CefBrowser>, bool, bool, bool);
2323
__PYX_EXTERN_C DL_IMPORT(void) DisplayHandler_OnAddressChange(CefRefPtr<CefBrowser>, CefRefPtr<CefFrame>, CefString const &);
2424
__PYX_EXTERN_C DL_IMPORT(void) DisplayHandler_OnTitleChange(CefRefPtr<CefBrowser>, CefString const &);

cefpython/utils.pyx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ cpdef str GetNavigateUrl(py_string url):
5353
return str(url)
5454

5555
IF CEF_VERSION == 1:
56-
5756
cpdef py_bool IsKeyModifier(int key, int modifiers):
5857
if key == KEY_NONE:
5958
# Same as: return (KEY_CTRL & modifiers) != KEY_CTRL
@@ -63,7 +62,12 @@ IF CEF_VERSION == 1:
6362
return (key & modifiers) == key
6463

6564
cpdef str GetModuleDirectory():
66-
import re, os
65+
import re, os, platform
66+
if platform.system() == "Linux" and os.getenv("CEFPYTHON3_PATH"):
67+
# cefpython3 package __init__.py sets CEFPYTHON3_PATH.
68+
# When cefpython3 is installed as debian package, this
69+
# env variable is the only way of getting valid path.
70+
return os.getenv("CEFPYTHON3_PATH")
6771
if hasattr(sys, "frozen"):
6872
path = os.path.dirname(sys.executable)
6973
elif "__file__" in globals():

0 commit comments

Comments
 (0)