Jelajahi Sumber

Merge pull request #53376 from ganondev/vsproj-props-for-mono

Rémi Verschelde 4 tahun lalu
induk
melakukan
1136d531b1
1 mengubah file dengan 127 tambahan dan 49 penghapusan
  1. 127 49
      methods.py

+ 127 - 49
methods.py

@@ -1,8 +1,10 @@
+import collections
 import os
 import re
 import glob
 import subprocess
 from collections import OrderedDict
+from typing import Iterator
 
 # We need to define our own `Action` method to control the verbosity of output
 # and whenever we need to run those commands in a subprocess on some platforms.
@@ -604,7 +606,11 @@ def detect_visual_c_compiler_version(tools_env):
 
 
 def find_visual_c_batch_file(env):
-    from SCons.Tool.MSCommon.vc import get_default_version, get_host_target, find_batch_file
+    from SCons.Tool.MSCommon.vc import (
+        get_default_version,
+        get_host_target,
+        find_batch_file,
+    )
 
     version = get_default_version(env)
     (host_platform, target_platform, _) = get_host_target(env)
@@ -656,36 +662,107 @@ def generate_vs_project(env, num_jobs):
     batch_file = find_visual_c_batch_file(env)
     if batch_file:
 
-        def build_commandline(commands):
-            common_build_prefix = [
-                'cmd /V /C set "plat=$(PlatformTarget)"',
-                '(if "$(PlatformTarget)"=="x64" (set "plat=x86_amd64"))',
-                'set "tools=%s"' % env["tools"],
-                '(if "$(Configuration)"=="release" (set "tools=no"))',
-                'call "' + batch_file + '" !plat!',
-            ]
-
-            # Windows allows us to have spaces in paths, so we need
-            # to double quote off the directory. However, the path ends
-            # in a backslash, so we need to remove this, lest it escape the
-            # last double quote off, confusing MSBuild
-            common_build_postfix = [
-                "--directory=\"$(ProjectDir.TrimEnd('\\'))\"",
-                "platform=windows",
-                "target=$(Configuration)",
-                "progress=no",
-                "tools=!tools!",
-                "-j%s" % num_jobs,
-            ]
-
-            if env["tests"]:
-                common_build_postfix.append("tests=yes")
-
-            if env["custom_modules"]:
-                common_build_postfix.append("custom_modules=%s" % env["custom_modules"])
-
-            result = " ^& ".join(common_build_prefix + [" ".join([commands] + common_build_postfix)])
-            return result
+        class ModuleConfigs(collections.Mapping):
+            # This version information (Win32, x64, Debug, Release, Release_Debug seems to be
+            # required for Visual Studio to understand that it needs to generate an NMAKE
+            # project. Do not modify without knowing what you are doing.
+            PLATFORMS = ["Win32", "x64"]
+            PLATFORM_IDS = ["32", "64"]
+            CONFIGURATIONS = ["debug", "release", "release_debug"]
+            CONFIGURATION_IDS = ["tools", "opt", "opt.tools"]
+
+            @staticmethod
+            def for_every_variant(value):
+                return [value for _ in range(len(ModuleConfigs.CONFIGURATIONS) * len(ModuleConfigs.PLATFORMS))]
+
+            def __init__(self):
+
+                shared_targets_array = []
+                self.names = []
+                self.arg_dict = {
+                    "variant": [],
+                    "runfile": shared_targets_array,
+                    "buildtarget": shared_targets_array,
+                    "cpppaths": [],
+                    "cppdefines": [],
+                    "cmdargs": [],
+                }
+                self.add_mode()  # default
+
+            def add_mode(
+                self,
+                name: str = "",
+                includes: str = "",
+                cli_args: str = "",
+                defines=None,
+            ):
+                if defines is None:
+                    defines = []
+                self.names.append(name)
+                self.arg_dict["variant"] += [
+                    f'{config}{f"_[{name}]" if name else ""}|{platform}'
+                    for config in ModuleConfigs.CONFIGURATIONS
+                    for platform in ModuleConfigs.PLATFORMS
+                ]
+                self.arg_dict["runfile"] += [
+                    f'bin\\godot.windows.{config_id}.{plat_id}{f".{name}" if name else ""}.exe'
+                    for config_id in ModuleConfigs.CONFIGURATION_IDS
+                    for plat_id in ModuleConfigs.PLATFORM_IDS
+                ]
+                self.arg_dict["cpppaths"] += ModuleConfigs.for_every_variant(env["CPPPATH"] + [includes])
+                self.arg_dict["cppdefines"] += ModuleConfigs.for_every_variant(env["CPPDEFINES"] + defines)
+                self.arg_dict["cmdargs"] += ModuleConfigs.for_every_variant(cli_args)
+
+            def build_commandline(self, commands):
+
+                configuration_getter = (
+                    "$(Configuration"
+                    + "".join([f'.Replace("{name}", "")' for name in self.names[1:]])
+                    + '.Replace("_[]", "")'
+                    + ")"
+                )
+
+                common_build_prefix = [
+                    'cmd /V /C set "plat=$(PlatformTarget)"',
+                    '(if "$(PlatformTarget)"=="x64" (set "plat=x86_amd64"))',
+                    'set "tools=%s"' % env["tools"],
+                    f'(if "{configuration_getter}"=="release" (set "tools=no"))',
+                    'call "' + batch_file + '" !plat!',
+                ]
+
+                # Windows allows us to have spaces in paths, so we need
+                # to double quote off the directory. However, the path ends
+                # in a backslash, so we need to remove this, lest it escape the
+                # last double quote off, confusing MSBuild
+                common_build_postfix = [
+                    "--directory=\"$(ProjectDir.TrimEnd('\\'))\"",
+                    "platform=windows",
+                    f"target={configuration_getter}",
+                    "progress=no",
+                    "tools=!tools!",
+                    "-j%s" % num_jobs,
+                ]
+
+                if env["tests"]:
+                    common_build_postfix.append("tests=yes")
+
+                if env["custom_modules"]:
+                    common_build_postfix.append("custom_modules=%s" % env["custom_modules"])
+
+                result = " ^& ".join(common_build_prefix + [" ".join([commands] + common_build_postfix)])
+                return result
+
+            # Mappings interface definitions
+
+            def __iter__(self) -> Iterator[str]:
+                for x in self.arg_dict:
+                    yield x
+
+            def __len__(self) -> int:
+                return len(self.names)
+
+            def __getitem__(self, k: str):
+                return self.arg_dict[k]
 
         add_to_vs_project(env, env.core_sources)
         add_to_vs_project(env, env.drivers_sources)
@@ -700,21 +777,24 @@ def generate_vs_project(env, num_jobs):
         for header in glob_recursive("**/*.h"):
             env.vs_incs.append(str(header))
 
-        env["MSVSBUILDCOM"] = build_commandline("scons")
-        env["MSVSREBUILDCOM"] = build_commandline("scons vsproj=yes")
-        env["MSVSCLEANCOM"] = build_commandline("scons --clean")
-
-        # This version information (Win32, x64, Debug, Release, Release_Debug seems to be
-        # required for Visual Studio to understand that it needs to generate an NMAKE
-        # project. Do not modify without knowing what you are doing.
-        debug_variants = ["debug|Win32"] + ["debug|x64"]
-        release_variants = ["release|Win32"] + ["release|x64"]
-        release_debug_variants = ["release_debug|Win32"] + ["release_debug|x64"]
-        variants = debug_variants + release_variants + release_debug_variants
-        debug_targets = ["bin\\godot.windows.tools.32.exe"] + ["bin\\godot.windows.tools.64.exe"]
-        release_targets = ["bin\\godot.windows.opt.32.exe"] + ["bin\\godot.windows.opt.64.exe"]
-        release_debug_targets = ["bin\\godot.windows.opt.tools.32.exe"] + ["bin\\godot.windows.opt.tools.64.exe"]
-        targets = debug_targets + release_targets + release_debug_targets
+        module_configs = ModuleConfigs()
+        import modules.mono.build_scripts.mono_reg_utils as mono_reg
+
+        if env.get("module_mono_enabled"):
+            mono_root = env.get("mono_prefix") or mono_reg.find_mono_root_dir(env["bits"])
+            if mono_root:
+                module_configs.add_mode(
+                    "mono",
+                    includes=os.path.join(mono_root, "include", "mono-2.0"),
+                    cli_args="module_mono_enabled=yes mono_glue=yes",
+                    defines=[("MONO_GLUE_ENABLED",)],
+                )
+            else:
+                print("Mono installation directory not found. Generated project will not have build variants for Mono.")
+
+        env["MSVSBUILDCOM"] = module_configs.build_commandline("scons")
+        env["MSVSREBUILDCOM"] = module_configs.build_commandline("scons vsproj=yes")
+        env["MSVSCLEANCOM"] = module_configs.build_commandline("scons --clean")
         if not env.get("MSVS"):
             env["MSVS"]["PROJECTSUFFIX"] = ".vcxproj"
             env["MSVS"]["SOLUTIONSUFFIX"] = ".sln"
@@ -722,10 +802,8 @@ def generate_vs_project(env, num_jobs):
             target=["#godot" + env["MSVSPROJECTSUFFIX"]],
             incs=env.vs_incs,
             srcs=env.vs_srcs,
-            runfile=targets,
-            buildtarget=targets,
             auto_build_solution=1,
-            variant=variants,
+            **module_configs,
         )
     else:
         print("Could not locate Visual Studio batch file to set up the build environment. Not generating VS project.")