Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(152)

Side by Side Diff: build/compiler_version.py

Issue 199793014: Extend compiler_version.py to work with clang output. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | build/compiler_version_unittest.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 # vim: set ts=2 sw=2 et sts=2 ai:
5 6
6 """Compiler version checking tool for gcc
7 7
8 Print gcc version as XY if you are running gcc X.Y.*. 8 """Compiler version checking tool.
9 This is used to tweak build flags for gcc 4.4. 9
10 Currently supports gcc and clang on Linux.
11
12 Allows getting the compiler, assembler and linker versions.
10 """ 13 """
11 14
12 import os 15 import os
13 import re 16 import re
14 import subprocess 17 import subprocess
18 import signal
19 import threading
15 import sys 20 import sys
16 21
17 22
18 def GetVersion(compiler, tool): 23 def call(cmdline):
19 tool_output = tool_error = None
20 try: 24 try:
21 # Note that compiler could be something tricky like "distcc g++". 25 pipe = subprocess.Popen(
22 if tool == "compiler": 26 cmdline, shell=True,
23 compiler = compiler + " -dumpversion" 27 stdout=subprocess.PIPE, stderr=subprocess.PIPE)
24 # 4.6
25 version_re = re.compile(r"(\d+)\.(\d+)")
26 elif tool == "assembler":
27 compiler = compiler + " -Xassembler --version -x assembler -c /dev/null"
28 # Unmodified: GNU assembler (GNU Binutils) 2.24
29 # Ubuntu: GNU assembler (GNU Binutils for Ubuntu) 2.22
30 # Fedora: GNU assembler version 2.23.2
31 version_re = re.compile(r"^GNU [^ ]+ .* (\d+).(\d+).*?$", re.M)
32 elif tool == "linker":
33 compiler = compiler + " -Xlinker --version"
34 # Using BFD linker
35 # Unmodified: GNU ld (GNU Binutils) 2.24
36 # Ubuntu: GNU ld (GNU Binutils for Ubuntu) 2.22
37 # Fedora: GNU ld version 2.23.2
38 # Using Gold linker
39 # Unmodified: GNU gold (GNU Binutils 2.24) 1.11
40 # Ubuntu: GNU gold (GNU Binutils for Ubuntu 2.22) 1.11
41 # Fedora: GNU gold (version 2.23.2) 1.11
42 version_re = re.compile(r"^GNU [^ ]+ .* (\d+).(\d+).*?$", re.M)
43 else:
44 raise Exception("Unknown tool %s" % tool)
45 28
46 pipe = subprocess.Popen(compiler, shell=True, 29 t = threading.Timer(0.25, pipe.terminate)
47 stdout=subprocess.PIPE, stderr=subprocess.PIPE) 30 t.start()
48 tool_output, tool_error = pipe.communicate() 31 tool_output, tool_error = pipe.communicate()
49 if pipe.returncode: 32 t.cancel()
50 raise subprocess.CalledProcessError(pipe.returncode, compiler) 33 return pipe.returncode, tool_output, tool_error
34 except subprocess.CalledProcessError, e:
35 return e.returncode, e.output[0], e.output[1]
51 36
52 result = version_re.match(tool_output) 37
53 return result.group(1) + result.group(2) 38 class GetVersionError(Exception):
54 except Exception, e: 39 pass
55 if tool_error: 40
56 sys.stderr.write(tool_error) 41
57 print >> sys.stderr, "compiler_version.py failed to execute:", compiler 42 def GetVersion(compiler, tool, call=call):
58 print >> sys.stderr, e 43 # Note that "compiler" is the string to launch the compiler which could
59 return "" 44 # contains all types of weirdness like "distcc g++".
45
46 if tool == "compiler":
47 totry = [" --version"]
48 version_re = re.compile(r"(?P<major>\d+)\.(?P<minor>\d+)")
49 output_fmt = "%i%i"
50 elif tool == "assembler":
51 totry = [
52 "-Xassembler -version -x assembler -c /dev/null",
53 # Mac's need just -v
54 "-Xassembler -v -x assembler -c /dev/null",
55 ]
56
57 # With clang we have to pass -no-integrated-as or -fno-integrated-as for
58 # the system assembler.
59 for args in list(totry):
60 totry.append("-no-integrated-as " + args)
61 totry.append("-fno-integrated-as " + args)
62
63 version_re = re.compile(
64 r"^.* assembler[ )].* (?P<major>\d+).(?P<minor>\d+).*?$",
65 re.M)
66 output_fmt = "%i%02i"
67 elif tool == "linker":
68 totry = ["-Xlinker -version"]
69 version_re = re.compile(
70 r"^.*[ :(-](ld|gold)[ )].* (?P<major>\d+).(?P<minor>\d+)(\.\d+)?$",
71 re.M)
72 output_fmt = "%i%02i"
73 else:
74 raise ValueError("Unknown tool %s" % tool)
75
76 errors = []
77 for arguments in totry:
78 cmdline = "%s %s" % (compiler, arguments)
79
80 retcode, tool_output, tool_error = call(cmdline)
81
82 result = version_re.search(tool_output)
83 if not result:
84 errors.append((retcode, cmdline, tool_output, tool_error))
85 continue
86
87 return output_fmt % (
88 int(result.group('major')), int(result.group('minor')))
89
90 error_output = """\
91 compiler_version.py was unable to execute requested tool. Error output follows
92
93 """
94 for retcode, cmdline, stdout, stderr in errors:
95 error_output += """\
96 compiler_version.py tried to execute: %s
97 Command returned %s
98
99 stdout output was
100 --------------------------------------------------------------------------
101 %s
102 --------------------------------------------------------------------------
103 stderr output was
104 --------------------------------------------------------------------------
105 %s
106 ==========================================================================
107 """ % (cmdline, retcode, stdout, stderr)
108 raise GetVersionError(error_output)
109
110
111 def FindCompiler(env):
112 cxx = env.get("CXX", None)
113 flags = env.get("CXXFLAGS", None)
114
115 if not cxx:
116 cxx = "c++"
117
118 if flags:
119 flags = " "+flags
120 else:
121 flags = ""
122
123 return cxx+flags
60 124
61 125
62 def main(args): 126 def main(args):
63 tool = "compiler" 127 tool = "compiler"
64 if len(args) == 1: 128 if len(args) == 1:
65 tool = args[0] 129 tool = args[0]
66 elif len(args) > 1: 130 elif len(args) > 1:
67 print "Unknown arguments!" 131 print "Unknown arguments!"
68 132
69 # Check if CXX environment variable exists and 133 cxxversion = GetVersion(FindCompiler(os.environ), tool)
70 # if it does use that compiler. 134 print cxxversion
71 cxx = os.getenv("CXX", None) 135 return 0
72 if cxx:
73 cxxversion = GetVersion(cxx, tool)
74 if cxxversion != "":
75 print cxxversion
76 return 0
77 else:
78 # Otherwise we check the g++ version.
79 gccversion = GetVersion("g++", tool)
80 if gccversion != "":
81 print gccversion
82 return 0
83
84 return 1
85 136
86 137
87 if __name__ == "__main__": 138 if __name__ == "__main__":
88 sys.exit(main(sys.argv[1:])) 139 sys.exit(main(sys.argv[1:]))
OLDNEW
« no previous file with comments | « no previous file | build/compiler_version_unittest.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698