From 5bb54d3184cf8fd779017a8f7f94dcf89c43aceb Mon Sep 17 00:00:00 2001 From: Mario Liebisch Date: Mon, 25 Sep 2023 21:08:36 +0200 Subject: [PATCH] Updated compiler version detection This fixes multiple issues/inconsistencies around `get_compiler_version()`: * With no shell allocated, launching the compiler could fail even with proper paths being set. * The return value was described as "an array of version numbers as ints", but the function actually returned a `Dictionary` (or `None`). * Not all calls were properly handling a `None` return value in case of errors. On Windows this broke compiling for me since #81869 with default settings. * Some calls defined inconsistent defaults/fallbacks (`0` or `-1`). (cherry picked from commit 426e18fd37f0eedf4cbb39f3dad4e8fad39ebebb) --- methods.py | 35 ++++++++++++++++++++++++++--------- platform/linuxbsd/detect.py | 2 +- platform/macos/detect.py | 13 +++---------- platform/web/detect.py | 2 +- 4 files changed, 31 insertions(+), 21 deletions(-) diff --git a/methods.py b/methods.py index 7067c219461..e18b19b991a 100644 --- a/methods.py +++ b/methods.py @@ -1002,19 +1002,32 @@ def is_vanilla_clang(env): def get_compiler_version(env): """ - Returns an array of version numbers as ints: [major, minor, patch]. - The return array should have at least two values (major, minor). + Returns a dictionary with various version information: + + - major, minor, patch: Version following semantic versioning system + - metadata1, metadata2: Extra information + - date: Date of the build """ + ret = { + "major": -1, + "minor": -1, + "patch": -1, + "metadata1": None, + "metadata2": None, + "date": None, + } + if not env.msvc: # Not using -dumpversion as some GCC distros only return major, and # Clang used to return hardcoded 4.2.1: # https://reviews.llvm.org/D56803 try: - version = subprocess.check_output([env.subst(env["CXX"]), "--version"]).strip().decode("utf-8") + version = subprocess.check_output([env.subst(env["CXX"]), "--version"], shell=True).strip().decode("utf-8") except (subprocess.CalledProcessError, OSError): print("Couldn't parse CXX environment variable to infer compiler version.") - return None - else: # TODO: Implement for MSVC - return None + return ret + else: + # TODO: Implement for MSVC + return ret match = re.search( r"(?:(?<=version )|(?<=\) )|(?<=^))" r"(?P\d+)" @@ -1026,9 +1039,13 @@ def get_compiler_version(env): version, ) if match is not None: - return match.groupdict() - else: - return None + for key, value in match.groupdict().items(): + if value is not None: + ret[key] = value + # Transform semantic versioning to integers + for key in ["major", "minor", "patch"]: + ret[key] = int(ret[key] or -1) + return ret def using_gcc(env): diff --git a/platform/linuxbsd/detect.py b/platform/linuxbsd/detect.py index 571d2a47d85..72bffceb1f0 100644 --- a/platform/linuxbsd/detect.py +++ b/platform/linuxbsd/detect.py @@ -106,7 +106,7 @@ def configure(env: "Environment"): print("Using linker program: " + env["linker"]) if env["linker"] == "mold" and using_gcc(env): # GCC < 12.1 doesn't support -fuse-ld=mold. cc_version = get_compiler_version(env) - cc_semver = (int(cc_version["major"]), int(cc_version["minor"])) + cc_semver = (cc_version["major"], cc_version["minor"]) if cc_semver < (12, 1): found_wrapper = False for path in ["/usr/libexec", "/usr/local/libexec", "/usr/lib", "/usr/local/lib"]: diff --git a/platform/macos/detect.py b/platform/macos/detect.py index 6abe1214070..81dda939a5c 100644 --- a/platform/macos/detect.py +++ b/platform/macos/detect.py @@ -119,16 +119,9 @@ def configure(env: "Environment"): env.Append(CCFLAGS=["-arch", "x86_64", "-mmacosx-version-min=10.13"]) env.Append(LINKFLAGS=["-arch", "x86_64", "-mmacosx-version-min=10.13"]) - cc_version = get_compiler_version(env) or { - "major": None, - "minor": None, - "patch": None, - "metadata1": None, - "metadata2": None, - "date": None, - } - cc_version_major = int(cc_version["major"] or -1) - cc_version_minor = int(cc_version["minor"] or -1) + cc_version = get_compiler_version(env) + cc_version_major = cc_version["major"] + cc_version_minor = cc_version["minor"] vanilla = is_vanilla_clang(env) # Workaround for Xcode 15 linker bug. diff --git a/platform/web/detect.py b/platform/web/detect.py index 24125dc4461..dfc11a22cb7 100644 --- a/platform/web/detect.py +++ b/platform/web/detect.py @@ -203,7 +203,7 @@ def configure(env: "Environment"): # Get version info for checks below. cc_version = get_compiler_version(env) - cc_semver = (int(cc_version["major"]), int(cc_version["minor"]), int(cc_version["patch"])) + cc_semver = (cc_version["major"], cc_version["minor"], cc_version["patch"]) if env["lto"] != "none": # Workaround https://github.com/emscripten-core/emscripten/issues/19781.