Skip to content

Commit

Permalink
Variants and targets are generated instead of manually defined. The s…
Browse files Browse the repository at this point in the history
…pecific details for each configuration are logically separated from the generators

Add support for specifying defines for each configuration

Add support for specifying extra cli args for each configuration

Add support for specifying extra includes for each configuration
  • Loading branch information
ganondev committed Oct 6, 2021
1 parent 66ab3ce commit 4c2f0a5
Showing 1 changed file with 127 additions and 49 deletions.
176 changes: 127 additions & 49 deletions methods.py
Original file line number Diff line number Diff line change
@@ -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.
Expand Down Expand Up @@ -601,7 +603,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)
Expand Down Expand Up @@ -653,36 +659,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)
Expand All @@ -697,32 +774,33 @@ def build_commandline(commands):
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"
env.MSVSProject(
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.")
Expand Down

0 comments on commit 4c2f0a5

Please sign in to comment.