Scons - add compiler requirements
This commit is contained in:
68
SConstruct
68
SConstruct
@ -469,6 +469,74 @@ if selected_platform in platform_list:
|
|||||||
if env["lto"] != "none":
|
if env["lto"] != "none":
|
||||||
print("Using LTO: " + env["lto"])
|
print("Using LTO: " + env["lto"])
|
||||||
|
|
||||||
|
# Enforce our minimal compiler version requirements
|
||||||
|
cc_version = methods.get_compiler_version_ex(env)
|
||||||
|
cc_version_major = cc_version["major"]
|
||||||
|
cc_version_minor = cc_version["minor"]
|
||||||
|
cc_version_metadata1 = cc_version["metadata1"]
|
||||||
|
|
||||||
|
if cc_version_major == -1:
|
||||||
|
print_warning(
|
||||||
|
"Couldn't detect compiler version, skipping version checks. "
|
||||||
|
"Build may fail if the compiler doesn't support C++17 fully."
|
||||||
|
)
|
||||||
|
elif methods.using_gcc(env):
|
||||||
|
if cc_version_major < 9:
|
||||||
|
print_error(
|
||||||
|
"Detected GCC version older than 9, which does not fully support "
|
||||||
|
"C++17, or has bugs when compiling Godot. Supported versions are 9 "
|
||||||
|
"and later. Use a newer GCC version, or Clang 6 or later by passing "
|
||||||
|
'"use_llvm=yes" to the SCons command line.'
|
||||||
|
)
|
||||||
|
Exit(255)
|
||||||
|
elif cc_version_metadata1 == "win32":
|
||||||
|
print_error(
|
||||||
|
"Detected mingw version is not using posix threads. Only posix "
|
||||||
|
"version of mingw is supported. "
|
||||||
|
'Use "update-alternatives --config x86_64-w64-mingw32-g++" '
|
||||||
|
"to switch to posix threads."
|
||||||
|
)
|
||||||
|
Exit(255)
|
||||||
|
elif methods.using_clang(env):
|
||||||
|
# Apple LLVM versions differ from upstream LLVM version \o/, compare
|
||||||
|
# in https://en.wikipedia.org/wiki/Xcode#Toolchain_versions
|
||||||
|
if methods.is_apple_clang(env):
|
||||||
|
if cc_version_major < 10:
|
||||||
|
print_error(
|
||||||
|
"Detected Apple Clang version older than 10, which does not fully "
|
||||||
|
"support C++17. Supported versions are Apple Clang 10 and later."
|
||||||
|
)
|
||||||
|
Exit(255)
|
||||||
|
else:
|
||||||
|
if cc_version_major < 6:
|
||||||
|
print_error(
|
||||||
|
"Detected Clang version older than 6, which does not fully support "
|
||||||
|
"C++17. Supported versions are Clang 6 and later."
|
||||||
|
)
|
||||||
|
Exit(255)
|
||||||
|
|
||||||
|
elif env.msvc:
|
||||||
|
# Ensure latest minor builds of Visual Studio 2017/2019.
|
||||||
|
# https://github.com/godotengine/godot/pull/94995#issuecomment-2336464574
|
||||||
|
if cc_version_major == 16 and cc_version_minor < 11:
|
||||||
|
print_error(
|
||||||
|
"Detected Visual Studio 2019 version older than 16.11, which has bugs "
|
||||||
|
"when compiling Godot. Use a newer VS2019 version, or VS2022."
|
||||||
|
)
|
||||||
|
Exit(255)
|
||||||
|
if cc_version_major == 15 and cc_version_minor < 9:
|
||||||
|
print_error(
|
||||||
|
"Detected Visual Studio 2017 version older than 15.9, which has bugs "
|
||||||
|
"when compiling Godot. Use a newer VS2017 version, or VS2019/VS2022."
|
||||||
|
)
|
||||||
|
Exit(255)
|
||||||
|
if cc_version_major < 15:
|
||||||
|
print_error(
|
||||||
|
"Detected Visual Studio 2015 or earlier, which is unsupported in Godot. "
|
||||||
|
"Supported versions are Visual Studio 2017 and later."
|
||||||
|
)
|
||||||
|
Exit(255)
|
||||||
|
|
||||||
# Set our C and C++ standard requirements.
|
# Set our C and C++ standard requirements.
|
||||||
# Prepending to make it possible to override
|
# Prepending to make it possible to override
|
||||||
# This needs to come after `configure`, otherwise we don't have env.msvc.
|
# This needs to come after `configure`, otherwise we don't have env.msvc.
|
||||||
|
|||||||
139
methods.py
139
methods.py
@ -19,6 +19,9 @@ from os.path import normpath, basename
|
|||||||
# Get the "Godot" folder name ahead of time
|
# Get the "Godot" folder name ahead of time
|
||||||
base_folder_path = str(os.path.abspath(Path(__file__).parent)) + "/"
|
base_folder_path = str(os.path.abspath(Path(__file__).parent)) + "/"
|
||||||
base_folder_only = os.path.basename(os.path.normpath(base_folder_path))
|
base_folder_only = os.path.basename(os.path.normpath(base_folder_path))
|
||||||
|
|
||||||
|
compiler_version_cache = None
|
||||||
|
|
||||||
# Listing all the folders we have converted
|
# Listing all the folders we have converted
|
||||||
# for SCU in scu_builders.py
|
# for SCU in scu_builders.py
|
||||||
_scu_folders = set()
|
_scu_folders = set()
|
||||||
@ -1068,6 +1071,21 @@ def detect_darwin_sdk_path(platform, env):
|
|||||||
raise
|
raise
|
||||||
|
|
||||||
|
|
||||||
|
def is_apple_clang(env):
|
||||||
|
import shlex
|
||||||
|
|
||||||
|
if env["platform"] not in ["macos", "ios"]:
|
||||||
|
return False
|
||||||
|
if not using_clang(env):
|
||||||
|
return False
|
||||||
|
try:
|
||||||
|
version = subprocess.check_output(shlex.split(env.subst(env["CXX"])) + ["--version"]).strip().decode("utf-8")
|
||||||
|
except (subprocess.CalledProcessError, OSError):
|
||||||
|
print_warning("Couldn't parse CXX environment variable to infer compiler version.")
|
||||||
|
return False
|
||||||
|
return version.startswith("Apple")
|
||||||
|
|
||||||
|
|
||||||
def get_compiler_version(env):
|
def get_compiler_version(env):
|
||||||
"""
|
"""
|
||||||
Returns an array of version numbers as ints: [major, minor, patch].
|
Returns an array of version numbers as ints: [major, minor, patch].
|
||||||
@ -1090,6 +1108,127 @@ def get_compiler_version(env):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def get_compiler_version_ex(env):
|
||||||
|
"""
|
||||||
|
Returns a dictionary with various version information:
|
||||||
|
|
||||||
|
- major, minor, patch: Version following semantic versioning system
|
||||||
|
- metadata1, metadata2: Extra information
|
||||||
|
- date: Date of the build
|
||||||
|
"""
|
||||||
|
|
||||||
|
global compiler_version_cache
|
||||||
|
if compiler_version_cache is not None:
|
||||||
|
return compiler_version_cache
|
||||||
|
|
||||||
|
import shlex
|
||||||
|
|
||||||
|
ret = {
|
||||||
|
"major": -1,
|
||||||
|
"minor": -1,
|
||||||
|
"patch": -1,
|
||||||
|
"metadata1": "",
|
||||||
|
"metadata2": "",
|
||||||
|
"date": "",
|
||||||
|
"apple_major": -1,
|
||||||
|
"apple_minor": -1,
|
||||||
|
"apple_patch1": -1,
|
||||||
|
"apple_patch2": -1,
|
||||||
|
"apple_patch3": -1,
|
||||||
|
}
|
||||||
|
|
||||||
|
if env.msvc and not using_clang(env):
|
||||||
|
try:
|
||||||
|
# FIXME: `-latest` works for most cases, but there are edge-cases where this would
|
||||||
|
# benefit from a more nuanced search.
|
||||||
|
# https://github.com/godotengine/godot/pull/91069#issuecomment-2358956731
|
||||||
|
# https://github.com/godotengine/godot/pull/91069#issuecomment-2380836341
|
||||||
|
args = [
|
||||||
|
env["VSWHERE"],
|
||||||
|
"-latest",
|
||||||
|
"-prerelease",
|
||||||
|
"-products",
|
||||||
|
"*",
|
||||||
|
"-requires",
|
||||||
|
"Microsoft.Component.MSBuild",
|
||||||
|
"-utf8",
|
||||||
|
]
|
||||||
|
version = subprocess.check_output(args, encoding="utf-8").strip()
|
||||||
|
for line in version.splitlines():
|
||||||
|
split = line.split(":", 1)
|
||||||
|
if split[0] == "catalog_productDisplayVersion":
|
||||||
|
sem_ver = split[1].split(".")
|
||||||
|
ret["major"] = int(sem_ver[0])
|
||||||
|
ret["minor"] = int(sem_ver[1])
|
||||||
|
ret["patch"] = int(sem_ver[2].split()[0])
|
||||||
|
# Could potentially add section for determining preview version, but
|
||||||
|
# that can wait until metadata is actually used for something.
|
||||||
|
if split[0] == "catalog_buildVersion":
|
||||||
|
ret["metadata1"] = split[1]
|
||||||
|
except (subprocess.CalledProcessError, OSError):
|
||||||
|
print_warning("Couldn't find vswhere to determine compiler version.")
|
||||||
|
return update_compiler_version_cache(ret)
|
||||||
|
|
||||||
|
# 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(
|
||||||
|
shlex.split(env.subst(env["CXX"]), posix=False) + ["--version"], shell=(os.name == "nt"), encoding="utf-8"
|
||||||
|
).strip()
|
||||||
|
except (subprocess.CalledProcessError, OSError):
|
||||||
|
print_warning("Couldn't parse CXX environment variable to infer compiler version.")
|
||||||
|
return update_compiler_version_cache(ret)
|
||||||
|
|
||||||
|
match = re.search(
|
||||||
|
r"(?:(?<=version )|(?<=\) )|(?<=^))"
|
||||||
|
r"(?P<major>\d+)"
|
||||||
|
r"(?:\.(?P<minor>\d*))?"
|
||||||
|
r"(?:\.(?P<patch>\d*))?"
|
||||||
|
r"(?:-(?P<metadata1>[0-9a-zA-Z-]*))?"
|
||||||
|
r"(?:\+(?P<metadata2>[0-9a-zA-Z-]*))?"
|
||||||
|
r"(?: (?P<date>[0-9]{8}|[0-9]{6})(?![0-9a-zA-Z]))?",
|
||||||
|
version,
|
||||||
|
)
|
||||||
|
if match is not None:
|
||||||
|
for key, value in match.groupdict().items():
|
||||||
|
if value is not None:
|
||||||
|
ret[key] = value
|
||||||
|
|
||||||
|
match_apple = re.search(
|
||||||
|
r"(?:(?<=clang-)|(?<=\) )|(?<=^))"
|
||||||
|
r"(?P<apple_major>\d+)"
|
||||||
|
r"(?:\.(?P<apple_minor>\d*))?"
|
||||||
|
r"(?:\.(?P<apple_patch1>\d*))?"
|
||||||
|
r"(?:\.(?P<apple_patch2>\d*))?"
|
||||||
|
r"(?:\.(?P<apple_patch3>\d*))?",
|
||||||
|
version,
|
||||||
|
)
|
||||||
|
if match_apple is not None:
|
||||||
|
for key, value in match_apple.groupdict().items():
|
||||||
|
if value is not None:
|
||||||
|
ret[key] = value
|
||||||
|
|
||||||
|
# Transform semantic versioning to integers
|
||||||
|
for key in [
|
||||||
|
"major",
|
||||||
|
"minor",
|
||||||
|
"patch",
|
||||||
|
"apple_major",
|
||||||
|
"apple_minor",
|
||||||
|
"apple_patch1",
|
||||||
|
"apple_patch2",
|
||||||
|
"apple_patch3",
|
||||||
|
]:
|
||||||
|
ret[key] = int(ret[key] or -1)
|
||||||
|
return update_compiler_version_cache(ret)
|
||||||
|
|
||||||
|
|
||||||
|
def update_compiler_version_cache(value):
|
||||||
|
global compiler_version_cache
|
||||||
|
compiler_version_cache = value
|
||||||
|
return value
|
||||||
|
|
||||||
|
|
||||||
def is_vanilla_clang(env):
|
def is_vanilla_clang(env):
|
||||||
if not using_clang(env):
|
if not using_clang(env):
|
||||||
return False
|
return False
|
||||||
|
|||||||
Reference in New Issue
Block a user