| 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__":
|
|
|