Blink roll 171837:171848
[chromium-blink-merge.git] / build / compiler_version.py
blob48df6c8ba9858ee6a647565d668fc569ba32b533
1 #!/usr/bin/env 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.
6 """Compiler version checking tool for gcc
8 Print gcc version as XY if you are running gcc X.Y.*.
9 This is used to tweak build flags for gcc 4.4.
10 """
12 import os
13 import re
14 import subprocess
15 import sys
18 compiler_version_cache = {} # Map from (compiler, tool) -> version.
21 def GetVersion(compiler, tool):
22 tool_output = tool_error = None
23 cache_key = (compiler, tool)
24 cached_version = compiler_version_cache.get(cache_key)
25 if cached_version:
26 return cached_version
27 try:
28 # Note that compiler could be something tricky like "distcc g++".
29 if tool == "compiler":
30 compiler = compiler + " -dumpversion"
31 # 4.6
32 version_re = re.compile(r"(\d+)\.(\d+)")
33 elif tool == "assembler":
34 compiler = compiler + " -Xassembler --version -x assembler -c /dev/null"
35 # Unmodified: GNU assembler (GNU Binutils) 2.24
36 # Ubuntu: GNU assembler (GNU Binutils for Ubuntu) 2.22
37 # Fedora: GNU assembler version 2.23.2
38 version_re = re.compile(r"^GNU [^ ]+ .* (\d+).(\d+).*?$", re.M)
39 elif tool == "linker":
40 compiler = compiler + " -Xlinker --version"
41 # Using BFD linker
42 # Unmodified: GNU ld (GNU Binutils) 2.24
43 # Ubuntu: GNU ld (GNU Binutils for Ubuntu) 2.22
44 # Fedora: GNU ld version 2.23.2
45 # Using Gold linker
46 # Unmodified: GNU gold (GNU Binutils 2.24) 1.11
47 # Ubuntu: GNU gold (GNU Binutils for Ubuntu 2.22) 1.11
48 # Fedora: GNU gold (version 2.23.2) 1.11
49 version_re = re.compile(r"^GNU [^ ]+ .* (\d+).(\d+).*?$", re.M)
50 else:
51 raise Exception("Unknown tool %s" % tool)
53 # Force the locale to C otherwise the version string could be localized
54 # making regex matching fail.
55 env = os.environ.copy()
56 env["LC_ALL"] = "C"
57 pipe = subprocess.Popen(compiler, shell=True, env=env,
58 stdout=subprocess.PIPE, stderr=subprocess.PIPE)
59 tool_output, tool_error = pipe.communicate()
60 if pipe.returncode:
61 raise subprocess.CalledProcessError(pipe.returncode, compiler)
63 parsed_output = version_re.match(tool_output)
64 result = parsed_output.group(1) + parsed_output.group(2)
65 compiler_version_cache[cache_key] = result
66 return result
67 except Exception, e:
68 if tool_error:
69 sys.stderr.write(tool_error)
70 print >> sys.stderr, "compiler_version.py failed to execute:", compiler
71 print >> sys.stderr, e
72 return ""
75 def main(args):
76 ret_code, result = ExtractVersion(args)
77 if ret_code == 0:
78 print result
79 return ret_code
82 def DoMain(args):
83 """Hook to be called from gyp without starting a separate python
84 interpreter."""
85 ret_code, result = ExtractVersion(args)
86 if ret_code == 0:
87 return result
88 raise Exception("Failed to extract compiler version for args: %s" % args)
91 def ExtractVersion(args):
92 tool = "compiler"
93 if len(args) == 1:
94 tool = args[0]
95 elif len(args) > 1:
96 print "Unknown arguments!"
98 # Check if CXX environment variable exists and if it does use that
99 # compiler, otherwise check g++.
100 compiler = os.getenv("CXX", "g++")
101 if compiler:
102 compiler_version = GetVersion(compiler, tool)
103 if compiler_version != "":
104 return (0, compiler_version)
106 return (1, None)
109 if __name__ == "__main__":
110 sys.exit(main(sys.argv[1:]))