• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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