# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved.
# License: New BSD License.
# Website: http://code.google.com/p/cefpython/
# This script finds dependencies. It fetches google chrome
# debian package dependencies from src.chromium.org for
# specific revision. Filters these dependencies with data
# returned by ldd command. Saves results to deps.txt.
import os
import sys
import re
import platform
import glob
import subprocess
def main():
branch = get_branch()
revision = get_chromium_revision(branch)
chrome_deps = get_chrome_deps(revision)
cef_library_dependencies = get_cef_library_dependencies()
cef_deps = get_cef_deps(cef_library_dependencies)
final_deps = get_final_deps(chrome_deps, cef_deps)
curdir = os.path.dirname(os.path.realpath(__file__))
with open(curdir+"/deps.txt", "w") as f:
f.write("\n".join(final_deps))
log("Saved deps to deps.txt file")
success = check_final_deps(final_deps)
if not success:
sys.exit(1)
def log(msg):
print("[dependencies.py] %s" % msg)
def fetch_url(url):
if sys.version_info[0] == 2:
import urllib2
try:
urlfile = urllib2.urlopen(url)
except:
# 404 for example
return None
return urlfile.read()
else:
import urllib.request
try:
urlfile = urllib.request.urlopen(url)
except:
# 404 for example
return None
return urlfile.read()
def get_branch():
curdir = os.path.dirname(os.path.realpath(__file__))
with open(curdir+"/../../BUILD_COMPATIBILITY.txt") as f:
m = re.search(r"\d+\.\d+\.(\d+)\.\d+", f.read())
branch = m.group(1)
log("branch = %s" % branch)
return branch
def get_chromium_revision(branch):
# TODO: revision not needed anymore, see new GIT link in get_chrome_deps()
url = "http://src.chromium.org/viewvc" \
"/chrome/branches/%s/src/chrome/VERSION" % branch
contents = fetch_url(url)
if not contents:
raise Exception("Failed fetching url: %s" % url)
m = re.search(r"revision=(\d+)", contents)
revision = m.group(1)
log("chromium revision = %s" % revision)
return revision
def get_chrome_deps(revision):
# TODO: new GIT link: https://chromium.googlesource.com/chromium ..
# /src/+/51.0.2704.104/chrome/installer/linux/debian/expected_deps_x64
# Currently works only with SVN up to Chrome revision 293233.
base_url = "http://src.chromium.org/svn/trunk/src" \
"/chrome/installer/linux/debian"
url = base_url+"/expected_deps?p=%s" % revision
contents = fetch_url(url)
if not contents:
url = base_url+"/expected_deps_x64?p=%s" % revision
contents = fetch_url(url)
if not contents:
raise Exception("Failed fetching url: %s" % url)
contents = contents.strip()
deps = contents.splitlines()
for i, dep in enumerate(deps):
deps[i] = dep.strip()
deps.sort(key = lambda s: s.lower());
log("Found %d Chrome deps" % len(deps))
print("-" * 80)
print("\n".join(deps))
print("-" * 80)
return deps
def get_cef_library_dependencies():
# Chrome deps != library dependencies
# deps = package dependencies (for apt-get install)
# library dependencies -> a package with such name may not exist
curdir = os.path.dirname(os.path.realpath(__file__))
bits = platform.architecture()[0]
assert (bits == "32bit" or bits == "64bit")
binaries_dir = curdir+"/../binaries_%s" % bits
libraries = glob.glob(binaries_dir+"/*.so")
assert(len(libraries))
log("Found %d CEF libraries" % (len(libraries)))
all_dependencies = []
for library in libraries:
library = os.path.abspath(library)
dependencies = get_library_dependencies(library)
all_dependencies = all_dependencies + dependencies
all_dependencies = remove_duplicate_dependencies(all_dependencies)
log("Found %d all CEF library dependencies combined" \
% len(all_dependencies))
return all_dependencies
def remove_duplicate_dependencies(dependencies):
unique = []
for dependency in dependencies:
if dependency not in unique:
unique.append(dependency)
return unique
def get_library_dependencies(library):
contents = subprocess.check_output("ldd %s" % library, shell=True)
contents = contents.strip()
lines = contents.splitlines()
dependencies = []
for line in lines:
m = re.search(r"([^/\s=>]+).so[.\s]", line)
dependencies.append(m.group(1))
dependencies.sort(key = lambda s: s.lower());
log("Found %d dependencies in %s:" % \
(len(dependencies), os.path.basename(library)))
print("-" * 80)
print("\n".join(dependencies))
print("-" * 80)
return dependencies
def get_cef_deps(dependencies):
cef_deps = []
for dependency in dependencies:
if package_exists(dependency):
cef_deps.append(dependency)
log("Found %d CEF deps for which package exists:" % len(cef_deps))
print("-" * 80)
print("\n".join(cef_deps))
print("-" * 80)
return cef_deps
def package_exists(package):
try:
devnull = open('/dev/null', 'w')
contents = subprocess.check_output("dpkg -s %s" % package,
stderr=devnull, shell=True)
devnull.close()
except subprocess.CalledProcessError, e:
return False
if "install ok installed" in contents:
return True
print("**PROBABLY ERROR OCCURED** while calling: %s" % "dpkg -s "+package)
return False
def get_final_deps(chrome_deps, cef_deps):
final_deps = chrome_deps
chrome_deps_names = []
for chrome_dep in chrome_deps:
chrome_dep_name = get_chrome_dep_name(chrome_dep)
chrome_deps_names.append(chrome_dep_name)
for cef_dep in cef_deps:
if cef_dep not in chrome_deps_names:
final_deps.append(cef_dep)
log("Found %d CEF deps that were not listed in Chrome deps" % \
(len(final_deps)-len(chrome_deps)) )
log("Found %d final deps:" % len(final_deps))
print("-" * 80)
print("\n".join(final_deps))
print("-" * 80)
return final_deps
def get_chrome_dep_name(dep):
# Eg. libxcomposite1 (>= 1:0.3-1) ===> libxcomposite1
dep = re.sub(r"\([^\(]+\)", "", dep)
dep = dep.strip()
return dep
def check_final_deps(deps):
# Check if all deps packages are installed
deps_not_installed = []
for dep in deps:
dep_name = get_chrome_dep_name(dep)
if not package_exists(dep_name):
deps_not_installed.append(dep_name)
if len(deps_not_installed) == 0:
log("Everything is OK. All deps are found to be installed.")
return True
else:
log("Found %d deps that are currently not installed:" % \
len(deps_not_installed))
print("-" * 80)
print("\n".join(deps_not_installed))
print("-" * 80)
log("ERROR")
return False
if __name__ == "__main__":
main()