diff --git a/methods.py b/methods.py index d2f4e38be23..9477639f93b 100644 --- a/methods.py +++ b/methods.py @@ -553,7 +553,7 @@ def glob_recursive(pattern, node="."): def precious_program(env, program, sources, **args): - program = env.ProgramOriginal(program, sources, **args) + program = env.Program(program, sources, **args) env.Precious(program) return program diff --git a/platform/windows/detect.py b/platform/windows/detect.py index bbdcb9e79aa..b008a897261 100644 --- a/platform/windows/detect.py +++ b/platform/windows/detect.py @@ -47,14 +47,6 @@ def try_cmd(test, prefix, arch, check_clang=False): def can_build(): if os.name == "nt": # Building natively on Windows - # If VCINSTALLDIR is set in the OS environ, use traditional Godot logic to set up MSVC - if os.getenv("VCINSTALLDIR"): # MSVC, manual setup - return True - - # Otherwise, let SCons find MSVC if installed, or else MinGW. - # Since we're just returning True here, if there's no compiler - # installed, we'll get errors when it tries to build with the - # null compiler. return True if os.name == "posix": @@ -156,10 +148,13 @@ def detect_build_env_arch(): def get_tools(env: "SConsEnvironment"): - if os.name != "nt" or env["use_mingw"]: + if os.name != "nt" or env.get("use_mingw"): return ["mingw"] else: - return ["default"] + msvc_arch_aliases = {"x86_32": "x86", "arm32": "arm"} + env["TARGET_ARCH"] = msvc_arch_aliases.get(env["arch"], env["arch"]) + env["MSVC_VERSION"] = env["MSVS_VERSION"] = env.get("msvc_version") + return ["msvc", "mslink", "mslib"] def get_opts(): @@ -194,11 +189,7 @@ def get_opts(): "0x0601", ), EnumVariable("windows_subsystem", "Windows subsystem", "gui", ("gui", "console")), - ( - "msvc_version", - "MSVC version to use. Ignored if VCINSTALLDIR is set in shell env.", - None, - ), + ("msvc_version", "MSVC version to use. Handled automatically by SCons if omitted.", ""), BoolVariable("use_mingw", "Use the Mingw compiler, even if MSVC is installed.", False), BoolVariable("use_llvm", "Use the LLVM compiler", False), BoolVariable("use_static_cpp", "Link MinGW/MSVC C++ runtime libraries statically", True), @@ -252,91 +243,7 @@ def get_flags(): } -def setup_msvc_manual(env: "SConsEnvironment"): - """Running from VCVARS environment""" - - env_arch = detect_build_env_arch() - if env["arch"] != env_arch: - print_error( - "Arch argument (%s) is not matching Native/Cross Compile Tools Prompt/Developer Console (or Visual Studio settings) that is being used to run SCons (%s).\n" - "Run SCons again without arch argument (example: scons p=windows) and SCons will attempt to detect what MSVC compiler will be executed and inform you." - % (env["arch"], env_arch) - ) - sys.exit(255) - - print("Using VCVARS-determined MSVC, arch %s" % (env_arch)) - - -def setup_msvc_auto(env: "SConsEnvironment"): - """Set up MSVC using SCons's auto-detection logic""" - - # If MSVC_VERSION is set by SCons, we know MSVC is installed. - # But we may want a different version or target arch. - - # Valid architectures for MSVC's TARGET_ARCH: - # ['amd64', 'emt64', 'i386', 'i486', 'i586', 'i686', 'ia64', 'itanium', 'x86', 'x86_64', 'arm', 'arm64', 'aarch64'] - # Our x86_64 and arm64 are the same, and we need to map the 32-bit - # architectures to other names since MSVC isn't as explicit. - # The rest we don't need to worry about because they are - # aliases or aren't supported by Godot (itanium & ia64). - msvc_arch_aliases = {"x86_32": "x86", "arm32": "arm"} - if env["arch"] in msvc_arch_aliases.keys(): - env["TARGET_ARCH"] = msvc_arch_aliases[env["arch"]] - else: - env["TARGET_ARCH"] = env["arch"] - - # The env may have already been set up with default MSVC tools, so - # reset a few things so we can set it up with the tools we want. - # (Ideally we'd decide on the tool config before configuring any - # environment, and just set the env up once, but this function runs - # on an existing env so this is the simplest way.) - env["MSVC_SETUP_RUN"] = False # Need to set this to re-run the tool - env["MSVS_VERSION"] = None - env["MSVC_VERSION"] = None - - if "msvc_version" in env: - env["MSVC_VERSION"] = env["msvc_version"] - env.Tool("msvc") - env.Tool("mssdk") # we want the MS SDK - - # Re-add potentially overwritten flags. - env.AppendUnique(CCFLAGS=env.get("ccflags", "").split()) - env.AppendUnique(CXXFLAGS=env.get("cxxflags", "").split()) - env.AppendUnique(CFLAGS=env.get("cflags", "").split()) - env.AppendUnique(RCFLAGS=env.get("rcflags", "").split()) - - # Note: actual compiler version can be found in env['MSVC_VERSION'], e.g. "14.1" for VS2015 - print("Using SCons-detected MSVC version %s, arch %s" % (env["MSVC_VERSION"], env["arch"])) - - -def setup_mingw(env: "SConsEnvironment"): - """Set up env for use with mingw""" - - env_arch = detect_build_env_arch() - if os.getenv("MSYSTEM") == "MSYS": - print_error( - "Running from base MSYS2 console/environment, use target specific environment instead (e.g., mingw32, mingw64, clang32, clang64)." - ) - sys.exit(255) - - if env_arch != "" and env["arch"] != env_arch: - print_error( - "Arch argument (%s) is not matching MSYS2 console/environment that is being used to run SCons (%s).\n" - "Run SCons again without arch argument (example: scons p=windows) and SCons will attempt to detect what MSYS2 compiler will be executed and inform you." - % (env["arch"], env_arch) - ) - sys.exit(255) - - if not try_cmd("gcc --version", env["mingw_prefix"], env["arch"]) and not try_cmd( - "clang --version", env["mingw_prefix"], env["arch"] - ): - print_error("No valid compilers found, use MINGW_PREFIX environment variable to set MinGW path.") - sys.exit(255) - - print("Using MinGW, arch %s" % (env["arch"])) - - -def configure_msvc(env: "SConsEnvironment", vcvars_msvc_config): +def configure_msvc(env: "SConsEnvironment"): """Configure env to work with MSVC""" ## Build type @@ -454,12 +361,6 @@ def configure_msvc(env: "SConsEnvironment", vcvars_msvc_config): # for notes on why this shouldn't be enabled for gcc env.AppendUnique(CCFLAGS=["/bigobj"]) - if vcvars_msvc_config: # should be automatic if SCons found it - if os.getenv("WindowsSdkDir") is not None: - env.Prepend(CPPPATH=[str(os.getenv("WindowsSdkDir")) + "/Include"]) - else: - print_warning("Missing environment variable: WindowsSdkDir") - validate_win_version(env) env.AppendUnique( @@ -568,12 +469,6 @@ def configure_msvc(env: "SConsEnvironment", vcvars_msvc_config): env.Append(LINKFLAGS=[p + env["LIBSUFFIX"] for p in LIBS]) - if vcvars_msvc_config: - if os.getenv("WindowsSdkDir") is not None: - env.Append(LIBPATH=[str(os.getenv("WindowsSdkDir")) + "/Lib"]) - else: - print_warning("Missing environment variable: WindowsSdkDir") - ## LTO if env["lto"] == "auto": # No LTO by default for MSVC, doesn't help. @@ -596,14 +491,6 @@ def configure_msvc(env: "SConsEnvironment", vcvars_msvc_config): env.AppendUnique(LINKFLAGS=["/LTCG"]) env.AppendUnique(ARFLAGS=["/LTCG"]) - if vcvars_msvc_config: - env.Prepend(CPPPATH=[p for p in str(os.getenv("INCLUDE")).split(";")]) - env.Append(LIBPATH=[p for p in str(os.getenv("LIB")).split(";")]) - - # Incremental linking fix - env["BUILDERS"]["ProgramOriginal"] = env["BUILDERS"]["Program"] - env["BUILDERS"]["Program"] = methods.precious_program - env.Append(LINKFLAGS=["/NATVIS:platform\\windows\\godot.natvis"]) if env["use_asan"]: @@ -679,6 +566,25 @@ def tempfile_arg_esc_func(arg): def configure_mingw(env: "SConsEnvironment"): + if os.getenv("MSYSTEM") == "MSYS": + print_error( + "Running from base MSYS2 console/environment, use target specific environment instead (e.g., mingw32, mingw64, clang32, clang64)." + ) + sys.exit(255) + + if (env_arch := detect_build_env_arch()) and env["arch"] != env_arch: + print_error( + f"Arch argument ({env['arch']}) is not matching MSYS2 console/environment that is being used to run SCons ({env_arch}).\n" + "Run SCons again without arch argument (example: scons p=windows) and SCons will attempt to detect what MSYS2 compiler will be executed and inform you." + ) + sys.exit(255) + + if not try_cmd("gcc --version", env["mingw_prefix"], env["arch"]) and not try_cmd( + "clang --version", env["mingw_prefix"], env["arch"] + ): + print_error("No valid compilers found, use MINGW_PREFIX environment variable to set MinGW path.") + sys.exit(255) + # Workaround for MinGW. See: # https://www.scons.org/wiki/LongCmdLinesOnWin32 env.use_windows_spawn_fix() @@ -913,28 +819,10 @@ def configure(env: "SConsEnvironment"): # At this point the env has been set up with basic tools/compilers. env.Prepend(CPPPATH=["#platform/windows"]) - if os.name == "nt": - env["ENV"] = os.environ # this makes build less repeatable, but simplifies some things - env["ENV"]["TMP"] = os.environ["TMP"] - - # First figure out which compiler, version, and target arch we're using - if os.getenv("VCINSTALLDIR") and detect_build_env_arch() and not env["use_mingw"]: - setup_msvc_manual(env) - env.msvc = True - vcvars_msvc_config = True - elif env.get("MSVC_VERSION", "") and not env["use_mingw"]: - setup_msvc_auto(env) - env.msvc = True - vcvars_msvc_config = False - else: - setup_mingw(env) - env.msvc = False - - # Now set compiler/linker flags + env.msvc = "mingw" not in env["TOOLS"] if env.msvc: - configure_msvc(env, vcvars_msvc_config) - - else: # MinGW + configure_msvc(env) + else: configure_mingw(env)