|
| 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 | +# This script finds dependencies. It fetches google chrome |
| 6 | +# debian package dependencies from src.chromium.org for |
| 7 | +# specific revision. Filters these dependencies with data |
| 8 | +# returned by ldd command. Saves results to deps.txt. |
| 9 | + |
| 10 | +import os |
| 11 | +import sys |
| 12 | +import re |
| 13 | +import platform |
| 14 | +import glob |
| 15 | +import subprocess |
| 16 | + |
| 17 | +def main(): |
| 18 | + branch = get_branch() |
| 19 | + revision = get_chromium_revision(branch) |
| 20 | + chrome_deps = get_chrome_deps(revision) |
| 21 | + cef_library_dependencies = get_cef_library_dependencies() |
| 22 | + cef_deps = get_cef_deps(cef_library_dependencies) |
| 23 | + final_deps = get_final_deps(chrome_deps, cef_deps) |
| 24 | + curdir = os.path.dirname(os.path.realpath(__file__)) |
| 25 | + with open(curdir+"/deps.txt", "w") as f: |
| 26 | + f.write("\n".join(final_deps)) |
| 27 | + log("Saved deps to deps.txt file") |
| 28 | + success = check_final_deps(final_deps) |
| 29 | + if not success: |
| 30 | + sys.exit(1) |
| 31 | + |
| 32 | +def log(msg): |
| 33 | + print("[dependencies.py] %s" % msg) |
| 34 | + |
| 35 | +def fetch_url(url): |
| 36 | + if sys.version_info[0] == 2: |
| 37 | + import urllib2 |
| 38 | + try: |
| 39 | + urlfile = urllib2.urlopen(url) |
| 40 | + except: |
| 41 | + # 404 for example |
| 42 | + return None |
| 43 | + return urlfile.read() |
| 44 | + else: |
| 45 | + import urllib.request |
| 46 | + try: |
| 47 | + urlfile = urllib.request.urlopen(url) |
| 48 | + except: |
| 49 | + # 404 for example |
| 50 | + return None |
| 51 | + return urlfile.read() |
| 52 | + |
| 53 | +def get_branch(): |
| 54 | + curdir = os.path.dirname(os.path.realpath(__file__)) |
| 55 | + with open(curdir+"/../../BUILD_COMPATIBILITY.txt") as f: |
| 56 | + m = re.search(r"\d+\.\d+\.(\d+)\.\d+", f.read()) |
| 57 | + branch = m.group(1) |
| 58 | + log("branch = %s" % branch) |
| 59 | + return branch |
| 60 | + |
| 61 | +def get_chromium_revision(branch): |
| 62 | + url = "http://src.chromium.org/viewvc" \ |
| 63 | + "/chrome/branches/%s/src/chrome/VERSION" % branch |
| 64 | + contents = fetch_url(url) |
| 65 | + if not contents: |
| 66 | + raise Exception("Failed fetching url: %s" % url) |
| 67 | + m = re.search(r"revision=(\d+)", contents) |
| 68 | + revision = m.group(1) |
| 69 | + log("chromium revision = %s" % revision) |
| 70 | + return revision |
| 71 | + |
| 72 | +def get_chrome_deps(revision): |
| 73 | + # Currently works only with SVN up to Chrome revision 293233. |
| 74 | + base_url = "http://src.chromium.org/svn/trunk/src" \ |
| 75 | + "/chrome/installer/linux/debian" |
| 76 | + url = base_url+"/expected_deps?p=%s" % revision |
| 77 | + contents = fetch_url(url) |
| 78 | + if not contents: |
| 79 | + url = base_url+"/expected_deps_x64?p=%s" % revision |
| 80 | + contents = fetch_url(url) |
| 81 | + if not contents: |
| 82 | + raise Exception("Failed fetching url: %s" % url) |
| 83 | + contents = contents.strip() |
| 84 | + deps = contents.splitlines() |
| 85 | + for i, dep in enumerate(deps): |
| 86 | + deps[i] = dep.strip() |
| 87 | + deps.sort(key = lambda s: s.lower()); |
| 88 | + log("Found %d Chrome deps" % len(deps)) |
| 89 | + print("-" * 80) |
| 90 | + print("\n".join(deps)) |
| 91 | + print("-" * 80) |
| 92 | + return deps |
| 93 | + |
| 94 | +def get_cef_library_dependencies(): |
| 95 | + # Chrome deps != library dependencies |
| 96 | + # deps = package dependencies (for apt-get install) |
| 97 | + # library dependencies -> a package with such name may not exist |
| 98 | + curdir = os.path.dirname(os.path.realpath(__file__)) |
| 99 | + bits = platform.architecture()[0] |
| 100 | + assert (bits == "32bit" or bits == "64bit") |
| 101 | + binaries_dir = curdir+"/../binaries_%s" % bits |
| 102 | + libraries = glob.glob(binaries_dir+"/*.so") |
| 103 | + assert(len(libraries)) |
| 104 | + log("Found %d CEF libraries" % (len(libraries))) |
| 105 | + all_dependencies = [] |
| 106 | + for library in libraries: |
| 107 | + library = os.path.abspath(library) |
| 108 | + dependencies = get_library_dependencies(library) |
| 109 | + all_dependencies = all_dependencies + dependencies |
| 110 | + all_dependencies = remove_duplicate_dependencies(all_dependencies) |
| 111 | + log("Found %d all CEF library dependencies combined" \ |
| 112 | + % len(all_dependencies)) |
| 113 | + return all_dependencies |
| 114 | + |
| 115 | +def remove_duplicate_dependencies(dependencies): |
| 116 | + unique = [] |
| 117 | + for dependency in dependencies: |
| 118 | + if dependency not in unique: |
| 119 | + unique.append(dependency) |
| 120 | + return unique |
| 121 | + |
| 122 | +def get_library_dependencies(library): |
| 123 | + contents = subprocess.check_output("ldd %s" % library, shell=True) |
| 124 | + contents = contents.strip() |
| 125 | + lines = contents.splitlines() |
| 126 | + dependencies = [] |
| 127 | + for line in lines: |
| 128 | + m = re.search(r"([^/\s=>]+).so[.\s]", line) |
| 129 | + dependencies.append(m.group(1)) |
| 130 | + dependencies.sort(key = lambda s: s.lower()); |
| 131 | + log("Found %d dependencies in %s:" % \ |
| 132 | + (len(dependencies), os.path.basename(library))) |
| 133 | + print("-" * 80) |
| 134 | + print("\n".join(dependencies)) |
| 135 | + print("-" * 80) |
| 136 | + return dependencies |
| 137 | + |
| 138 | +def get_cef_deps(dependencies): |
| 139 | + cef_deps = [] |
| 140 | + for dependency in dependencies: |
| 141 | + if package_exists(dependency): |
| 142 | + cef_deps.append(dependency) |
| 143 | + log("Found %d CEF deps for which package exists:" % len(cef_deps)) |
| 144 | + print("-" * 80) |
| 145 | + print("\n".join(cef_deps)) |
| 146 | + print("-" * 80) |
| 147 | + return cef_deps |
| 148 | + |
| 149 | +def package_exists(package): |
| 150 | + try: |
| 151 | + devnull = open('/dev/null', 'w') |
| 152 | + contents = subprocess.check_output("dpkg -s %s" % package, |
| 153 | + stderr=devnull, shell=True) |
| 154 | + devnull.close() |
| 155 | + except subprocess.CalledProcessError, e: |
| 156 | + return False |
| 157 | + if "install ok installed" in contents: |
| 158 | + return True |
| 159 | + print("**PROBABLY ERROR OCCURED** while calling: %s" % "dpkg -s "+package) |
| 160 | + return False |
| 161 | + |
| 162 | +def get_final_deps(chrome_deps, cef_deps): |
| 163 | + final_deps = chrome_deps |
| 164 | + chrome_deps_names = [] |
| 165 | + for chrome_dep in chrome_deps: |
| 166 | + chrome_deps_names.append(get_chrome_dep_name(chrome_dep)) |
| 167 | + for cef_dep in cef_deps: |
| 168 | + if cef_dep not in chrome_deps_names: |
| 169 | + final_deps.append(cef_dep) |
| 170 | + log("Found %d CEF deps that were not listed in Chrome deps" % \ |
| 171 | + (len(final_deps)-len(chrome_deps)) ) |
| 172 | + log("Found %d final deps:" % len(final_deps)) |
| 173 | + print("-" * 80) |
| 174 | + print("\n".join(final_deps)) |
| 175 | + print("-" * 80) |
| 176 | + return final_deps |
| 177 | + |
| 178 | +def get_chrome_dep_name(dep): |
| 179 | + # Eg. libxcomposite1 (>= 1:0.3-1) ===> libxcomposite1 |
| 180 | + dep = re.sub(r"\([^\(]+\)", "", dep) |
| 181 | + dep = dep.strip() |
| 182 | + return dep |
| 183 | + |
| 184 | +def check_final_deps(deps): |
| 185 | + # Check if all deps packages are installed |
| 186 | + deps_not_installed = [] |
| 187 | + for dep in deps: |
| 188 | + dep_name = get_chrome_dep_name(dep) |
| 189 | + if not package_exists(dep_name): |
| 190 | + deps_not_installed.append(dep_name) |
| 191 | + if len(deps_not_installed) == 0: |
| 192 | + log("Everything is OK. All deps are found to be installed.") |
| 193 | + return True |
| 194 | + else: |
| 195 | + log("Found %d deps that are currently not installed:" % \ |
| 196 | + len(deps_not_installed)) |
| 197 | + print("-" * 80) |
| 198 | + print("\n".join(deps_not_installed)) |
| 199 | + print("-" * 80) |
| 200 | + log("ERROR") |
| 201 | + return False |
| 202 | + |
| 203 | +if __name__ == "__main__": |
| 204 | + main() |
0 commit comments