1#!/usr/bin/python 2# Copyright (c) 2012 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"""Diagnose some common system configuration problems on Linux, and 7suggest fixes.""" 8 9import os 10import subprocess 11import sys 12 13all_checks = [] 14 15def Check(name): 16 """Decorator that defines a diagnostic check.""" 17 def wrap(func): 18 all_checks.append((name, func)) 19 return func 20 return wrap 21 22 23@Check("/usr/bin/ld is not gold") 24def CheckSystemLd(): 25 proc = subprocess.Popen(['/usr/bin/ld', '-v'], stdout=subprocess.PIPE) 26 stdout = proc.communicate()[0] 27 if 'GNU gold' in stdout: 28 return ("When /usr/bin/ld is gold, system updates can silently\n" 29 "corrupt your graphics drivers.\n" 30 "Try 'sudo apt-get remove binutils-gold'.\n") 31 return None 32 33 34@Check("random lds are not in the $PATH") 35def CheckPathLd(): 36 proc = subprocess.Popen(['which', '-a', 'ld'], stdout=subprocess.PIPE) 37 stdout = proc.communicate()[0] 38 instances = stdout.split() 39 if len(instances) > 1: 40 return ("You have multiple 'ld' binaries in your $PATH:\n" 41 + '\n'.join(' - ' + i for i in instances) + "\n" 42 "You should delete all of them but your system one.\n" 43 "gold is hooked into your build via gyp.\n") 44 return None 45 46 47@Check("/usr/bin/ld doesn't point to gold") 48def CheckLocalGold(): 49 # Check /usr/bin/ld* symlinks. 50 for path in ('ld.bfd', 'ld'): 51 path = '/usr/bin/' + path 52 try: 53 target = os.readlink(path) 54 except OSError, e: 55 if e.errno == 2: 56 continue # No such file 57 if e.errno == 22: 58 continue # Not a symlink 59 raise 60 if '/usr/local/gold' in target: 61 return ("%s is a symlink into /usr/local/gold.\n" 62 "It's difficult to make a recommendation, because you\n" 63 "probably set this up yourself. But you should make\n" 64 "/usr/bin/ld be the standard linker, which you likely\n" 65 "renamed /usr/bin/ld.bfd or something like that.\n" % path) 66 67 return None 68 69 70@Check("random ninja binaries are not in the $PATH") 71def CheckPathNinja(): 72 proc = subprocess.Popen(['which', 'ninja'], stdout=subprocess.PIPE) 73 stdout = proc.communicate()[0] 74 if not 'depot_tools' in stdout: 75 return ("The ninja binary in your path isn't from depot_tools:\n" 76 + " " + stdout + 77 "Remove custom ninjas from your path so that the one\n" 78 "in depot_tools is used.\n") 79 return None 80 81 82@Check("build dependencies are satisfied") 83def CheckBuildDeps(): 84 script_path = os.path.join( 85 os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'build', 86 'install-build-deps.sh') 87 proc = subprocess.Popen([script_path, '--quick-check'], 88 stdout=subprocess.PIPE) 89 stdout = proc.communicate()[0] 90 if 'WARNING' in stdout: 91 return ("Your build dependencies are out-of-date.\n" 92 "Run '" + script_path + "' to update.") 93 return None 94 95 96def RunChecks(): 97 for name, check in all_checks: 98 sys.stdout.write("* Checking %s: " % name) 99 sys.stdout.flush() 100 error = check() 101 if not error: 102 print "ok" 103 else: 104 print "FAIL" 105 print error 106 107 108if __name__ == '__main__': 109 RunChecks() 110