diff options
Diffstat (limited to 'modules/mono/build_scripts')
-rw-r--r-- | modules/mono/build_scripts/api_solution_build.py | 80 | ||||
-rwxr-xr-x | modules/mono/build_scripts/build_assemblies.py | 337 | ||||
-rw-r--r-- | modules/mono/build_scripts/gen_cs_glue_version.py | 20 | ||||
-rw-r--r-- | modules/mono/build_scripts/godot_net_sdk_build.py | 55 | ||||
-rw-r--r-- | modules/mono/build_scripts/godot_tools_build.py | 38 | ||||
-rw-r--r-- | modules/mono/build_scripts/make_android_mono_config.py | 55 | ||||
-rw-r--r-- | modules/mono/build_scripts/mono_android_config.xml | 28 | ||||
-rw-r--r-- | modules/mono/build_scripts/mono_configure.py | 561 | ||||
-rw-r--r-- | modules/mono/build_scripts/mono_reg_utils.py | 112 | ||||
-rw-r--r-- | modules/mono/build_scripts/solution_builder.py | 145 |
10 files changed, 345 insertions, 1086 deletions
diff --git a/modules/mono/build_scripts/api_solution_build.py b/modules/mono/build_scripts/api_solution_build.py deleted file mode 100644 index 9abac22df6..0000000000 --- a/modules/mono/build_scripts/api_solution_build.py +++ /dev/null @@ -1,80 +0,0 @@ -# Build the Godot API solution - -import os - -from SCons.Script import Dir - - -def build_api_solution(source, target, env): - # source and target elements are of type SCons.Node.FS.File, hence why we convert them to str - - module_dir = env["module_dir"] - - solution_path = os.path.join(module_dir, "glue/GodotSharp/GodotSharp.sln") - - build_config = env["solution_build_config"] - - extra_msbuild_args = ["/p:NoWarn=1591"] # Ignore missing documentation warnings - - from .solution_builder import build_solution - - build_solution(env, solution_path, build_config, extra_msbuild_args=extra_msbuild_args) - - # Copy targets - - core_src_dir = os.path.abspath(os.path.join(solution_path, os.pardir, "GodotSharp", "bin", build_config)) - editor_src_dir = os.path.abspath(os.path.join(solution_path, os.pardir, "GodotSharpEditor", "bin", build_config)) - - dst_dir = os.path.abspath(os.path.join(str(target[0]), os.pardir)) - - if not os.path.isdir(dst_dir): - assert not os.path.isfile(dst_dir) - os.makedirs(dst_dir) - - def copy_target(target_path): - from shutil import copy - - filename = os.path.basename(target_path) - - src_path = os.path.join(core_src_dir, filename) - if not os.path.isfile(src_path): - src_path = os.path.join(editor_src_dir, filename) - - copy(src_path, target_path) - - for scons_target in target: - copy_target(str(scons_target)) - - -def build(env_mono): - assert env_mono["tools"] - - target_filenames = [ - "GodotSharp.dll", - "GodotSharp.pdb", - "GodotSharp.xml", - "GodotSharpEditor.dll", - "GodotSharpEditor.pdb", - "GodotSharpEditor.xml", - ] - - depend_cmd = [] - - for build_config in ["Debug", "Release"]: - output_dir = Dir("#bin").abspath - editor_api_dir = os.path.join(output_dir, "GodotSharp", "Api", build_config) - - targets = [os.path.join(editor_api_dir, filename) for filename in target_filenames] - - cmd = env_mono.CommandNoCache( - targets, depend_cmd, build_api_solution, module_dir=os.getcwd(), solution_build_config=build_config - ) - env_mono.AlwaysBuild(cmd) - - # Make the Release build of the API solution depend on the Debug build. - # We do this in order to prevent SCons from building them in parallel, - # which can freak out MSBuild. In many cases, one of the builds would - # hang indefinitely requiring a key to be pressed for it to continue. - depend_cmd = cmd - - return depend_cmd diff --git a/modules/mono/build_scripts/build_assemblies.py b/modules/mono/build_scripts/build_assemblies.py new file mode 100755 index 0000000000..6f66ce9efa --- /dev/null +++ b/modules/mono/build_scripts/build_assemblies.py @@ -0,0 +1,337 @@ +#!/usr/bin/python3 + +import os +import os.path +import shlex +import subprocess +from dataclasses import dataclass + + +def find_dotnet_cli(): + if os.name == "nt": + for hint_dir in os.environ["PATH"].split(os.pathsep): + hint_dir = hint_dir.strip('"') + hint_path = os.path.join(hint_dir, "dotnet") + if os.path.isfile(hint_path) and os.access(hint_path, os.X_OK): + return hint_path + if os.path.isfile(hint_path + ".exe") and os.access(hint_path + ".exe", os.X_OK): + return hint_path + ".exe" + else: + for hint_dir in os.environ["PATH"].split(os.pathsep): + hint_dir = hint_dir.strip('"') + hint_path = os.path.join(hint_dir, "dotnet") + if os.path.isfile(hint_path) and os.access(hint_path, os.X_OK): + return hint_path + + +def find_msbuild_standalone_windows(): + msbuild_tools_path = find_msbuild_tools_path_reg() + + if msbuild_tools_path: + return os.path.join(msbuild_tools_path, "MSBuild.exe") + + return None + + +def find_msbuild_mono_windows(mono_prefix): + assert mono_prefix is not None + + mono_bin_dir = os.path.join(mono_prefix, "bin") + msbuild_mono = os.path.join(mono_bin_dir, "msbuild.bat") + + if os.path.isfile(msbuild_mono): + return msbuild_mono + + return None + + +def find_msbuild_mono_unix(): + import sys + + hint_dirs = [] + if sys.platform == "darwin": + hint_dirs[:0] = [ + "/Library/Frameworks/Mono.framework/Versions/Current/bin", + "/usr/local/var/homebrew/linked/mono/bin", + ] + + for hint_dir in hint_dirs: + hint_path = os.path.join(hint_dir, "msbuild") + if os.path.isfile(hint_path): + return hint_path + elif os.path.isfile(hint_path + ".exe"): + return hint_path + ".exe" + + for hint_dir in os.environ["PATH"].split(os.pathsep): + hint_dir = hint_dir.strip('"') + hint_path = os.path.join(hint_dir, "msbuild") + if os.path.isfile(hint_path) and os.access(hint_path, os.X_OK): + return hint_path + if os.path.isfile(hint_path + ".exe") and os.access(hint_path + ".exe", os.X_OK): + return hint_path + ".exe" + + return None + + +def find_msbuild_tools_path_reg(): + import subprocess + + program_files = os.getenv("PROGRAMFILES(X86)") + if not program_files: + program_files = os.getenv("PROGRAMFILES") + vswhere = os.path.join(program_files, "Microsoft Visual Studio", "Installer", "vswhere.exe") + + vswhere_args = ["-latest", "-products", "*", "-requires", "Microsoft.Component.MSBuild"] + + try: + lines = subprocess.check_output([vswhere] + vswhere_args).splitlines() + + for line in lines: + parts = line.decode("utf-8").split(":", 1) + + if len(parts) < 2 or parts[0] != "installationPath": + continue + + val = parts[1].strip() + + if not val: + raise ValueError("Value of `installationPath` entry is empty") + + # Since VS2019, the directory is simply named "Current" + msbuild_dir = os.path.join(val, "MSBuild", "Current", "Bin") + if os.path.isdir(msbuild_dir): + return msbuild_dir + + # Directory name "15.0" is used in VS 2017 + return os.path.join(val, "MSBuild", "15.0", "Bin") + + raise ValueError("Cannot find `installationPath` entry") + except ValueError as e: + print("Error reading output from vswhere: " + str(e)) + except OSError: + pass # Fine, vswhere not found + except (subprocess.CalledProcessError, OSError): + pass + + +@dataclass +class ToolsLocation: + dotnet_cli: str = "" + msbuild_standalone: str = "" + msbuild_mono: str = "" + mono_bin_dir: str = "" + + +def find_any_msbuild_tool(mono_prefix): + # Preference order: dotnet CLI > Standalone MSBuild > Mono's MSBuild + + # Find dotnet CLI + dotnet_cli = find_dotnet_cli() + if dotnet_cli: + return ToolsLocation(dotnet_cli=dotnet_cli) + + # Find standalone MSBuild + if os.name == "nt": + msbuild_standalone = find_msbuild_standalone_windows() + if msbuild_standalone: + return ToolsLocation(msbuild_standalone=msbuild_standalone) + + if mono_prefix: + # Find Mono's MSBuild + if os.name == "nt": + msbuild_mono = find_msbuild_mono_windows(mono_prefix) + if msbuild_mono: + return ToolsLocation(msbuild_mono=msbuild_mono) + else: + msbuild_mono = find_msbuild_mono_unix() + if msbuild_mono: + return ToolsLocation(msbuild_mono=msbuild_mono) + + return None + + +def run_msbuild(tools: ToolsLocation, sln: str, msbuild_args: [str] = None): + if msbuild_args is None: + msbuild_args = [] + + using_msbuild_mono = False + + # Preference order: dotnet CLI > Standalone MSBuild > Mono's MSBuild + if tools.dotnet_cli: + args = [tools.dotnet_cli, "msbuild"] + elif tools.msbuild_standalone: + args = [tools.msbuild_standalone] + elif tools.msbuild_mono: + args = [tools.msbuild_mono] + using_msbuild_mono = True + else: + raise RuntimeError("Path to MSBuild or dotnet CLI not provided.") + + args += [sln] + + if len(msbuild_args) > 0: + args += msbuild_args + + print("Running MSBuild: ", " ".join(shlex.quote(arg) for arg in args), flush=True) + + msbuild_env = os.environ.copy() + + # Needed when running from Developer Command Prompt for VS + if "PLATFORM" in msbuild_env: + del msbuild_env["PLATFORM"] + + if using_msbuild_mono: + # The (Csc/Vbc/Fsc)ToolExe environment variables are required when + # building with Mono's MSBuild. They must point to the batch files + # in Mono's bin directory to make sure they are executed with Mono. + msbuild_env.update( + { + "CscToolExe": os.path.join(tools.mono_bin_dir, "csc.bat"), + "VbcToolExe": os.path.join(tools.mono_bin_dir, "vbc.bat"), + "FscToolExe": os.path.join(tools.mono_bin_dir, "fsharpc.bat"), + } + ) + + return subprocess.call(args, env=msbuild_env) + + +def build_godot_api(msbuild_tool, module_dir, output_dir, push_nupkgs_local, float_size): + target_filenames = [ + "GodotSharp.dll", + "GodotSharp.pdb", + "GodotSharp.xml", + "GodotSharpEditor.dll", + "GodotSharpEditor.pdb", + "GodotSharpEditor.xml", + "GodotPlugins.dll", + "GodotPlugins.pdb", + "GodotPlugins.runtimeconfig.json", + ] + + for build_config in ["Debug", "Release"]: + editor_api_dir = os.path.join(output_dir, "GodotSharp", "Api", build_config) + + targets = [os.path.join(editor_api_dir, filename) for filename in target_filenames] + + args = ["/restore", "/t:Build", "/p:Configuration=" + build_config, "/p:NoWarn=1591"] + if push_nupkgs_local: + args += ["/p:ClearNuGetLocalCache=true", "/p:PushNuGetToLocalSource=" + push_nupkgs_local] + if float_size == "64": + args += ["/p:GodotFloat64=true"] + + sln = os.path.join(module_dir, "glue/GodotSharp/GodotSharp.sln") + exit_code = run_msbuild( + msbuild_tool, + sln=sln, + msbuild_args=args, + ) + if exit_code != 0: + return exit_code + + # Copy targets + + core_src_dir = os.path.abspath(os.path.join(sln, os.pardir, "GodotSharp", "bin", build_config)) + editor_src_dir = os.path.abspath(os.path.join(sln, os.pardir, "GodotSharpEditor", "bin", build_config)) + plugins_src_dir = os.path.abspath(os.path.join(sln, os.pardir, "GodotPlugins", "bin", build_config, "net6.0")) + + if not os.path.isdir(editor_api_dir): + assert not os.path.isfile(editor_api_dir) + os.makedirs(editor_api_dir) + + def copy_target(target_path): + from shutil import copy + + filename = os.path.basename(target_path) + + src_path = os.path.join(core_src_dir, filename) + if not os.path.isfile(src_path): + src_path = os.path.join(editor_src_dir, filename) + if not os.path.isfile(src_path): + src_path = os.path.join(plugins_src_dir, filename) + + print(f"Copying assembly to {target_path}...") + copy(src_path, target_path) + + for scons_target in targets: + copy_target(scons_target) + + return 0 + + +def build_all(msbuild_tool, module_dir, output_dir, godot_platform, dev_debug, push_nupkgs_local, float_size): + # Godot API + exit_code = build_godot_api(msbuild_tool, module_dir, output_dir, push_nupkgs_local, float_size) + if exit_code != 0: + return exit_code + + # GodotTools + sln = os.path.join(module_dir, "editor/GodotTools/GodotTools.sln") + args = ["/restore", "/t:Build", "/p:Configuration=" + ("Debug" if dev_debug else "Release")] + ( + ["/p:GodotPlatform=" + godot_platform] if godot_platform else [] + ) + if push_nupkgs_local: + args += ["/p:ClearNuGetLocalCache=true", "/p:PushNuGetToLocalSource=" + push_nupkgs_local] + if float_size == "64": + args += ["/p:GodotFloat64=true"] + exit_code = run_msbuild(msbuild_tool, sln=sln, msbuild_args=args) + if exit_code != 0: + return exit_code + + # Godot.NET.Sdk + args = ["/restore", "/t:Build", "/p:Configuration=Release"] + if push_nupkgs_local: + args += ["/p:ClearNuGetLocalCache=true", "/p:PushNuGetToLocalSource=" + push_nupkgs_local] + if float_size == "64": + args += ["/p:GodotFloat64=true"] + sln = os.path.join(module_dir, "editor/Godot.NET.Sdk/Godot.NET.Sdk.sln") + exit_code = run_msbuild(msbuild_tool, sln=sln, msbuild_args=args) + if exit_code != 0: + return exit_code + + return 0 + + +def main(): + import argparse + import sys + + parser = argparse.ArgumentParser(description="Builds all Godot .NET solutions") + parser.add_argument("--godot-output-dir", type=str, required=True) + parser.add_argument( + "--dev-debug", + action="store_true", + default=False, + help="Build GodotTools and Godot.NET.Sdk with 'Configuration=Debug'", + ) + parser.add_argument("--godot-platform", type=str, default="") + parser.add_argument("--mono-prefix", type=str, default="") + parser.add_argument("--push-nupkgs-local", type=str, default="") + parser.add_argument("--float", type=str, default="32", choices=["32", "64"], help="Floating-point precision") + + args = parser.parse_args() + + this_script_dir = os.path.dirname(os.path.realpath(__file__)) + module_dir = os.path.abspath(os.path.join(this_script_dir, os.pardir)) + + output_dir = os.path.abspath(args.godot_output_dir) + + msbuild_tool = find_any_msbuild_tool(args.mono_prefix) + + if msbuild_tool is None: + print("Unable to find MSBuild") + sys.exit(1) + + exit_code = build_all( + msbuild_tool, + module_dir, + output_dir, + args.godot_platform, + args.dev_debug, + args.push_nupkgs_local, + args.float, + ) + sys.exit(exit_code) + + +if __name__ == "__main__": + main() diff --git a/modules/mono/build_scripts/gen_cs_glue_version.py b/modules/mono/build_scripts/gen_cs_glue_version.py deleted file mode 100644 index 98bbb4d9be..0000000000 --- a/modules/mono/build_scripts/gen_cs_glue_version.py +++ /dev/null @@ -1,20 +0,0 @@ -def generate_header(solution_dir, version_header_dst): - import os - - latest_mtime = 0 - for root, dirs, files in os.walk(solution_dir, topdown=True): - dirs[:] = [d for d in dirs if d not in ["Generated"]] # Ignored generated files - files = [f for f in files if f.endswith(".cs")] - for file in files: - filepath = os.path.join(root, file) - mtime = os.path.getmtime(filepath) - latest_mtime = mtime if mtime > latest_mtime else latest_mtime - - glue_version = int(latest_mtime) # The latest modified time will do for now - - with open(version_header_dst, "w") as version_header: - version_header.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n") - version_header.write("#ifndef CS_GLUE_VERSION_H\n") - version_header.write("#define CS_GLUE_VERSION_H\n\n") - version_header.write("#define CS_GLUE_VERSION UINT32_C(" + str(glue_version) + ")\n") - version_header.write("\n#endif // CS_GLUE_VERSION_H\n") diff --git a/modules/mono/build_scripts/godot_net_sdk_build.py b/modules/mono/build_scripts/godot_net_sdk_build.py deleted file mode 100644 index 8c5a60d2db..0000000000 --- a/modules/mono/build_scripts/godot_net_sdk_build.py +++ /dev/null @@ -1,55 +0,0 @@ -# Build Godot.NET.Sdk solution - -import os - -from SCons.Script import Dir - - -def build_godot_net_sdk(source, target, env): - # source and target elements are of type SCons.Node.FS.File, hence why we convert them to str - - module_dir = env["module_dir"] - - solution_path = os.path.join(module_dir, "editor/Godot.NET.Sdk/Godot.NET.Sdk.sln") - build_config = "Release" - - from .solution_builder import build_solution - - extra_msbuild_args = ["/p:GodotPlatform=" + env["platform"]] - - build_solution(env, solution_path, build_config, extra_msbuild_args) - # No need to copy targets. The Godot.NET.Sdk csproj takes care of copying them. - - -def get_nupkgs_versions(props_file): - import xml.etree.ElementTree as ET - - tree = ET.parse(props_file) - root = tree.getroot() - - return { - "Godot.NET.Sdk": root.find("./PropertyGroup/PackageVersion_Godot_NET_Sdk").text.strip(), - "Godot.SourceGenerators": root.find("./PropertyGroup/PackageVersion_Godot_SourceGenerators").text.strip(), - } - - -def build(env_mono): - assert env_mono["tools"] - - output_dir = Dir("#bin").abspath - editor_tools_dir = os.path.join(output_dir, "GodotSharp", "Tools") - nupkgs_dir = os.path.join(editor_tools_dir, "nupkgs") - - module_dir = os.getcwd() - - nupkgs_versions = get_nupkgs_versions(os.path.join(module_dir, "SdkPackageVersions.props")) - - target_filenames = [ - "Godot.NET.Sdk.%s.nupkg" % nupkgs_versions["Godot.NET.Sdk"], - "Godot.SourceGenerators.%s.nupkg" % nupkgs_versions["Godot.SourceGenerators"], - ] - - targets = [os.path.join(nupkgs_dir, filename) for filename in target_filenames] - - cmd = env_mono.CommandNoCache(targets, [], build_godot_net_sdk, module_dir=module_dir) - env_mono.AlwaysBuild(cmd) diff --git a/modules/mono/build_scripts/godot_tools_build.py b/modules/mono/build_scripts/godot_tools_build.py deleted file mode 100644 index 3bbbf29d3b..0000000000 --- a/modules/mono/build_scripts/godot_tools_build.py +++ /dev/null @@ -1,38 +0,0 @@ -# Build GodotTools solution - -import os - -from SCons.Script import Dir - - -def build_godot_tools(source, target, env): - # source and target elements are of type SCons.Node.FS.File, hence why we convert them to str - - module_dir = env["module_dir"] - - solution_path = os.path.join(module_dir, "editor/GodotTools/GodotTools.sln") - build_config = "Debug" if env["target"] == "debug" else "Release" - - from .solution_builder import build_solution - - extra_msbuild_args = ["/p:GodotPlatform=" + env["platform"]] - - build_solution(env, solution_path, build_config, extra_msbuild_args) - # No need to copy targets. The GodotTools csproj takes care of copying them. - - -def build(env_mono, api_sln_cmd): - assert env_mono["tools"] - - output_dir = Dir("#bin").abspath - editor_tools_dir = os.path.join(output_dir, "GodotSharp", "Tools") - - target_filenames = ["GodotTools.dll"] - - if env_mono["target"] == "debug": - target_filenames += ["GodotTools.pdb"] - - targets = [os.path.join(editor_tools_dir, filename) for filename in target_filenames] - - cmd = env_mono.CommandNoCache(targets, api_sln_cmd, build_godot_tools, module_dir=os.getcwd()) - env_mono.AlwaysBuild(cmd) diff --git a/modules/mono/build_scripts/make_android_mono_config.py b/modules/mono/build_scripts/make_android_mono_config.py deleted file mode 100644 index 1920ef1c1a..0000000000 --- a/modules/mono/build_scripts/make_android_mono_config.py +++ /dev/null @@ -1,55 +0,0 @@ -def generate_compressed_config(config_src, output_dir): - import os.path - - # Source file - with open(os.path.join(output_dir, "android_mono_config.gen.cpp"), "w") as cpp: - with open(config_src, "rb") as f: - buf = f.read() - decompr_size = len(buf) - import zlib - - # Use maximum zlib compression level to further reduce file size - # (at the cost of initial build times). - buf = zlib.compress(buf, zlib.Z_BEST_COMPRESSION) - compr_size = len(buf) - - bytes_seq_str = "" - for i, buf_idx in enumerate(range(compr_size)): - if i > 0: - bytes_seq_str += ", " - bytes_seq_str += str(buf[buf_idx]) - - cpp.write( - """/* THIS FILE IS GENERATED DO NOT EDIT */ -#include "android_mono_config.h" - -#ifdef ANDROID_ENABLED - -#include "core/io/compression.h" - - -namespace { - -// config -static const int config_compressed_size = %d; -static const int config_uncompressed_size = %d; -static const unsigned char config_compressed_data[] = { %s }; -} // namespace - -String get_godot_android_mono_config() { - Vector<uint8_t> data; - data.resize(config_uncompressed_size); - uint8_t* w = data.ptrw(); - Compression::decompress(w, config_uncompressed_size, config_compressed_data, - config_compressed_size, Compression::MODE_DEFLATE); - String s; - if (s.parse_utf8((const char *)w, data.size())) { - ERR_FAIL_V(String()); - } - return s; -} - -#endif // ANDROID_ENABLED -""" - % (compr_size, decompr_size, bytes_seq_str) - ) diff --git a/modules/mono/build_scripts/mono_android_config.xml b/modules/mono/build_scripts/mono_android_config.xml deleted file mode 100644 index e79670afd2..0000000000 --- a/modules/mono/build_scripts/mono_android_config.xml +++ /dev/null @@ -1,28 +0,0 @@ -<configuration> - <dllmap wordsize="32" dll="i:cygwin1.dll" target="/system/lib/libc.so" /> - <dllmap wordsize="64" dll="i:cygwin1.dll" target="/system/lib64/libc.so" /> - <dllmap wordsize="32" dll="libc" target="/system/lib/libc.so" /> - <dllmap wordsize="64" dll="libc" target="/system/lib64/libc.so" /> - <dllmap wordsize="32" dll="intl" target="/system/lib/libc.so" /> - <dllmap wordsize="64" dll="intl" target="/system/lib64/libc.so" /> - <dllmap wordsize="32" dll="libintl" target="/system/lib/libc.so" /> - <dllmap wordsize="64" dll="libintl" target="/system/lib64/libc.so" /> - <dllmap dll="MonoPosixHelper" target="libMonoPosixHelper.so" /> - <dllmap dll="System.Native" target="libmono-native.so" /> - <dllmap wordsize="32" dll="i:msvcrt" target="/system/lib/libc.so" /> - <dllmap wordsize="64" dll="i:msvcrt" target="/system/lib64/libc.so" /> - <dllmap wordsize="32" dll="i:msvcrt.dll" target="/system/lib/libc.so" /> - <dllmap wordsize="64" dll="i:msvcrt.dll" target="/system/lib64/libc.so" /> - <dllmap wordsize="32" dll="sqlite" target="/system/lib/libsqlite.so" /> - <dllmap wordsize="64" dll="sqlite" target="/system/lib64/libsqlite.so" /> - <dllmap wordsize="32" dll="sqlite3" target="/system/lib/libsqlite.so" /> - <dllmap wordsize="64" dll="sqlite3" target="/system/lib64/libsqlite.so" /> - <dllmap wordsize="32" dll="liblog" target="/system/lib/liblog.so" /> - <dllmap wordsize="64" dll="liblog" target="/system/lib64/liblog.so" /> - <dllmap dll="i:kernel32.dll"> - <dllentry dll="__Internal" name="CopyMemory" target="mono_win32_compat_CopyMemory"/> - <dllentry dll="__Internal" name="FillMemory" target="mono_win32_compat_FillMemory"/> - <dllentry dll="__Internal" name="MoveMemory" target="mono_win32_compat_MoveMemory"/> - <dllentry dll="__Internal" name="ZeroMemory" target="mono_win32_compat_ZeroMemory"/> - </dllmap> -</configuration> diff --git a/modules/mono/build_scripts/mono_configure.py b/modules/mono/build_scripts/mono_configure.py index 8e441e7e07..5d63773096 100644 --- a/modules/mono/build_scripts/mono_configure.py +++ b/modules/mono/build_scripts/mono_configure.py @@ -1,574 +1,29 @@ import os import os.path -import subprocess - -from SCons.Script import Dir, Environment - -if os.name == "nt": - from . import mono_reg_utils as monoreg - - -android_arch_dirs = { - "armv7": "armeabi-v7a", - "arm64v8": "arm64-v8a", - "x86": "x86", - "x86_64": "x86_64", -} - - -def get_android_out_dir(env): - return os.path.join( - Dir("#platform/android/java/lib/libs").abspath, - "release" if env["target"] == "release" else "debug", - android_arch_dirs[env["android_arch"]], - ) - - -def find_name_in_dir_files(directory, names, prefixes=[""], extensions=[""]): - for extension in extensions: - if extension and not extension.startswith("."): - extension = "." + extension - for prefix in prefixes: - for curname in names: - if os.path.isfile(os.path.join(directory, prefix + curname + extension)): - return curname - return "" - - -def find_file_in_dir(directory, names, prefixes=[""], extensions=[""]): - for extension in extensions: - if extension and not extension.startswith("."): - extension = "." + extension - for prefix in prefixes: - for curname in names: - filename = prefix + curname + extension - if os.path.isfile(os.path.join(directory, filename)): - return filename - return "" - - -def copy_file(src_dir, dst_dir, src_name, dst_name=""): - from shutil import copy - - src_path = os.path.join(Dir(src_dir).abspath, src_name) - dst_dir = Dir(dst_dir).abspath - - if not os.path.isdir(dst_dir): - os.makedirs(dst_dir) - - if dst_name: - copy(src_path, os.path.join(dst_dir, dst_name)) - else: - copy(src_path, dst_dir) def is_desktop(platform): - return platform in ["windows", "osx", "linuxbsd", "server", "uwp", "haiku"] + return platform in ["windows", "macos", "linuxbsd", "uwp", "haiku"] def is_unix_like(platform): - return platform in ["osx", "linuxbsd", "server", "android", "haiku", "iphone"] + return platform in ["macos", "linuxbsd", "android", "haiku", "ios"] def module_supports_tools_on(platform): - return platform not in ["android", "javascript", "iphone"] - - -def find_wasm_src_dir(mono_root): - hint_dirs = [ - os.path.join(mono_root, "src"), - os.path.join(mono_root, "../src"), - ] - for hint_dir in hint_dirs: - if os.path.isfile(os.path.join(hint_dir, "driver.c")): - return hint_dir - return "" + return is_desktop(platform) def configure(env, env_mono): - bits = env["bits"] - is_android = env["platform"] == "android" - is_javascript = env["platform"] == "javascript" - is_ios = env["platform"] == "iphone" - is_ios_sim = is_ios and env["arch"] in ["x86", "x86_64"] + # is_android = env["platform"] == "android" + # is_web = env["platform"] == "web" + # is_ios = env["platform"] == "ios" + # is_ios_sim = is_ios and env["arch"] in ["x86_32", "x86_64"] tools_enabled = env["tools"] - mono_static = env["mono_static"] - copy_mono_root = env["copy_mono_root"] - - mono_prefix = env["mono_prefix"] - mono_bcl = env["mono_bcl"] - - mono_lib_names = ["mono-2.0-sgen", "monosgen-2.0"] - - if is_android and not env["android_arch"] in android_arch_dirs: - raise RuntimeError("This module does not support the specified 'android_arch': " + env["android_arch"]) if tools_enabled and not module_supports_tools_on(env["platform"]): - # TODO: - # Android: We have to add the data directory to the apk, concretely the Api and Tools folders. raise RuntimeError("This module does not currently support building for this platform with tools enabled") - if is_android and mono_static: - # FIXME: When static linking and doing something that requires libmono-native, we get a dlopen error as 'libmono-native' - # seems to depend on 'libmonosgen-2.0'. Could be fixed by re-directing to '__Internal' with a dllmap or in the dlopen hook. - raise RuntimeError("Statically linking Mono is not currently supported for this platform") - - if not mono_static and (is_javascript or is_ios): - raise RuntimeError("Dynamically linking Mono is not currently supported for this platform") - - if not mono_prefix and (os.getenv("MONO32_PREFIX") or os.getenv("MONO64_PREFIX")): - print( - "WARNING: The environment variables 'MONO32_PREFIX' and 'MONO64_PREFIX' are deprecated; use the" - " 'mono_prefix' SCons parameter instead" - ) - - # Although we don't support building with tools for any platform where we currently use static AOT, - # if these are supported in the future, we won't be using static AOT for them as that would be - # too restrictive for the editor. These builds would probably be made to only use the interpreter. - mono_aot_static = (is_ios and not is_ios_sim) and not env["tools"] - - # Static AOT is only supported on the root domain - mono_single_appdomain = mono_aot_static - - if mono_single_appdomain: - env_mono.Append(CPPDEFINES=["GD_MONO_SINGLE_APPDOMAIN"]) - - if (env["tools"] or env["target"] != "release") and not mono_single_appdomain: + if env["tools"]: env_mono.Append(CPPDEFINES=["GD_MONO_HOT_RELOAD"]) - - if env["platform"] == "windows": - mono_root = mono_prefix - - if not mono_root and os.name == "nt": - mono_root = monoreg.find_mono_root_dir(bits) - - if not mono_root: - raise RuntimeError( - "Mono installation directory not found; specify one manually with the 'mono_prefix' SCons parameter" - ) - - print("Found Mono root directory: " + mono_root) - - mono_lib_path = os.path.join(mono_root, "lib") - - env.Append(LIBPATH=mono_lib_path) - env_mono.Prepend(CPPPATH=os.path.join(mono_root, "include", "mono-2.0")) - - lib_suffixes = [".lib"] - - if not env.msvc: - # MingW supports both '.a' and '.lib' - lib_suffixes.insert(0, ".a") - - if mono_static: - if env.msvc: - mono_static_lib_name = "libmono-static-sgen" - else: - mono_static_lib_name = "libmonosgen-2.0" - - mono_static_lib_file = find_file_in_dir(mono_lib_path, [mono_static_lib_name], extensions=lib_suffixes) - - if not mono_static_lib_file: - raise RuntimeError("Could not find static mono library in: " + mono_lib_path) - - if env.msvc: - env.Append(LINKFLAGS=mono_static_lib_file) - - env.Append(LINKFLAGS="Mincore.lib") - env.Append(LINKFLAGS="msvcrt.lib") - env.Append(LINKFLAGS="LIBCMT.lib") - env.Append(LINKFLAGS="Psapi.lib") - else: - mono_static_lib_file_path = os.path.join(mono_lib_path, mono_static_lib_file) - env.Append(LINKFLAGS=["-Wl,-whole-archive", mono_static_lib_file_path, "-Wl,-no-whole-archive"]) - - env.Append(LIBS=["psapi"]) - env.Append(LIBS=["version"]) - else: - mono_lib_file = find_file_in_dir(mono_lib_path, mono_lib_names, extensions=lib_suffixes) - - if not mono_lib_file: - raise RuntimeError("Could not find mono library in: " + mono_lib_path) - - if env.msvc: - env.Append(LINKFLAGS=mono_lib_file) - else: - mono_lib_file_path = os.path.join(mono_lib_path, mono_lib_file) - env.Append(LINKFLAGS=mono_lib_file_path) - - mono_bin_path = os.path.join(mono_root, "bin") - - mono_dll_file = find_file_in_dir(mono_bin_path, mono_lib_names, prefixes=["", "lib"], extensions=[".dll"]) - - if not mono_dll_file: - raise RuntimeError("Could not find mono shared library in: " + mono_bin_path) - - copy_file(mono_bin_path, "#bin", mono_dll_file) - else: - is_apple = env["platform"] in ["osx", "iphone"] - is_macos = is_apple and not is_ios - - sharedlib_ext = ".dylib" if is_apple else ".so" - - mono_root = mono_prefix - mono_lib_path = "" - mono_so_file = "" - - if not mono_root and (is_android or is_javascript or is_ios): - raise RuntimeError( - "Mono installation directory not found; specify one manually with the 'mono_prefix' SCons parameter" - ) - - if not mono_root and is_macos: - # Try with some known directories under OSX - hint_dirs = ["/Library/Frameworks/Mono.framework/Versions/Current", "/usr/local/var/homebrew/linked/mono"] - for hint_dir in hint_dirs: - if os.path.isdir(hint_dir): - mono_root = hint_dir - break - - # We can't use pkg-config to link mono statically, - # but we can still use it to find the mono root directory - if not mono_root and mono_static: - mono_root = pkgconfig_try_find_mono_root(mono_lib_names, sharedlib_ext) - if not mono_root: - raise RuntimeError( - "Building with mono_static=yes, but failed to find the mono prefix with pkg-config; " - + "specify one manually with the 'mono_prefix' SCons parameter" - ) - - if is_ios and not is_ios_sim: - env_mono.Append(CPPDEFINES=["IOS_DEVICE"]) - - if mono_root: - print("Found Mono root directory: " + mono_root) - - mono_lib_path = os.path.join(mono_root, "lib") - - env.Append(LIBPATH=[mono_lib_path]) - env_mono.Prepend(CPPPATH=os.path.join(mono_root, "include", "mono-2.0")) - - mono_lib = find_name_in_dir_files(mono_lib_path, mono_lib_names, prefixes=["lib"], extensions=[".a"]) - - if not mono_lib: - raise RuntimeError("Could not find mono library in: " + mono_lib_path) - - env_mono.Append(CPPDEFINES=["_REENTRANT"]) - - if mono_static: - if not is_javascript: - env.Append(LINKFLAGS=["-rdynamic"]) - - mono_lib_file = os.path.join(mono_lib_path, "lib" + mono_lib + ".a") - - if is_apple: - if is_macos: - env.Append(LINKFLAGS=["-Wl,-force_load," + mono_lib_file]) - else: - arch = env["arch"] - - def copy_mono_lib(libname_wo_ext): - copy_file( - mono_lib_path, "#bin", libname_wo_ext + ".a", "%s.iphone.%s.a" % (libname_wo_ext, arch) - ) - - # Copy Mono libraries to the output folder. These are meant to be bundled with - # the export templates and added to the Xcode project when exporting a game. - copy_mono_lib("lib" + mono_lib) - copy_mono_lib("libmono-native") - copy_mono_lib("libmono-profiler-log") - - if not is_ios_sim: - copy_mono_lib("libmono-ee-interp") - copy_mono_lib("libmono-icall-table") - copy_mono_lib("libmono-ilgen") - else: - assert is_desktop(env["platform"]) or is_android or is_javascript - env.Append(LINKFLAGS=["-Wl,-whole-archive", mono_lib_file, "-Wl,-no-whole-archive"]) - - if is_javascript: - env.Append(LIBS=["mono-icall-table", "mono-native", "mono-ilgen", "mono-ee-interp"]) - - wasm_src_dir = os.path.join(mono_root, "src") - if not os.path.isdir(wasm_src_dir): - raise RuntimeError("Could not find mono wasm src directory") - - # Ideally this should be defined only for 'driver.c', but I can't fight scons for another 2 hours - env_mono.Append(CPPDEFINES=["CORE_BINDINGS"]) - - env_mono.add_source_files( - env.modules_sources, - [ - os.path.join(wasm_src_dir, "driver.c"), - os.path.join(wasm_src_dir, "zlib-helper.c"), - os.path.join(wasm_src_dir, "corebindings.c"), - ], - ) - - env.Append( - LINKFLAGS=[ - "--js-library", - os.path.join(wasm_src_dir, "library_mono.js"), - "--js-library", - os.path.join(wasm_src_dir, "binding_support.js"), - "--js-library", - os.path.join(wasm_src_dir, "dotnet_support.js"), - ] - ) - else: - env.Append(LIBS=[mono_lib]) - - if is_macos: - env.Append(LIBS=["iconv", "pthread"]) - elif is_android: - pass # Nothing - elif is_ios: - pass # Nothing, linking is delegated to the exported Xcode project - elif is_javascript: - env.Append(LIBS=["m", "rt", "dl", "pthread"]) - else: - env.Append(LIBS=["m", "rt", "dl", "pthread"]) - - if not mono_static: - mono_so_file = find_file_in_dir( - mono_lib_path, mono_lib_names, prefixes=["lib"], extensions=[sharedlib_ext] - ) - - if not mono_so_file: - raise RuntimeError("Could not find mono shared library in: " + mono_lib_path) - else: - assert not mono_static - - # TODO: Add option to force using pkg-config - print("Mono root directory not found. Using pkg-config instead") - - env.ParseConfig("pkg-config monosgen-2 --libs") - env_mono.ParseConfig("pkg-config monosgen-2 --cflags") - - tmpenv = Environment() - tmpenv.AppendENVPath("PKG_CONFIG_PATH", os.getenv("PKG_CONFIG_PATH")) - tmpenv.ParseConfig("pkg-config monosgen-2 --libs-only-L") - - for hint_dir in tmpenv["LIBPATH"]: - file_found = find_file_in_dir(hint_dir, mono_lib_names, prefixes=["lib"], extensions=[sharedlib_ext]) - if file_found: - mono_lib_path = hint_dir - mono_so_file = file_found - break - - if not mono_so_file: - raise RuntimeError("Could not find mono shared library in: " + str(tmpenv["LIBPATH"])) - - if not mono_static: - libs_output_dir = get_android_out_dir(env) if is_android else "#bin" - copy_file(mono_lib_path, libs_output_dir, mono_so_file) - - if not tools_enabled: - if is_desktop(env["platform"]): - if not mono_root: - mono_root = ( - subprocess.check_output(["pkg-config", "mono-2", "--variable=prefix"]).decode("utf8").strip() - ) - - make_template_dir(env, mono_root) - elif is_android: - # Compress Android Mono Config - from . import make_android_mono_config - - module_dir = os.getcwd() - config_file_path = os.path.join(module_dir, "build_scripts", "mono_android_config.xml") - make_android_mono_config.generate_compressed_config(config_file_path, "mono_gd/") - - # Copy the required shared libraries - copy_mono_shared_libs(env, mono_root, None) - elif is_javascript: - pass # No data directory for this platform - elif is_ios: - pass # No data directory for this platform - - if copy_mono_root: - if not mono_root: - mono_root = subprocess.check_output(["pkg-config", "mono-2", "--variable=prefix"]).decode("utf8").strip() - - if tools_enabled: - # Only supported for editor builds. - copy_mono_root_files(env, mono_root, mono_bcl) - - -def make_template_dir(env, mono_root): - from shutil import rmtree - - platform = env["platform"] - target = env["target"] - - template_dir_name = "" - - assert is_desktop(platform) - - template_dir_name = "data.mono.%s.%s.%s" % (platform, env["bits"], target) - - output_dir = Dir("#bin").abspath - template_dir = os.path.join(output_dir, template_dir_name) - - template_mono_root_dir = os.path.join(template_dir, "Mono") - - if os.path.isdir(template_mono_root_dir): - rmtree(template_mono_root_dir) # Clean first - - # Copy etc/mono/ - - template_mono_config_dir = os.path.join(template_mono_root_dir, "etc", "mono") - copy_mono_etc_dir(mono_root, template_mono_config_dir, platform) - - # Copy the required shared libraries - - copy_mono_shared_libs(env, mono_root, template_mono_root_dir) - - -def copy_mono_root_files(env, mono_root, mono_bcl): - from glob import glob - from shutil import copy - from shutil import rmtree - - if not mono_root: - raise RuntimeError("Mono installation directory not found") - - output_dir = Dir("#bin").abspath - editor_mono_root_dir = os.path.join(output_dir, "GodotSharp", "Mono") - - if os.path.isdir(editor_mono_root_dir): - rmtree(editor_mono_root_dir) # Clean first - - # Copy etc/mono/ - - editor_mono_config_dir = os.path.join(editor_mono_root_dir, "etc", "mono") - copy_mono_etc_dir(mono_root, editor_mono_config_dir, env["platform"]) - - # Copy the required shared libraries - - copy_mono_shared_libs(env, mono_root, editor_mono_root_dir) - - # Copy framework assemblies - - mono_framework_dir = mono_bcl or os.path.join(mono_root, "lib", "mono", "4.5") - mono_framework_facades_dir = os.path.join(mono_framework_dir, "Facades") - - editor_mono_framework_dir = os.path.join(editor_mono_root_dir, "lib", "mono", "4.5") - editor_mono_framework_facades_dir = os.path.join(editor_mono_framework_dir, "Facades") - - if not os.path.isdir(editor_mono_framework_dir): - os.makedirs(editor_mono_framework_dir) - if not os.path.isdir(editor_mono_framework_facades_dir): - os.makedirs(editor_mono_framework_facades_dir) - - for assembly in glob(os.path.join(mono_framework_dir, "*.dll")): - copy(assembly, editor_mono_framework_dir) - for assembly in glob(os.path.join(mono_framework_facades_dir, "*.dll")): - copy(assembly, editor_mono_framework_facades_dir) - - -def copy_mono_etc_dir(mono_root, target_mono_config_dir, platform): - from distutils.dir_util import copy_tree - from glob import glob - from shutil import copy - - if not os.path.isdir(target_mono_config_dir): - os.makedirs(target_mono_config_dir) - - mono_etc_dir = os.path.join(mono_root, "etc", "mono") - if not os.path.isdir(mono_etc_dir): - mono_etc_dir = "" - etc_hint_dirs = [] - if platform != "windows": - etc_hint_dirs += ["/etc/mono", "/usr/local/etc/mono"] - if "MONO_CFG_DIR" in os.environ: - etc_hint_dirs += [os.path.join(os.environ["MONO_CFG_DIR"], "mono")] - for etc_hint_dir in etc_hint_dirs: - if os.path.isdir(etc_hint_dir): - mono_etc_dir = etc_hint_dir - break - if not mono_etc_dir: - raise RuntimeError("Mono installation etc directory not found") - - copy_tree(os.path.join(mono_etc_dir, "2.0"), os.path.join(target_mono_config_dir, "2.0")) - copy_tree(os.path.join(mono_etc_dir, "4.0"), os.path.join(target_mono_config_dir, "4.0")) - copy_tree(os.path.join(mono_etc_dir, "4.5"), os.path.join(target_mono_config_dir, "4.5")) - if os.path.isdir(os.path.join(mono_etc_dir, "mconfig")): - copy_tree(os.path.join(mono_etc_dir, "mconfig"), os.path.join(target_mono_config_dir, "mconfig")) - - for file in glob(os.path.join(mono_etc_dir, "*")): - if os.path.isfile(file): - copy(file, target_mono_config_dir) - - -def copy_mono_shared_libs(env, mono_root, target_mono_root_dir): - from shutil import copy - - def copy_if_exists(src, dst): - if os.path.isfile(src): - copy(src, dst) - - platform = env["platform"] - - if platform == "windows": - src_mono_bin_dir = os.path.join(mono_root, "bin") - target_mono_bin_dir = os.path.join(target_mono_root_dir, "bin") - - if not os.path.isdir(target_mono_bin_dir): - os.makedirs(target_mono_bin_dir) - - mono_posix_helper_file = find_file_in_dir( - src_mono_bin_dir, ["MonoPosixHelper"], prefixes=["", "lib"], extensions=[".dll"] - ) - copy( - os.path.join(src_mono_bin_dir, mono_posix_helper_file), - os.path.join(target_mono_bin_dir, "MonoPosixHelper.dll"), - ) - - # For newer versions - btls_dll_path = os.path.join(src_mono_bin_dir, "libmono-btls-shared.dll") - if os.path.isfile(btls_dll_path): - copy(btls_dll_path, target_mono_bin_dir) - else: - target_mono_lib_dir = ( - get_android_out_dir(env) if platform == "android" else os.path.join(target_mono_root_dir, "lib") - ) - - if not os.path.isdir(target_mono_lib_dir): - os.makedirs(target_mono_lib_dir) - - lib_file_names = [] - if platform == "osx": - lib_file_names = [ - lib_name + ".dylib" - for lib_name in ["libmono-btls-shared", "libmono-native-compat", "libMonoPosixHelper"] - ] - elif is_unix_like(platform): - lib_file_names = [ - lib_name + ".so" - for lib_name in [ - "libmono-btls-shared", - "libmono-ee-interp", - "libmono-native", - "libMonoPosixHelper", - "libmono-profiler-aot", - "libmono-profiler-coverage", - "libmono-profiler-log", - "libMonoSupportW", - ] - ] - - for lib_file_name in lib_file_names: - copy_if_exists(os.path.join(mono_root, "lib", lib_file_name), target_mono_lib_dir) - - -def pkgconfig_try_find_mono_root(mono_lib_names, sharedlib_ext): - tmpenv = Environment() - tmpenv.AppendENVPath("PKG_CONFIG_PATH", os.getenv("PKG_CONFIG_PATH")) - tmpenv.ParseConfig("pkg-config monosgen-2 --libs-only-L") - for hint_dir in tmpenv["LIBPATH"]: - name_found = find_name_in_dir_files(hint_dir, mono_lib_names, prefixes=["lib"], extensions=[sharedlib_ext]) - if name_found and os.path.isdir(os.path.join(hint_dir, "..", "include", "mono-2.0")): - return os.path.join(hint_dir, "..") - return "" diff --git a/modules/mono/build_scripts/mono_reg_utils.py b/modules/mono/build_scripts/mono_reg_utils.py deleted file mode 100644 index 43c1ec8f8a..0000000000 --- a/modules/mono/build_scripts/mono_reg_utils.py +++ /dev/null @@ -1,112 +0,0 @@ -import os -import platform - -if os.name == "nt": - import winreg - - -def _reg_open_key(key, subkey): - try: - return winreg.OpenKey(key, subkey) - except OSError: - if platform.architecture()[0] == "32bit": - bitness_sam = winreg.KEY_WOW64_64KEY - else: - bitness_sam = winreg.KEY_WOW64_32KEY - return winreg.OpenKey(key, subkey, 0, winreg.KEY_READ | bitness_sam) - - -def _reg_open_key_bits(key, subkey, bits): - sam = winreg.KEY_READ - - if platform.architecture()[0] == "32bit": - if bits == "64": - # Force 32bit process to search in 64bit registry - sam |= winreg.KEY_WOW64_64KEY - else: - if bits == "32": - # Force 64bit process to search in 32bit registry - sam |= winreg.KEY_WOW64_32KEY - - return winreg.OpenKey(key, subkey, 0, sam) - - -def _find_mono_in_reg(subkey, bits): - try: - with _reg_open_key_bits(winreg.HKEY_LOCAL_MACHINE, subkey, bits) as hKey: - value = winreg.QueryValueEx(hKey, "SdkInstallRoot")[0] - return value - except OSError: - return None - - -def _find_mono_in_reg_old(subkey, bits): - try: - with _reg_open_key_bits(winreg.HKEY_LOCAL_MACHINE, subkey, bits) as hKey: - default_clr = winreg.QueryValueEx(hKey, "DefaultCLR")[0] - if default_clr: - return _find_mono_in_reg(subkey + "\\" + default_clr, bits) - return None - except OSError: - return None - - -def find_mono_root_dir(bits): - root_dir = _find_mono_in_reg(r"SOFTWARE\Mono", bits) - if root_dir is not None: - return str(root_dir) - root_dir = _find_mono_in_reg_old(r"SOFTWARE\Novell\Mono", bits) - if root_dir is not None: - return str(root_dir) - return "" - - -def find_msbuild_tools_path_reg(): - import subprocess - - vswhere = os.getenv("PROGRAMFILES(X86)") - if not vswhere: - vswhere = os.getenv("PROGRAMFILES") - vswhere += r"\Microsoft Visual Studio\Installer\vswhere.exe" - - vswhere_args = ["-latest", "-products", "*", "-requires", "Microsoft.Component.MSBuild"] - - try: - lines = subprocess.check_output([vswhere] + vswhere_args).splitlines() - - for line in lines: - parts = line.decode("utf-8").split(":", 1) - - if len(parts) < 2 or parts[0] != "installationPath": - continue - - val = parts[1].strip() - - if not val: - raise ValueError("Value of `installationPath` entry is empty") - - # Since VS2019, the directory is simply named "Current" - msbuild_dir = os.path.join(val, "MSBuild\\Current\\Bin") - if os.path.isdir(msbuild_dir): - return msbuild_dir - - # Directory name "15.0" is used in VS 2017 - return os.path.join(val, "MSBuild\\15.0\\Bin") - - raise ValueError("Cannot find `installationPath` entry") - except ValueError as e: - print("Error reading output from vswhere: " + e.message) - except subprocess.CalledProcessError as e: - print(e.output) - except OSError as e: - print(e) - - # Try to find 14.0 in the Registry - - try: - subkey = r"SOFTWARE\Microsoft\MSBuild\ToolsVersions\14.0" - with _reg_open_key(winreg.HKEY_LOCAL_MACHINE, subkey) as hKey: - value = winreg.QueryValueEx(hKey, "MSBuildToolsPath")[0] - return value - except OSError: - return "" diff --git a/modules/mono/build_scripts/solution_builder.py b/modules/mono/build_scripts/solution_builder.py deleted file mode 100644 index 6a621c3c8b..0000000000 --- a/modules/mono/build_scripts/solution_builder.py +++ /dev/null @@ -1,145 +0,0 @@ -import os - - -verbose = False - - -def find_dotnet_cli(): - import os.path - - if os.name == "nt": - for hint_dir in os.environ["PATH"].split(os.pathsep): - hint_dir = hint_dir.strip('"') - hint_path = os.path.join(hint_dir, "dotnet") - if os.path.isfile(hint_path) and os.access(hint_path, os.X_OK): - return hint_path - if os.path.isfile(hint_path + ".exe") and os.access(hint_path + ".exe", os.X_OK): - return hint_path + ".exe" - else: - for hint_dir in os.environ["PATH"].split(os.pathsep): - hint_dir = hint_dir.strip('"') - hint_path = os.path.join(hint_dir, "dotnet") - if os.path.isfile(hint_path) and os.access(hint_path, os.X_OK): - return hint_path - - -def find_msbuild_unix(): - import os.path - import sys - - hint_dirs = [] - if sys.platform == "darwin": - hint_dirs[:0] = [ - "/Library/Frameworks/Mono.framework/Versions/Current/bin", - "/usr/local/var/homebrew/linked/mono/bin", - ] - - for hint_dir in hint_dirs: - hint_path = os.path.join(hint_dir, "msbuild") - if os.path.isfile(hint_path): - return hint_path - elif os.path.isfile(hint_path + ".exe"): - return hint_path + ".exe" - - for hint_dir in os.environ["PATH"].split(os.pathsep): - hint_dir = hint_dir.strip('"') - hint_path = os.path.join(hint_dir, "msbuild") - if os.path.isfile(hint_path) and os.access(hint_path, os.X_OK): - return hint_path - if os.path.isfile(hint_path + ".exe") and os.access(hint_path + ".exe", os.X_OK): - return hint_path + ".exe" - - return None - - -def find_msbuild_windows(env): - from .mono_reg_utils import find_mono_root_dir, find_msbuild_tools_path_reg - - mono_root = env["mono_prefix"] or find_mono_root_dir(env["bits"]) - - if not mono_root: - raise RuntimeError("Cannot find mono root directory") - - mono_bin_dir = os.path.join(mono_root, "bin") - msbuild_mono = os.path.join(mono_bin_dir, "msbuild.bat") - - msbuild_tools_path = find_msbuild_tools_path_reg() - - if msbuild_tools_path: - return (os.path.join(msbuild_tools_path, "MSBuild.exe"), {}) - - if os.path.isfile(msbuild_mono): - # The (Csc/Vbc/Fsc)ToolExe environment variables are required when - # building with Mono's MSBuild. They must point to the batch files - # in Mono's bin directory to make sure they are executed with Mono. - mono_msbuild_env = { - "CscToolExe": os.path.join(mono_bin_dir, "csc.bat"), - "VbcToolExe": os.path.join(mono_bin_dir, "vbc.bat"), - "FscToolExe": os.path.join(mono_bin_dir, "fsharpc.bat"), - } - return (msbuild_mono, mono_msbuild_env) - - return None - - -def run_command(command, args, env_override=None, name=None): - def cmd_args_to_str(cmd_args): - return " ".join([arg if not " " in arg else '"%s"' % arg for arg in cmd_args]) - - args = [command] + args - - if name is None: - name = os.path.basename(command) - - if verbose: - print("Running '%s': %s" % (name, cmd_args_to_str(args))) - - import subprocess - - try: - if env_override is None: - subprocess.check_call(args) - else: - subprocess.check_call(args, env=env_override) - except subprocess.CalledProcessError as e: - raise RuntimeError("'%s' exited with error code: %s" % (name, e.returncode)) - - -def build_solution(env, solution_path, build_config, extra_msbuild_args=[]): - global verbose - verbose = env["verbose"] - - msbuild_env = os.environ.copy() - - # Needed when running from Developer Command Prompt for VS - if "PLATFORM" in msbuild_env: - del msbuild_env["PLATFORM"] - - msbuild_args = [] - - dotnet_cli = find_dotnet_cli() - - if dotnet_cli: - msbuild_path = dotnet_cli - msbuild_args += ["msbuild"] # `dotnet msbuild` command - else: - # Find MSBuild - if os.name == "nt": - msbuild_info = find_msbuild_windows(env) - if msbuild_info is None: - raise RuntimeError("Cannot find MSBuild executable") - msbuild_path = msbuild_info[0] - msbuild_env.update(msbuild_info[1]) - else: - msbuild_path = find_msbuild_unix() - if msbuild_path is None: - raise RuntimeError("Cannot find MSBuild executable") - - print("MSBuild path: " + msbuild_path) - - # Build solution - - msbuild_args += [solution_path, "/restore", "/t:Build", "/p:Configuration=" + build_config] - msbuild_args += extra_msbuild_args - - run_command(msbuild_path, msbuild_args, env_override=msbuild_env, name="msbuild") |