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.
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'},
23 # Packages needed for chromeos only.
24 _packages_chromeos_dev
= (
31 # Packages needed for development.
50 'language-pack-zh-hant',
51 'libapache2-mod-php5',
59 'libcurl4-gnutls-dev',
66 'libgnome-keyring-dev',
111 # Run-time libraries required by chromeos only.
112 _packages_chromeos_lib
= (
118 # Full list of required run-time libraries.
160 # Debugging symbols for all of the run-time libraries.
165 'libfontconfig1-dbg',
175 'libxcomposite1-dbg',
190 # 32-bit libraries needed e.g. to compile V8 snapshot for Android or armhf.
192 'linux-libc-dev:i386',
196 # arm cross toolchain packages needed to build chrome on armhf.
198 'g++-arm-linux-gnueabihf',
199 'libc6-dev-armhf-cross',
200 'linux-libc-dev-armhf-cross',
204 # Packages to build NaCl, its toolchains, and its ports.
205 _packages_naclports
= (
216 'g++-mingw-w64-i686',
223 'libfontconfig1:i386',
230 'libpango1.0-0:i386',
235 'libxcomposite1:i386',
247 def is_userland_64_bit():
248 return platform
.architecture()[0] == '64bit'
251 def package_exists(pkg
):
252 return pkg
in subprocess
.check_output(['apt-cache', 'pkgnames']).splitlines()
255 def lsb_release_short_codename():
256 return subprocess
.check_output(
257 ['lsb_release', '--codename', '--short']).strip()
260 def write_error(message
):
261 sys
.stderr
.write('ERROR: %s\n' % message
)
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
273 def compute_dynamic_package_lists():
278 global _packages_lib32
279 global _packages_nacl
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.
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
,)
301 lsb_codename
= lsb_release_short_codename()
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',)
309 _packages_dbg
+= ('libstdc++6-4.9-dbg',)
311 # Work around for dependency issue Ubuntu/Trusty: http://crbug.com/435056 .
312 if lsb_codename
== 'trusty':
314 'g++-4.8-multilib-arm-linux-gnueabihf',
315 'gcc-4.8-multilib-arm-linux-gnueabihf',
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.
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
328 'libgbm-dev' + mesa_variant
,
329 'libgl1-mesa-dev' + mesa_variant
,
330 'libgles2-mesa-dev' + mesa_variant
,
331 'mesa-common-dev' + mesa_variant
,
334 if package_exists('ttf-mscorefonts-installer'):
335 _packages_dev
+= ('ttf-mscorefonts-installer',)
337 _packages_dev
+= ('msttcorefonts',)
339 if package_exists('libnspr4-dbg'):
340 _packages_dbg
+= ('libnspr4-dbg', 'libnss3-dbg')
341 _packages_lib
+= ('libnspr4', 'libnss3')
343 _packages_dbg
+= ('libnspr4-0d-dbg', 'libnss3-1d-dbg')
344 _packages_lib
+= ('libnspr4-0d', 'libnss3-1d')
346 if package_exists('libjpeg-dev'):
347 _packages_dev
+= ('libjpeg-dev',)
349 _packages_dev
+= ('libjpeg62-dev',)
351 if package_exists('libudev1'):
352 _packages_dev
+= ('libudev1',)
353 _packages_nacl
+= ('libudev1:i386',)
355 _packages_dev
+= ('libudev0',)
356 _packages_nacl
+= ('libudev0:i386',)
358 if package_exists('libbrlapi0.6'):
359 _packages_dev
+= ('libbrlapi0.6',)
361 _packages_dev
+= ('libbrlapi0.5',)
363 # Some packages are only needed if the distribution actually supports
365 if package_exists('appmenu-gtk'):
366 _packages_lib
+= ('appmenu-gtk',)
368 _packages_dev
+= _packages_chromeos_dev
369 _packages_lib
+= _packages_chromeos_lib
370 _packages_nacl
+= _packages_naclports
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
:
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
)
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
))
402 if platform
.machine() not in ('i686', 'x86_64'):
403 write_error('Only x86 architectures are currently supported.')
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\'.'
412 compute_dynamic_package_lists()
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)
421 packages
= sorted(set(packages
), key
=packages_key
)
424 return quick_check(packages
)
429 if __name__
== '__main__':
430 sys
.exit(main(sys
.argv
[1:]))