|  | #!/usr/bin/python | 
|  | # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 
|  | # Use of this source code is governed by a BSD-style license that can be | 
|  | # found in the LICENSE file. | 
|  |  | 
|  | """Diagnose some common system configuration problems on Linux, and | 
|  | suggest fixes.""" | 
|  |  | 
|  | import os | 
|  | import subprocess | 
|  | import sys | 
|  |  | 
|  | all_checks = [] | 
|  |  | 
|  | def Check(name): | 
|  | """Decorator that defines a diagnostic check.""" | 
|  | def wrap(func): | 
|  | all_checks.append((name, func)) | 
|  | return func | 
|  | return wrap | 
|  |  | 
|  |  | 
|  | @Check("/usr/bin/ld is not gold") | 
|  | def CheckSystemLd(): | 
|  | proc = subprocess.Popen(['/usr/bin/ld', '-v'], stdout=subprocess.PIPE) | 
|  | stdout = proc.communicate()[0] | 
|  | if 'GNU gold' in stdout: | 
|  | return ("When /usr/bin/ld is gold, system updates can silently\n" | 
|  | "corrupt your graphics drivers.\n" | 
|  | "Try 'sudo apt-get remove binutils-gold'.\n") | 
|  | return None | 
|  |  | 
|  |  | 
|  | @Check("random lds are not in the $PATH") | 
|  | def CheckPathLd(): | 
|  | proc = subprocess.Popen(['which', '-a', 'ld'], stdout=subprocess.PIPE) | 
|  | stdout = proc.communicate()[0] | 
|  | instances = stdout.split() | 
|  | if len(instances) > 1: | 
|  | return ("You have multiple 'ld' binaries in your $PATH:\n" | 
|  | + '\n'.join(' - ' + i for i in instances) + "\n" | 
|  | "You should delete all of them but your system one.\n" | 
|  | "gold is hooked into your build via gyp.\n") | 
|  | return None | 
|  |  | 
|  |  | 
|  | @Check("/usr/bin/ld doesn't point to gold") | 
|  | def CheckLocalGold(): | 
|  | # Check /usr/bin/ld* symlinks. | 
|  | for path in ('ld.bfd', 'ld'): | 
|  | path = '/usr/bin/' + path | 
|  | try: | 
|  | target = os.readlink(path) | 
|  | except OSError, e: | 
|  | if e.errno == 2: | 
|  | continue  # No such file | 
|  | if e.errno == 22: | 
|  | continue  # Not a symlink | 
|  | raise | 
|  | if '/usr/local/gold' in target: | 
|  | return ("%s is a symlink into /usr/local/gold.\n" | 
|  | "It's difficult to make a recommendation, because you\n" | 
|  | "probably set this up yourself.  But you should make\n" | 
|  | "/usr/bin/ld be the standard linker, which you likely\n" | 
|  | "renamed /usr/bin/ld.bfd or something like that.\n" % path) | 
|  |  | 
|  | return None | 
|  |  | 
|  |  | 
|  | @Check("random ninja binaries are not in the $PATH") | 
|  | def CheckPathNinja(): | 
|  | proc = subprocess.Popen(['which', 'ninja'], stdout=subprocess.PIPE) | 
|  | stdout = proc.communicate()[0] | 
|  | if not 'depot_tools' in stdout: | 
|  | return ("The ninja binary in your path isn't from depot_tools:\n" | 
|  | + "    " + stdout + | 
|  | "Remove custom ninjas from your path so that the one\n" | 
|  | "in depot_tools is used.\n") | 
|  | return None | 
|  |  | 
|  |  | 
|  | @Check("build dependencies are satisfied") | 
|  | def CheckBuildDeps(): | 
|  | script_path = os.path.join( | 
|  | os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'build', | 
|  | 'install-build-deps.sh') | 
|  | proc = subprocess.Popen([script_path, '--quick-check'], | 
|  | stdout=subprocess.PIPE) | 
|  | stdout = proc.communicate()[0] | 
|  | if 'WARNING' in stdout: | 
|  | return ("Your build dependencies are out-of-date.\n" | 
|  | "Run '" + script_path + "' to update.") | 
|  | return None | 
|  |  | 
|  |  | 
|  | def RunChecks(): | 
|  | for name, check in all_checks: | 
|  | sys.stdout.write("* Checking %s: " % name) | 
|  | sys.stdout.flush() | 
|  | error = check() | 
|  | if not error: | 
|  | print "ok" | 
|  | else: | 
|  | print "FAIL" | 
|  | print error | 
|  |  | 
|  |  | 
|  | if __name__ == '__main__': | 
|  | RunChecks() |