Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 3 # Use of this source code is governed by a BSD-style license that can be |
| 4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
| 5 | 5 |
| 6 """Compiler version checking tool for gcc | 6 """Compiler version checking tool for gcc |
| 7 | 7 |
| 8 Print gcc version as XY if you are running gcc X.Y.*. | 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. | 9 This is used to tweak build flags for gcc 4.4. |
| 10 """ | 10 """ |
| 11 | 11 |
| 12 import os | 12 import os |
| 13 import re | 13 import re |
| 14 import subprocess | 14 import subprocess |
| 15 import sys | 15 import sys |
| 16 | 16 |
| 17 compiler_version_cache = {} # Map from (compiler, tool) -> version. | |
|
scottmg
2014/04/15 18:29:02
nit; two blank lines between top level things in p
scottmg
2014/04/15 18:29:02
nit; two spaces after code before #
| |
| 17 | 18 |
| 18 def GetVersion(compiler, tool): | 19 def GetVersion(compiler, tool): |
| 19 tool_output = tool_error = None | 20 tool_output = tool_error = None |
| 21 cache_key = (compiler, tool) | |
| 22 cached_version = compiler_version_cache.get(cache_key) | |
|
scottmg
2014/04/15 18:29:02
is it the cache (not-invoking-compiler) or the not
Daniel Bratell
2014/04/15 19:37:41
A bit hard to say because the python profiler does
| |
| 23 if cached_version: | |
| 24 return cached_version | |
| 20 try: | 25 try: |
| 21 # Note that compiler could be something tricky like "distcc g++". | 26 # Note that compiler could be something tricky like "distcc g++". |
| 22 if tool == "compiler": | 27 if tool == "compiler": |
| 23 compiler = compiler + " -dumpversion" | 28 compiler = compiler + " -dumpversion" |
| 24 # 4.6 | 29 # 4.6 |
| 25 version_re = re.compile(r"(\d+)\.(\d+)") | 30 version_re = re.compile(r"(\d+)\.(\d+)") |
| 26 elif tool == "assembler": | 31 elif tool == "assembler": |
| 27 compiler = compiler + " -Xassembler --version -x assembler -c /dev/null" | 32 compiler = compiler + " -Xassembler --version -x assembler -c /dev/null" |
| 28 # Unmodified: GNU assembler (GNU Binutils) 2.24 | 33 # Unmodified: GNU assembler (GNU Binutils) 2.24 |
| 29 # Ubuntu: GNU assembler (GNU Binutils for Ubuntu) 2.22 | 34 # Ubuntu: GNU assembler (GNU Binutils for Ubuntu) 2.22 |
| 30 # Fedora: GNU assembler version 2.23.2 | 35 # Fedora: GNU assembler version 2.23.2 |
| 31 version_re = re.compile(r"^GNU [^ ]+ .* (\d+).(\d+).*?$", re.M) | 36 version_re = re.compile(r"^GNU [^ ]+ .* (\d+).(\d+).*?$", re.M) |
| 32 elif tool == "linker": | 37 elif tool == "linker": |
| 33 compiler = compiler + " -Xlinker --version" | 38 compiler = compiler + " -Xlinker --version" |
| 34 # Using BFD linker | 39 # Using BFD linker |
| 35 # Unmodified: GNU ld (GNU Binutils) 2.24 | 40 # Unmodified: GNU ld (GNU Binutils) 2.24 |
| 36 # Ubuntu: GNU ld (GNU Binutils for Ubuntu) 2.22 | 41 # Ubuntu: GNU ld (GNU Binutils for Ubuntu) 2.22 |
| 37 # Fedora: GNU ld version 2.23.2 | 42 # Fedora: GNU ld version 2.23.2 |
| 38 # Using Gold linker | 43 # Using Gold linker |
| 39 # Unmodified: GNU gold (GNU Binutils 2.24) 1.11 | 44 # Unmodified: GNU gold (GNU Binutils 2.24) 1.11 |
| 40 # Ubuntu: GNU gold (GNU Binutils for Ubuntu 2.22) 1.11 | 45 # Ubuntu: GNU gold (GNU Binutils for Ubuntu 2.22) 1.11 |
| 41 # Fedora: GNU gold (version 2.23.2) 1.11 | 46 # Fedora: GNU gold (version 2.23.2) 1.11 |
| 42 version_re = re.compile(r"^GNU [^ ]+ .* (\d+).(\d+).*?$", re.M) | 47 version_re = re.compile(r"^GNU [^ ]+ .* (\d+).(\d+).*?$", re.M) |
| 43 else: | 48 else: |
| 44 raise Exception("Unknown tool %s" % tool) | 49 raise Exception("Unknown tool %s" % tool) |
| 45 | 50 |
| 46 pipe = subprocess.Popen(compiler, shell=True, | 51 # Force the locale to C otherwise the version string could be localized |
| 52 # making regex matching fail. | |
| 53 env = os.environ.copy() | |
| 54 env["LC_ALL"] = "C" | |
| 55 pipe = subprocess.Popen(compiler, shell=True, env=env, | |
| 47 stdout=subprocess.PIPE, stderr=subprocess.PIPE) | 56 stdout=subprocess.PIPE, stderr=subprocess.PIPE) |
| 48 tool_output, tool_error = pipe.communicate() | 57 tool_output, tool_error = pipe.communicate() |
| 49 if pipe.returncode: | 58 if pipe.returncode: |
| 50 raise subprocess.CalledProcessError(pipe.returncode, compiler) | 59 raise subprocess.CalledProcessError(pipe.returncode, compiler) |
| 51 | 60 |
| 52 result = version_re.match(tool_output) | 61 parsed_output = version_re.match(tool_output) |
| 53 return result.group(1) + result.group(2) | 62 result = parsed_output.group(1) + parsed_output.group(2) |
| 63 compiler_version_cache[cache_key] = result | |
| 64 return result | |
| 54 except Exception, e: | 65 except Exception, e: |
| 55 if tool_error: | 66 if tool_error: |
| 56 sys.stderr.write(tool_error) | 67 sys.stderr.write(tool_error) |
| 57 print >> sys.stderr, "compiler_version.py failed to execute:", compiler | 68 print >> sys.stderr, "compiler_version.py failed to execute:", compiler |
| 58 print >> sys.stderr, e | 69 print >> sys.stderr, e |
| 59 return "" | 70 return "" |
| 60 | 71 |
| 61 | 72 |
| 62 def main(args): | 73 def main(args): |
| 63 # Force the locale to C otherwise the version string could be localized | 74 (ret_code, result) = ExtractVersion(args) |
|
scottmg
2014/04/15 18:29:02
no parens around return value
| |
| 64 # making regex matching fail. | 75 if ret_code == 0: |
| 65 os.environ["LC_ALL"] = "C" | 76 print(result) |
|
scottmg
2014/04/15 18:29:02
no parens around print (as this file doesn't seem
| |
| 77 return ret_code | |
| 66 | 78 |
| 79 def DoMain(args): | |
| 80 """Hook to be called from gyp withing starting a separate python | |
|
scottmg
2014/04/15 18:29:02
withing -> without
| |
| 81 interpreter.""" | |
| 82 (ret_code, result) = ExtractVersion(args) | |
|
scottmg
2014/04/15 18:29:02
no parens on return
| |
| 83 if ret_code == 0: | |
| 84 return result | |
| 85 raise Exception("Failed to extract compiler version for args: %s" % args) | |
| 86 | |
| 87 def ExtractVersion(args): | |
| 67 tool = "compiler" | 88 tool = "compiler" |
| 68 if len(args) == 1: | 89 if len(args) == 1: |
| 69 tool = args[0] | 90 tool = args[0] |
| 70 elif len(args) > 1: | 91 elif len(args) > 1: |
| 71 print "Unknown arguments!" | 92 print "Unknown arguments!" |
| 72 | 93 |
| 73 # Check if CXX environment variable exists and | 94 # Check if CXX environment variable exists and |
| 74 # if it does use that compiler. | 95 # if it does use that compiler. |
| 75 cxx = os.getenv("CXX", None) | 96 cxx = os.getenv("CXX", None) |
|
scottmg
2014/04/15 18:29:02
change None to "g++" and delete the if/else
(I kn
| |
| 76 if cxx: | 97 if cxx: |
| 77 cxxversion = GetVersion(cxx, tool) | 98 cxxversion = GetVersion(cxx, tool) |
| 78 if cxxversion != "": | 99 if cxxversion != "": |
| 79 print cxxversion | 100 return (0, cxxversion) |
| 80 return 0 | |
| 81 else: | 101 else: |
| 82 # Otherwise we check the g++ version. | 102 # Otherwise we check the g++ version. |
| 83 gccversion = GetVersion("g++", tool) | 103 gccversion = GetVersion("g++", tool) |
| 84 if gccversion != "": | 104 if gccversion != "": |
| 85 print gccversion | 105 return (0, gccversion) |
| 86 return 0 | |
| 87 | 106 |
| 88 return 1 | 107 return (1, None) |
| 89 | 108 |
| 90 | 109 |
| 91 if __name__ == "__main__": | 110 if __name__ == "__main__": |
| 92 sys.exit(main(sys.argv[1:])) | 111 sys.exit(main(sys.argv[1:])) |
| OLD | NEW |