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

Unified 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | build/compiler_version_unittest.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: build/compiler_version.py
diff --git a/build/compiler_version.py b/build/compiler_version.py
index b06712d25b2d3c25990a97f99a630a66c703ce0b..aa6df62f7542d3d7231e0f9923b3f71ef183d843 100755
--- a/build/compiler_version.py
+++ b/build/compiler_version.py
@@ -2,61 +2,125 @@
# Copyright (c) 2012 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+# vim: set ts=2 sw=2 et sts=2 ai:
-"""Compiler version checking tool for gcc
-Print gcc version as XY if you are running gcc X.Y.*.
-This is used to tweak build flags for gcc 4.4.
+"""Compiler version checking tool.
+
+Currently supports gcc and clang on Linux.
+
+Allows getting the compiler, assembler and linker versions.
"""
import os
import re
import subprocess
+import signal
+import threading
import sys
-def GetVersion(compiler, tool):
- tool_output = tool_error = None
+def call(cmdline):
try:
- # Note that compiler could be something tricky like "distcc g++".
- if tool == "compiler":
- compiler = compiler + " -dumpversion"
- # 4.6
- version_re = re.compile(r"(\d+)\.(\d+)")
- elif tool == "assembler":
- compiler = compiler + " -Xassembler --version -x assembler -c /dev/null"
- # Unmodified: GNU assembler (GNU Binutils) 2.24
- # Ubuntu: GNU assembler (GNU Binutils for Ubuntu) 2.22
- # Fedora: GNU assembler version 2.23.2
- version_re = re.compile(r"^GNU [^ ]+ .* (\d+).(\d+).*?$", re.M)
- elif tool == "linker":
- compiler = compiler + " -Xlinker --version"
- # Using BFD linker
- # Unmodified: GNU ld (GNU Binutils) 2.24
- # Ubuntu: GNU ld (GNU Binutils for Ubuntu) 2.22
- # Fedora: GNU ld version 2.23.2
- # Using Gold linker
- # Unmodified: GNU gold (GNU Binutils 2.24) 1.11
- # Ubuntu: GNU gold (GNU Binutils for Ubuntu 2.22) 1.11
- # Fedora: GNU gold (version 2.23.2) 1.11
- version_re = re.compile(r"^GNU [^ ]+ .* (\d+).(\d+).*?$", re.M)
- else:
- raise Exception("Unknown tool %s" % tool)
-
- pipe = subprocess.Popen(compiler, shell=True,
- stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ pipe = subprocess.Popen(
+ cmdline, shell=True,
+ stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+
+ t = threading.Timer(0.25, pipe.terminate)
+ t.start()
tool_output, tool_error = pipe.communicate()
- if pipe.returncode:
- raise subprocess.CalledProcessError(pipe.returncode, compiler)
+ t.cancel()
+ return pipe.returncode, tool_output, tool_error
+ except subprocess.CalledProcessError, e:
+ return e.returncode, e.output[0], e.output[1]
+
+
+class GetVersionError(Exception):
+ pass
+
+
+def GetVersion(compiler, tool, call=call):
+ # Note that "compiler" is the string to launch the compiler which could
+ # contains all types of weirdness like "distcc g++".
+
+ if tool == "compiler":
+ totry = [" --version"]
+ version_re = re.compile(r"(?P<major>\d+)\.(?P<minor>\d+)")
+ output_fmt = "%i%i"
+ elif tool == "assembler":
+ totry = [
+ "-Xassembler -version -x assembler -c /dev/null",
+ # Mac's need just -v
+ "-Xassembler -v -x assembler -c /dev/null",
+ ]
+
+ # With clang we have to pass -no-integrated-as or -fno-integrated-as for
+ # the system assembler.
+ for args in list(totry):
+ totry.append("-no-integrated-as " + args)
+ totry.append("-fno-integrated-as " + args)
+
+ version_re = re.compile(
+ r"^.* assembler[ )].* (?P<major>\d+).(?P<minor>\d+).*?$",
+ re.M)
+ output_fmt = "%i%02i"
+ elif tool == "linker":
+ totry = ["-Xlinker -version"]
+ version_re = re.compile(
+ r"^.*[ :(-](ld|gold)[ )].* (?P<major>\d+).(?P<minor>\d+)(\.\d+)?$",
+ re.M)
+ output_fmt = "%i%02i"
+ else:
+ raise ValueError("Unknown tool %s" % tool)
+
+ errors = []
+ for arguments in totry:
+ cmdline = "%s %s" % (compiler, arguments)
+
+ retcode, tool_output, tool_error = call(cmdline)
- result = version_re.match(tool_output)
- return result.group(1) + result.group(2)
- except Exception, e:
- if tool_error:
- sys.stderr.write(tool_error)
- print >> sys.stderr, "compiler_version.py failed to execute:", compiler
- print >> sys.stderr, e
- return ""
+ result = version_re.search(tool_output)
+ if not result:
+ errors.append((retcode, cmdline, tool_output, tool_error))
+ continue
+
+ return output_fmt % (
+ int(result.group('major')), int(result.group('minor')))
+
+ error_output = """\
+compiler_version.py was unable to execute requested tool. Error output follows
+
+"""
+ for retcode, cmdline, stdout, stderr in errors:
+ error_output += """\
+compiler_version.py tried to execute: %s
+Command returned %s
+
+stdout output was
+--------------------------------------------------------------------------
+%s
+--------------------------------------------------------------------------
+stderr output was
+--------------------------------------------------------------------------
+%s
+==========================================================================
+""" % (cmdline, retcode, stdout, stderr)
+ raise GetVersionError(error_output)
+
+
+def FindCompiler(env):
+ cxx = env.get("CXX", None)
+ flags = env.get("CXXFLAGS", None)
+
+ if not cxx:
+ cxx = "c++"
+
+ if flags:
+ flags = " "+flags
+ else:
+ flags = ""
+
+ return cxx+flags
def main(args):
@@ -66,22 +130,9 @@ def main(args):
elif len(args) > 1:
print "Unknown arguments!"
- # Check if CXX environment variable exists and
- # if it does use that compiler.
- cxx = os.getenv("CXX", None)
- if cxx:
- cxxversion = GetVersion(cxx, tool)
- if cxxversion != "":
- print cxxversion
- return 0
- else:
- # Otherwise we check the g++ version.
- gccversion = GetVersion("g++", tool)
- if gccversion != "":
- print gccversion
- return 0
-
- return 1
+ cxxversion = GetVersion(FindCompiler(os.environ), tool)
+ print cxxversion
+ return 0
if __name__ == "__main__":
« 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