| OLD | NEW |
| (Empty) |
| 1 #!/usr/bin/env python | |
| 2 # Copyright 2015 The Chromium Authors. All rights reserved. | |
| 3 # Use of this source code is governed by a BSD-style license that can be | |
| 4 # found in the LICENSE file. | |
| 5 | |
| 6 import argparse | |
| 7 import operator | |
| 8 import os | |
| 9 import platform | |
| 10 import re | |
| 11 import subprocess | |
| 12 import sys | |
| 13 | |
| 14 | |
| 15 SUPPORTED_UBUNTU_VERSIONS = ( | |
| 16 {'number': '12.04', 'codename': 'precise'}, | |
| 17 {'number': '14.04', 'codename': 'trusty'}, | |
| 18 {'number': '14.10', 'codename': 'utopic'}, | |
| 19 {'number': '15.04', 'codename': 'vivid'}, | |
| 20 ) | |
| 21 | |
| 22 | |
| 23 # Packages needed for chromeos only. | |
| 24 _packages_chromeos_dev = ( | |
| 25 'libbluetooth-dev', | |
| 26 'libxkbcommon-dev', | |
| 27 'realpath', | |
| 28 ) | |
| 29 | |
| 30 | |
| 31 # Packages needed for development. | |
| 32 _packages_dev = ( | |
| 33 'apache2.2-bin', | |
| 34 'bison', | |
| 35 'cdbs', | |
| 36 'curl', | |
| 37 'devscripts', | |
| 38 'dpkg-dev', | |
| 39 'elfutils', | |
| 40 'fakeroot', | |
| 41 'flex', | |
| 42 'fonts-thai-tlwg', | |
| 43 'g++', | |
| 44 'git-core', | |
| 45 'git-svn', | |
| 46 'gperf', | |
| 47 'language-pack-da', | |
| 48 'language-pack-fr', | |
| 49 'language-pack-he', | |
| 50 'language-pack-zh-hant', | |
| 51 'libapache2-mod-php5', | |
| 52 'libasound2-dev', | |
| 53 'libav-tools', | |
| 54 'libbrlapi-dev', | |
| 55 'libbz2-dev', | |
| 56 'libcairo2-dev', | |
| 57 'libcap-dev', | |
| 58 'libcups2-dev', | |
| 59 'libcurl4-gnutls-dev', | |
| 60 'libdrm-dev', | |
| 61 'libelf-dev', | |
| 62 'libexif-dev', | |
| 63 'libgconf2-dev', | |
| 64 'libglib2.0-dev', | |
| 65 'libglu1-mesa-dev', | |
| 66 'libgnome-keyring-dev', | |
| 67 'libgtk2.0-dev', | |
| 68 'libkrb5-dev', | |
| 69 'libnspr4-dev', | |
| 70 'libnss3-dev', | |
| 71 'libpam0g-dev', | |
| 72 'libpci-dev', | |
| 73 'libpulse-dev', | |
| 74 'libsctp-dev', | |
| 75 'libspeechd-dev', | |
| 76 'libsqlite3-dev', | |
| 77 'libssl-dev', | |
| 78 'libudev-dev', | |
| 79 'libwww-perl', | |
| 80 'libxslt1-dev', | |
| 81 'libxss-dev', | |
| 82 'libxt-dev', | |
| 83 'libxtst-dev', | |
| 84 'openbox', | |
| 85 'patch', | |
| 86 'perl', | |
| 87 'php5-cgi', | |
| 88 'pkg-config', | |
| 89 'python', | |
| 90 'python-cherrypy3', | |
| 91 'python-crypto', | |
| 92 'python-dev', | |
| 93 'python-numpy', | |
| 94 'python-opencv', | |
| 95 'python-openssl', | |
| 96 'python-psutil', | |
| 97 'python-yaml', | |
| 98 'rpm', | |
| 99 'ruby', | |
| 100 'subversion', | |
| 101 'ttf-dejavu-core', | |
| 102 'ttf-indic-fonts', | |
| 103 'ttf-kochi-gothic', | |
| 104 'ttf-kochi-mincho', | |
| 105 'wdiff', | |
| 106 'xfonts-mathml', | |
| 107 'zip', | |
| 108 ) | |
| 109 | |
| 110 | |
| 111 # Run-time libraries required by chromeos only. | |
| 112 _packages_chromeos_lib = ( | |
| 113 'libbz2-1.0', | |
| 114 'libpulse0', | |
| 115 ) | |
| 116 | |
| 117 | |
| 118 # Full list of required run-time libraries. | |
| 119 _packages_lib = ( | |
| 120 'libasound2', | |
| 121 'libatk1.0-0', | |
| 122 'libc6', | |
| 123 'libcairo2', | |
| 124 'libcap2', | |
| 125 'libcups2', | |
| 126 'libexif12', | |
| 127 'libexpat1', | |
| 128 'libfontconfig1', | |
| 129 'libfreetype6', | |
| 130 'libglib2.0-0', | |
| 131 'libgnome-keyring0', | |
| 132 'libgtk2.0-0', | |
| 133 'libpam0g', | |
| 134 'libpango1.0-0', | |
| 135 'libpci3', | |
| 136 'libpcre3', | |
| 137 'libpixman-1-0', | |
| 138 'libpng12-0', | |
| 139 'libspeechd2', | |
| 140 'libsqlite3-0', | |
| 141 'libstdc++6', | |
| 142 'libx11-6', | |
| 143 'libxau6', | |
| 144 'libxcb1', | |
| 145 'libxcomposite1', | |
| 146 'libxcursor1', | |
| 147 'libxdamage1', | |
| 148 'libxdmcp6', | |
| 149 'libxext6', | |
| 150 'libxfixes3', | |
| 151 'libxi6', | |
| 152 'libxinerama1', | |
| 153 'libxrandr2', | |
| 154 'libxrender1', | |
| 155 'libxtst6', | |
| 156 'zlib1g', | |
| 157 ) | |
| 158 | |
| 159 | |
| 160 # Debugging symbols for all of the run-time libraries. | |
| 161 _packages_dbg = ( | |
| 162 'libatk1.0-dbg', | |
| 163 'libc6-dbg', | |
| 164 'libcairo2-dbg', | |
| 165 'libfontconfig1-dbg', | |
| 166 'libglib2.0-0-dbg', | |
| 167 'libgtk2.0-0-dbg', | |
| 168 'libpango1.0-0-dbg', | |
| 169 'libpcre3-dbg', | |
| 170 'libpixman-1-0-dbg', | |
| 171 'libsqlite3-0-dbg', | |
| 172 'libx11-6-dbg', | |
| 173 'libxau6-dbg', | |
| 174 'libxcb1-dbg', | |
| 175 'libxcomposite1-dbg', | |
| 176 'libxcursor1-dbg', | |
| 177 'libxdamage1-dbg', | |
| 178 'libxdmcp6-dbg', | |
| 179 'libxext6-dbg', | |
| 180 'libxfixes3-dbg', | |
| 181 'libxi6-dbg', | |
| 182 'libxinerama1-dbg', | |
| 183 'libxrandr2-dbg', | |
| 184 'libxrender1-dbg', | |
| 185 'libxtst6-dbg', | |
| 186 'zlib1g-dbg', | |
| 187 ) | |
| 188 | |
| 189 | |
| 190 # 32-bit libraries needed e.g. to compile V8 snapshot for Android or armhf. | |
| 191 _packages_lib32 = ( | |
| 192 'linux-libc-dev:i386', | |
| 193 ) | |
| 194 | |
| 195 | |
| 196 # arm cross toolchain packages needed to build chrome on armhf. | |
| 197 _packages_arm = ( | |
| 198 'g++-arm-linux-gnueabihf', | |
| 199 'libc6-dev-armhf-cross', | |
| 200 'linux-libc-dev-armhf-cross', | |
| 201 ) | |
| 202 | |
| 203 | |
| 204 # Packages to build NaCl, its toolchains, and its ports. | |
| 205 _packages_naclports = ( | |
| 206 'ant', | |
| 207 'autoconf', | |
| 208 'bison', | |
| 209 'cmake', | |
| 210 'gawk', | |
| 211 'intltool', | |
| 212 'xsltproc', | |
| 213 'xutils-dev', | |
| 214 ) | |
| 215 _packages_nacl = ( | |
| 216 'g++-mingw-w64-i686', | |
| 217 'lib32ncurses5-dev', | |
| 218 'lib32z1-dev', | |
| 219 'libasound2:i386', | |
| 220 'libcap2:i386', | |
| 221 'libelf-dev:i386', | |
| 222 'libexif12:i386', | |
| 223 'libfontconfig1:i386', | |
| 224 'libgconf-2-4:i386', | |
| 225 'libglib2.0-0:i386', | |
| 226 'libgpm2:i386', | |
| 227 'libgtk2.0-0:i386', | |
| 228 'libncurses5:i386', | |
| 229 'libnss3:i386', | |
| 230 'libpango1.0-0:i386', | |
| 231 'libssl1.0.0:i386', | |
| 232 'libtinfo-dev', | |
| 233 'libtinfo-dev:i386', | |
| 234 'libtool', | |
| 235 'libxcomposite1:i386', | |
| 236 'libxcursor1:i386', | |
| 237 'libxdamage1:i386', | |
| 238 'libxi6:i386', | |
| 239 'libxrandr2:i386', | |
| 240 'libxss1:i386', | |
| 241 'libxtst6:i386', | |
| 242 'texinfo', | |
| 243 'xvfb', | |
| 244 ) | |
| 245 | |
| 246 | |
| 247 def is_userland_64_bit(): | |
| 248 return platform.architecture()[0] == '64bit' | |
| 249 | |
| 250 | |
| 251 def package_exists(pkg): | |
| 252 return pkg in subprocess.check_output(['apt-cache', 'pkgnames']).splitlines() | |
| 253 | |
| 254 | |
| 255 def lsb_release_short_codename(): | |
| 256 return subprocess.check_output( | |
| 257 ['lsb_release', '--codename', '--short']).strip() | |
| 258 | |
| 259 | |
| 260 def write_error(message): | |
| 261 sys.stderr.write('ERROR: %s\n' % message) | |
| 262 sys.stderr.flush() | |
| 263 | |
| 264 | |
| 265 def nonfatal_get_output(*popenargs, **kwargs): | |
| 266 process = subprocess.Popen( | |
| 267 stdout=subprocess.PIPE, stderr=subprocess.PIPE, *popenargs, **kwargs) | |
| 268 stdout, stderr = process.communicate() | |
| 269 retcode = process.poll() | |
| 270 return retcode, stdout, stderr | |
| 271 | |
| 272 | |
| 273 def compute_dynamic_package_lists(): | |
| 274 global _packages_arm | |
| 275 global _packages_dbg | |
| 276 global _packages_dev | |
| 277 global _packages_lib | |
| 278 global _packages_lib32 | |
| 279 global _packages_nacl | |
| 280 | |
| 281 if is_userland_64_bit(): | |
| 282 # 64-bit systems need a minimum set of 32-bit compat packages | |
| 283 # for the pre-built NaCl binaries. | |
| 284 _packages_dev += ( | |
| 285 'lib32gcc1', | |
| 286 'lib32stdc++6', | |
| 287 'libc6-i386', | |
| 288 ) | |
| 289 | |
| 290 # When cross building for arm/Android on 64-bit systems the host binaries | |
| 291 # that are part of v8 need to be compiled with -m32 which means | |
| 292 # that basic multilib support is needed. | |
| 293 # gcc-multilib conflicts with the arm cross compiler (at least in trusty) | |
| 294 # but g++-X.Y-multilib gives us the 32-bit support that we need. Find out | |
| 295 # the appropriate value of X and Y by seeing what version the current | |
| 296 # distribution's g++-multilib package depends on. | |
| 297 output = subprocess.check_output(['apt-cache', 'depends', 'g++-multilib']) | |
| 298 multilib_package = re.search(r'g\+\+-[0-9.]+-multilib', output).group() | |
| 299 _packages_lib32 += (multilib_package,) | |
| 300 | |
| 301 lsb_codename = lsb_release_short_codename() | |
| 302 | |
| 303 # Find the proper version of libstdc++6-4.x-dbg. | |
| 304 if lsb_codename == 'precise': | |
| 305 _packages_dbg += ('libstdc++6-4.6-dbg',) | |
| 306 elif lsb_codename == 'trusty': | |
| 307 _packages_dbg += ('libstdc++6-4.8-dbg',) | |
| 308 else: | |
| 309 _packages_dbg += ('libstdc++6-4.9-dbg',) | |
| 310 | |
| 311 # Work around for dependency issue Ubuntu/Trusty: http://crbug.com/435056 . | |
| 312 if lsb_codename == 'trusty': | |
| 313 _packages_arm += ( | |
| 314 'g++-4.8-multilib-arm-linux-gnueabihf', | |
| 315 'gcc-4.8-multilib-arm-linux-gnueabihf', | |
| 316 ) | |
| 317 | |
| 318 # Find the proper version of libgbm-dev. We can't just install libgbm-dev as | |
| 319 # it depends on mesa, and only one version of mesa can exists on the system. | |
| 320 # Hence we must match the same version or this entire script will fail. | |
| 321 mesa_variant = '' | |
| 322 for variant in ('-lts-trusty', '-lts-utopic'): | |
| 323 rc, stdout, stderr = nonfatal_get_output( | |
| 324 ['dpkg-query', '-Wf\'{Status}\'', 'libgl1-mesa-glx' + variant]) | |
| 325 if 'ok installed' in output: | |
| 326 mesa_variant = variant | |
| 327 _packages_dev += ( | |
| 328 'libgbm-dev' + mesa_variant, | |
| 329 'libgl1-mesa-dev' + mesa_variant, | |
| 330 'libgles2-mesa-dev' + mesa_variant, | |
| 331 'mesa-common-dev' + mesa_variant, | |
| 332 ) | |
| 333 | |
| 334 if package_exists('ttf-mscorefonts-installer'): | |
| 335 _packages_dev += ('ttf-mscorefonts-installer',) | |
| 336 else: | |
| 337 _packages_dev += ('msttcorefonts',) | |
| 338 | |
| 339 if package_exists('libnspr4-dbg'): | |
| 340 _packages_dbg += ('libnspr4-dbg', 'libnss3-dbg') | |
| 341 _packages_lib += ('libnspr4', 'libnss3') | |
| 342 else: | |
| 343 _packages_dbg += ('libnspr4-0d-dbg', 'libnss3-1d-dbg') | |
| 344 _packages_lib += ('libnspr4-0d', 'libnss3-1d') | |
| 345 | |
| 346 if package_exists('libjpeg-dev'): | |
| 347 _packages_dev += ('libjpeg-dev',) | |
| 348 else: | |
| 349 _packages_dev += ('libjpeg62-dev',) | |
| 350 | |
| 351 if package_exists('libudev1'): | |
| 352 _packages_dev += ('libudev1',) | |
| 353 _packages_nacl += ('libudev1:i386',) | |
| 354 else: | |
| 355 _packages_dev += ('libudev0',) | |
| 356 _packages_nacl += ('libudev0:i386',) | |
| 357 | |
| 358 if package_exists('libbrlapi0.6'): | |
| 359 _packages_dev += ('libbrlapi0.6',) | |
| 360 else: | |
| 361 _packages_dev += ('libbrlapi0.5',) | |
| 362 | |
| 363 # Some packages are only needed if the distribution actually supports | |
| 364 # installing them. | |
| 365 if package_exists('appmenu-gtk'): | |
| 366 _packages_lib += ('appmenu-gtk',) | |
| 367 | |
| 368 _packages_dev += _packages_chromeos_dev | |
| 369 _packages_lib += _packages_chromeos_lib | |
| 370 _packages_nacl += _packages_naclports | |
| 371 | |
| 372 | |
| 373 def quick_check(packages): | |
| 374 rc, stdout, stderr = nonfatal_get_output([ | |
| 375 'dpkg-query', '-W', '-f', '${PackageSpec}:${Status}\n'] + list(packages)) | |
| 376 if rc == 0 and not stderr: | |
| 377 return 0 | |
| 378 print stderr | |
| 379 return 1 | |
| 380 | |
| 381 | |
| 382 def main(argv): | |
| 383 parser = argparse.ArgumentParser() | |
| 384 parser.add_argument('--quick-check', action='store_true', | |
| 385 help='quickly try to determine if dependencies are ' | |
| 386 'installed (this avoids interactive prompts and ' | |
| 387 'sudo commands so might not be 100% accurate)') | |
| 388 parser.add_argument('--unsupported', action='store_true', | |
| 389 help='attempt installation even on unsupported systems') | |
| 390 args = parser.parse_args(argv) | |
| 391 | |
| 392 lsb_codename = lsb_release_short_codename() | |
| 393 if not args.unsupported and not args.quick_check: | |
| 394 if lsb_codename not in map( | |
| 395 operator.itemgetter('codename'), SUPPORTED_UBUNTU_VERSIONS): | |
| 396 supported_ubuntus = ['%(number)s (%(codename)s)' % v | |
| 397 for v in SUPPORTED_UBUNTU_VERSIONS] | |
| 398 write_error('Only Ubuntu %s are currently supported.' % | |
| 399 ', '.join(supported_ubuntus)) | |
| 400 return 1 | |
| 401 | |
| 402 if platform.machine() not in ('i686', 'x86_64'): | |
| 403 write_error('Only x86 architectures are currently supported.') | |
| 404 return 1 | |
| 405 | |
| 406 if os.geteuid() != 0 and not args.quick_check: | |
| 407 print 'Running as non-root user.' | |
| 408 print 'You might have to enter your password one or more times' | |
| 409 print 'for \'sudo\'.' | |
| 410 print | |
| 411 | |
| 412 compute_dynamic_package_lists() | |
| 413 | |
| 414 packages = (_packages_dev + _packages_lib + _packages_dbg + _packages_lib32 + | |
| 415 _packages_arm + _packages_nacl) | |
| 416 def packages_key(pkg): | |
| 417 s = pkg.rsplit(':', 1) | |
| 418 if len(s) == 1: | |
| 419 return (s, '') | |
| 420 return s | |
| 421 packages = sorted(set(packages), key=packages_key) | |
| 422 | |
| 423 if args.quick_check: | |
| 424 return quick_check(packages) | |
| 425 | |
| 426 return 0 | |
| 427 | |
| 428 | |
| 429 if __name__ == '__main__': | |
| 430 sys.exit(main(sys.argv[1:])) | |
| OLD | NEW |