diff options
Diffstat (limited to 'modules/mono/build_scripts')
-rw-r--r-- | modules/mono/build_scripts/api_solution_build.py | 35 | ||||
-rw-r--r-- | modules/mono/build_scripts/gen_cs_glue_version.py | 20 | ||||
-rw-r--r-- | modules/mono/build_scripts/godot_tools_build.py | 23 | ||||
-rw-r--r-- | modules/mono/build_scripts/make_android_mono_config.py | 20 | ||||
-rw-r--r-- | modules/mono/build_scripts/mono_configure.py | 509 | ||||
-rw-r--r-- | modules/mono/build_scripts/mono_reg_utils.py | 59 | ||||
-rw-r--r-- | modules/mono/build_scripts/solution_builder.py | 132 |
7 files changed, 459 insertions, 339 deletions
diff --git a/modules/mono/build_scripts/api_solution_build.py b/modules/mono/build_scripts/api_solution_build.py index 639197c285..9abac22df6 100644 --- a/modules/mono/build_scripts/api_solution_build.py +++ b/modules/mono/build_scripts/api_solution_build.py @@ -8,21 +8,22 @@ 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'] + module_dir = env["module_dir"] - solution_path = os.path.join(module_dir, 'glue/GodotSharp/GodotSharp.sln') + solution_path = os.path.join(module_dir, "glue/GodotSharp/GodotSharp.sln") - build_config = env['solution_build_config'] + build_config = env["solution_build_config"] - extra_msbuild_args = ['/p:NoWarn=1591'] # Ignore missing documentation warnings + 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)) + 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)) @@ -32,6 +33,7 @@ def build_api_solution(source, target, env): def copy_target(target_path): from shutil import copy + filename = os.path.basename(target_path) src_path = os.path.join(core_src_dir, filename) @@ -45,23 +47,28 @@ def build_api_solution(source, target, env): def build(env_mono): - assert env_mono['tools'] + assert env_mono["tools"] target_filenames = [ - 'GodotSharp.dll', 'GodotSharp.pdb', 'GodotSharp.xml', - 'GodotSharpEditor.dll', 'GodotSharpEditor.pdb', 'GodotSharpEditor.xml' + "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) + 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) + 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. diff --git a/modules/mono/build_scripts/gen_cs_glue_version.py b/modules/mono/build_scripts/gen_cs_glue_version.py index 5d1056c2fc..98bbb4d9be 100644 --- a/modules/mono/build_scripts/gen_cs_glue_version.py +++ b/modules/mono/build_scripts/gen_cs_glue_version.py @@ -1,20 +1,20 @@ - 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')] + 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 + 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') + 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_tools_build.py b/modules/mono/build_scripts/godot_tools_build.py index 99341c631e..cffacf2577 100644 --- a/modules/mono/build_scripts/godot_tools_build.py +++ b/modules/mono/build_scripts/godot_tools_build.py @@ -8,30 +8,31 @@ 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'] + 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' + solution_path = os.path.join(module_dir, "editor/GodotTools/GodotTools.sln") + build_config = "Debug" if env["target"] == "debug" else "Release" # Custom build target to make sure output is always copied to the data dir. - extra_build_args = ['/Target:Build;GodotTools:BuildAlwaysCopyToDataDir'] + extra_build_args = ["/Target:Build;GodotTools:BuildAlwaysCopyToDataDir"] + + from .solution_builder import build_solution, nuget_restore - from . solution_builder import build_solution, nuget_restore nuget_restore(env, solution_path) build_solution(env, solution_path, build_config, extra_build_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'] + assert env_mono["tools"] - output_dir = Dir('#bin').abspath - editor_tools_dir = os.path.join(output_dir, 'GodotSharp', 'Tools') + output_dir = Dir("#bin").abspath + editor_tools_dir = os.path.join(output_dir, "GodotSharp", "Tools") - target_filenames = ['GodotTools.dll'] + target_filenames = ["GodotTools.dll"] - if env_mono['target'] == 'debug': - target_filenames += ['GodotTools.pdb'] + if env_mono["target"] == "debug": + target_filenames += ["GodotTools.pdb"] targets = [os.path.join(editor_tools_dir, filename) for filename in target_filenames] diff --git a/modules/mono/build_scripts/make_android_mono_config.py b/modules/mono/build_scripts/make_android_mono_config.py index 0afd939c57..d276d7d886 100644 --- a/modules/mono/build_scripts/make_android_mono_config.py +++ b/modules/mono/build_scripts/make_android_mono_config.py @@ -1,24 +1,24 @@ - def generate_compressed_config(config_src, output_dir): import os.path - from compat import byte_to_str # Source file - with open(os.path.join(output_dir, 'android_mono_config.gen.cpp'), 'w') as cpp: - with open(config_src, 'rb') as f: + 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 + buf = zlib.compress(buf) compr_size = len(buf) - bytes_seq_str = '' + bytes_seq_str = "" for i, buf_idx in enumerate(range(compr_size)): if i > 0: - bytes_seq_str += ', ' - bytes_seq_str += byte_to_str(buf[buf_idx]) + bytes_seq_str += ", " + bytes_seq_str += str(buf[buf_idx]) - cpp.write('''/* THIS FILE IS GENERATED DO NOT EDIT */ + cpp.write( + """/* THIS FILE IS GENERATED DO NOT EDIT */ #include "android_mono_config.h" #ifdef ANDROID_ENABLED @@ -49,4 +49,6 @@ String get_godot_android_mono_config() { } #endif // ANDROID_ENABLED -''' % (compr_size, decompr_size, bytes_seq_str)) +""" + % (compr_size, decompr_size, bytes_seq_str) + ) diff --git a/modules/mono/build_scripts/mono_configure.py b/modules/mono/build_scripts/mono_configure.py index 9a6198f13a..23f01b3cca 100644 --- a/modules/mono/build_scripts/mono_configure.py +++ b/modules/mono/build_scripts/mono_configure.py @@ -5,178 +5,230 @@ import subprocess from SCons.Script import Dir, Environment -if os.name == 'nt': +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' + "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_file_in_dir(directory, files, prefix='', extension=''): - if not extension.startswith('.'): - extension = '.' + extension - for curfile in files: - if os.path.isfile(os.path.join(directory, prefix + curfile + extension)): - return curfile - return '' - - -def copy_file(src_dir, dst_dir, name): + 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, name) + 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) - copy(src_path, 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', 'x11', 'server', 'uwp', 'haiku'] + return platform in ["windows", "osx", "linuxbsd", "server", "uwp", "haiku"] def is_unix_like(platform): - return platform in ['osx', 'x11', 'server', 'android', 'haiku'] + return platform in ["osx", "linuxbsd", "server", "android", "haiku", "iphone"] def module_supports_tools_on(platform): - return platform not in ['android', 'javascript'] + 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'), + 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')): + if os.path.isfile(os.path.join(hint_dir, "driver.c")): return hint_dir - return '' + return "" def configure(env, env_mono): - bits = env['bits'] - is_android = env['platform'] == 'android' - is_javascript = env['platform'] == 'javascript' + 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"] - tools_enabled = env['tools'] - mono_static = env['mono_static'] - copy_mono_root = env['copy_mono_root'] + tools_enabled = env["tools"] + mono_static = env["mono_static"] + copy_mono_root = env["copy_mono_root"] - mono_prefix = env['mono_prefix'] + mono_prefix = env["mono_prefix"] - mono_lib_names = ['mono-2.0-sgen', 'monosgen-2.0'] + mono_lib_names = ["mono-2.0-sgen", "monosgen-2.0"] - is_travis = os.environ.get('TRAVIS') == 'true' + is_travis = os.environ.get("TRAVIS") == "true" if is_travis: # Travis CI may have a Mono version lower than 5.12 - env_mono.Append(CPPDEFINES=['NO_PENDING_EXCEPTIONS']) + env_mono.Append(CPPDEFINES=["NO_PENDING_EXCEPTIONS"]) - 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 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']): + 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') + raise RuntimeError("This module does not currently support building for this platform with tools enabled") if is_android and mono_static: - # Android: 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 - raise RuntimeError('Statically linking Mono is not currently supported on this platform') + # 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"] - if is_javascript: - mono_static = True + # Static AOT is only supported on the root domain + mono_single_appdomain = mono_aot_static - 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") + if mono_single_appdomain: + env_mono.Append(CPPDEFINES=["GD_MONO_SINGLE_APPDOMAIN"]) - if env['platform'] == 'windows': + if (env["tools"] or env["target"] != "release") and not mono_single_appdomain: + env_mono.Append(CPPDEFINES=["GD_MONO_HOT_RELOAD"]) + + if env["platform"] == "windows": mono_root = mono_prefix - if not mono_root and os.name == 'nt': + 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") + raise RuntimeError( + "Mono installation directory not found; specify one manually with the 'mono_prefix' SCons parameter" + ) - print('Found Mono root directory: ' + mono_root) + print("Found Mono root directory: " + mono_root) - mono_lib_path = os.path.join(mono_root, 'lib') + 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')) + env_mono.Prepend(CPPPATH=os.path.join(mono_root, "include", "mono-2.0")) + + lib_suffixes = [".lib"] - lib_suffix = Environment()['LIBSUFFIX'] + 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' + mono_static_lib_name = "libmono-static-sgen" else: - mono_static_lib_name = 'libmonosgen-2.0' + mono_static_lib_name = "libmonosgen-2.0" - if not os.path.isfile(os.path.join(mono_lib_path, mono_static_lib_name + lib_suffix)): - raise RuntimeError('Could not find static mono library in: ' + mono_lib_path) + 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_name + lib_suffix) + env.Append(LINKFLAGS=mono_static_lib_file) - env.Append(LINKFLAGS='Mincore' + lib_suffix) - env.Append(LINKFLAGS='msvcrt' + lib_suffix) - env.Append(LINKFLAGS='LIBCMT' + lib_suffix) - env.Append(LINKFLAGS='Psapi' + lib_suffix) + env.Append(LINKFLAGS="Mincore.lib") + env.Append(LINKFLAGS="msvcrt.lib") + env.Append(LINKFLAGS="LIBCMT.lib") + env.Append(LINKFLAGS="Psapi.lib") else: - env.Append(LINKFLAGS=os.path.join(mono_lib_path, mono_static_lib_name + lib_suffix)) + 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']) + env.Append(LIBS=["psapi"]) + env.Append(LIBS=["version"]) else: - mono_lib_name = find_file_in_dir(mono_lib_path, mono_lib_names, extension=lib_suffix) + mono_lib_name = find_name_in_dir_files( + mono_lib_path, mono_lib_names, prefixes=["", "lib"], extensions=lib_suffixes + ) if not mono_lib_name: - raise RuntimeError('Could not find mono library in: ' + mono_lib_path) + raise RuntimeError("Could not find mono library in: " + mono_lib_path) if env.msvc: - env.Append(LINKFLAGS=mono_lib_name + lib_suffix) + env.Append(LINKFLAGS=mono_lib_name + ".lib") else: env.Append(LIBS=[mono_lib_name]) - mono_bin_path = os.path.join(mono_root, 'bin') + mono_bin_path = os.path.join(mono_root, "bin") - mono_dll_name = find_file_in_dir(mono_bin_path, mono_lib_names, extension='.dll') + mono_dll_file = find_file_in_dir(mono_bin_path, mono_lib_names, prefixes=["", "lib"], extensions=[".dll"]) - if not mono_dll_name: - raise RuntimeError('Could not find mono shared library in: ' + mono_bin_path) + 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_name + '.dll') + copy_file(mono_bin_path, "#bin", mono_dll_file) else: - is_apple = env['platform'] in ['osx', 'iphone'] + is_apple = env["platform"] in ["osx", "iphone"] + is_macos = is_apple and not is_ios - sharedlib_ext = '.dylib' if is_apple else '.so' + sharedlib_ext = ".dylib" if is_apple else ".so" mono_root = mono_prefix - mono_lib_path = '' - mono_so_name = '' + mono_lib_path = "" + mono_so_file = "" - if not mono_root and (is_android or is_javascript): - raise RuntimeError("Mono installation directory not found; specify one manually with the 'mono_prefix' SCons parameter") + 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_apple: + 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'] + 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 @@ -187,126 +239,165 @@ def configure(env, env_mono): 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") + 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) + print("Found Mono root directory: " + mono_root) - mono_lib_path = os.path.join(mono_root, 'lib') + 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')) + env_mono.Prepend(CPPPATH=os.path.join(mono_root, "include", "mono-2.0")) - mono_lib = find_file_in_dir(mono_lib_path, mono_lib_names, prefix='lib', extension='.a') + 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) + raise RuntimeError("Could not find mono library in: " + mono_lib_path) - env_mono.Append(CPPDEFINES=['_REENTRANT']) + env_mono.Append(CPPDEFINES=["_REENTRANT"]) if mono_static: - env.Append(LINKFLAGS=['-rdynamic']) + env.Append(LINKFLAGS=["-rdynamic"]) - mono_lib_file = os.path.join(mono_lib_path, 'lib' + mono_lib + '.a') + mono_lib_file = os.path.join(mono_lib_path, "lib" + mono_lib + ".a") if is_apple: - env.Append(LINKFLAGS=['-Wl,-force_load,' + mono_lib_file]) + 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']) + 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']) + env.Append(LIBS=["mono-icall-table", "mono-native", "mono-ilgen", "mono-ee-interp"]) - wasm_src_dir = os.path.join(mono_root, 'src') + 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') + 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') - ]) + 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_apple: - env.Append(LIBS=['iconv', 'pthread']) + if is_macos: + env.Append(LIBS=["iconv", "pthread"]) elif is_android: - pass # Nothing + 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']) + env.Append(LIBS=["m", "rt", "dl", "pthread"]) else: - env.Append(LIBS=['m', 'rt', 'dl', 'pthread']) + env.Append(LIBS=["m", "rt", "dl", "pthread"]) if not mono_static: - mono_so_name = find_file_in_dir(mono_lib_path, mono_lib_names, prefix='lib', extension=sharedlib_ext) + mono_so_file = find_file_in_dir( + mono_lib_path, mono_lib_names, prefixes=["lib"], extensions=[sharedlib_ext] + ) - if not mono_so_name: - raise RuntimeError('Could not find mono shared library in: ' + mono_lib_path) - - copy_file(mono_lib_path, '#bin', 'lib' + mono_so_name + 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') + 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') + 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') + 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_file_in_dir(hint_dir, mono_lib_names, prefix='lib', extension=sharedlib_ext) - if name_found: + 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_name = name_found + mono_so_file = file_found break - if not mono_so_name: - raise RuntimeError('Could not find mono shared library in: ' + str(tmpenv['LIBPATH'])) + 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, 'lib' + mono_so_name + sharedlib_ext) + 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 is_desktop(env["platform"]): if not mono_root: - mono_root = subprocess.check_output(['pkg-config', 'mono-2', '--variable=prefix']).decode('utf8').strip() + 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/') + 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 + 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() + mono_root = subprocess.check_output(["pkg-config", "mono-2", "--variable=prefix"]).decode("utf8").strip() if tools_enabled: - copy_mono_root_files(env, mono_root) + copy_mono_root_files(env, mono_root) else: print("Ignoring option: 'copy_mono_root'; only available for builds with 'tools' enabled.") @@ -314,26 +405,26 @@ def configure(env, env_mono): def make_template_dir(env, mono_root): from shutil import rmtree - platform = env['platform'] - target = env['target'] + platform = env["platform"] + target = env["target"] - template_dir_name = '' + template_dir_name = "" assert is_desktop(platform) - template_dir_name = 'data.mono.%s.%s.%s' % (platform, env['bits'], target) + template_dir_name = "data.mono.%s.%s.%s" % (platform, env["bits"], target) - output_dir = Dir('#bin').abspath + 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') + 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 + rmtree(template_mono_root_dir) # Clean first # Copy etc/mono/ - template_mono_config_dir = os.path.join(template_mono_root_dir, '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 @@ -347,18 +438,18 @@ def copy_mono_root_files(env, mono_root): from shutil import rmtree if not mono_root: - raise RuntimeError('Mono installation directory not found') + raise RuntimeError("Mono installation directory not found") - output_dir = Dir('#bin').abspath - editor_mono_root_dir = os.path.join(output_dir, 'GodotSharp', 'Mono') + 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 + 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']) + 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 @@ -366,20 +457,20 @@ def copy_mono_root_files(env, mono_root): # Copy framework assemblies - mono_framework_dir = os.path.join(mono_root, 'lib', 'mono', '4.5') - mono_framework_facades_dir = os.path.join(mono_framework_dir, 'Facades') + mono_framework_dir = 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') + 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')): + 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')): + for assembly in glob(os.path.join(mono_framework_facades_dir, "*.dll")): copy(assembly, editor_mono_framework_facades_dir) @@ -391,28 +482,28 @@ def copy_mono_etc_dir(mono_root, target_mono_config_dir, platform): 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') + mono_etc_dir = os.path.join(mono_root, "etc", "mono") if not os.path.isdir(mono_etc_dir): - 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')] + 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') + 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')) + 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, '*')): + for file in glob(os.path.join(mono_etc_dir, "*")): if os.path.isfile(file): copy(file, target_mono_config_dir) @@ -424,48 +515,66 @@ def copy_mono_shared_libs(env, mono_root, target_mono_root_dir): if os.path.isfile(src): copy(src, dst) - platform = env['platform'] + 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 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_name = find_file_in_dir(src_mono_bin_dir, ['MonoPosixHelper', 'libMonoPosixHelper'], extension='.dll') - copy(os.path.join(src_mono_bin_dir, mono_posix_helper_name + '.dll'), os.path.join(target_mono_bin_dir, 'MonoPosixHelper.dll')) + 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') + 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') + 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' - ]] + 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' - ]] + 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) + 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_file_in_dir(hint_dir, mono_lib_names, prefix='lib', extension=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 '' + 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 index b2c48f0a61..3090a4759a 100644 --- a/modules/mono/build_scripts/mono_reg_utils.py +++ b/modules/mono/build_scripts/mono_reg_utils.py @@ -1,21 +1,16 @@ import os import platform -from compat import decode_utf8 - -if os.name == 'nt': +if os.name == "nt": import sys - if sys.version_info < (3,): - import _winreg as winreg - else: - import winreg + import winreg def _reg_open_key(key, subkey): try: return winreg.OpenKey(key, subkey) except (WindowsError, OSError): - if platform.architecture()[0] == '32bit': + if platform.architecture()[0] == "32bit": bitness_sam = winreg.KEY_WOW64_64KEY else: bitness_sam = winreg.KEY_WOW64_32KEY @@ -25,12 +20,12 @@ def _reg_open_key(key, subkey): def _reg_open_key_bits(key, subkey, bits): sam = winreg.KEY_READ - if platform.architecture()[0] == '32bit': - if bits == '64': + 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': + if bits == "32": # Force 64bit process to search in 32bit registry sam |= winreg.KEY_WOW64_32KEY @@ -40,7 +35,7 @@ def _reg_open_key_bits(key, subkey, bits): 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] + value = winreg.QueryValueEx(hKey, "SdkInstallRoot")[0] return value except (WindowsError, OSError): return None @@ -49,70 +44,70 @@ def _find_mono_in_reg(subkey, bits): 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] + default_clr = winreg.QueryValueEx(hKey, "DefaultCLR")[0] if default_clr: - return _find_mono_in_reg(subkey + '\\' + default_clr, bits) + return _find_mono_in_reg(subkey + "\\" + default_clr, bits) return None except (WindowsError, EnvironmentError): return None def find_mono_root_dir(bits): - root_dir = _find_mono_in_reg(r'SOFTWARE\Mono', 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) + root_dir = _find_mono_in_reg_old(r"SOFTWARE\Novell\Mono", bits) if root_dir is not None: return str(root_dir) - return '' + return "" def find_msbuild_tools_path_reg(): import subprocess - vswhere = os.getenv('PROGRAMFILES(X86)') + vswhere = os.getenv("PROGRAMFILES(X86)") if not vswhere: - vswhere = os.getenv('PROGRAMFILES') - vswhere += r'\Microsoft Visual Studio\Installer\vswhere.exe' + vswhere = os.getenv("PROGRAMFILES") + vswhere += r"\Microsoft Visual Studio\Installer\vswhere.exe" - vswhere_args = ['-latest', '-products', '*', '-requires', 'Microsoft.Component.MSBuild'] + vswhere_args = ["-latest", "-products", "*", "-requires", "Microsoft.Component.MSBuild"] try: lines = subprocess.check_output([vswhere] + vswhere_args).splitlines() for line in lines: - parts = decode_utf8(line).split(':', 1) + parts = line.decode("utf-8").split(":", 1) - if len(parts) < 2 or parts[0] != 'installationPath': + if len(parts) < 2 or parts[0] != "installationPath": continue val = parts[1].strip() if not val: - raise ValueError('Value of `installationPath` entry is empty') + 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') + 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') + return os.path.join(val, "MSBuild\\15.0\\Bin") - raise ValueError('Cannot find `installationPath` entry') + raise ValueError("Cannot find `installationPath` entry") except ValueError as e: - print('Error reading output from vswhere: ' + e.message) + print("Error reading output from vswhere: " + e.message) except WindowsError: - pass # Fine, vswhere not found + pass # Fine, vswhere not found except (subprocess.CalledProcessError, OSError): pass # Try to find 14.0 in the Registry try: - subkey = r'SOFTWARE\Microsoft\MSBuild\ToolsVersions\14.0' + 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] + value = winreg.QueryValueEx(hKey, "MSBuildToolsPath")[0] return value except (WindowsError, OSError): - return '' + return "" diff --git a/modules/mono/build_scripts/solution_builder.py b/modules/mono/build_scripts/solution_builder.py index d1529a64d2..db6b4ff7aa 100644 --- a/modules/mono/build_scripts/solution_builder.py +++ b/modules/mono/build_scripts/solution_builder.py @@ -1,4 +1,3 @@ - import os @@ -8,35 +7,38 @@ verbose = False def find_nuget_unix(): import os - if 'NUGET_PATH' in os.environ: - hint_path = os.environ['NUGET_PATH'] + if "NUGET_PATH" in os.environ: + hint_path = os.environ["NUGET_PATH"] if os.path.isfile(hint_path) and os.access(hint_path, os.X_OK): return hint_path - hint_path = os.path.join(hint_path, 'nuget') + hint_path = os.path.join(hint_path, "nuget") if os.path.isfile(hint_path) and os.access(hint_path, os.X_OK): return hint_path import os.path import sys - hint_dirs = ['/opt/novell/mono/bin'] - if sys.platform == 'darwin': - hint_dirs = ['/Library/Frameworks/Mono.framework/Versions/Current/bin', '/usr/local/var/homebrew/linked/mono/bin'] + hint_dirs + hint_dirs = ["/opt/novell/mono/bin"] + if sys.platform == "darwin": + hint_dirs = [ + "/Library/Frameworks/Mono.framework/Versions/Current/bin", + "/usr/local/var/homebrew/linked/mono/bin", + ] + hint_dirs for hint_dir in hint_dirs: - hint_path = os.path.join(hint_dir, 'nuget') + hint_path = os.path.join(hint_dir, "nuget") if os.path.isfile(hint_path): return hint_path - elif os.path.isfile(hint_path + '.exe'): - return hint_path + '.exe' + elif os.path.isfile(hint_path + ".exe"): + return hint_path + ".exe" - for hint_dir in os.environ['PATH'].split(os.pathsep): + for hint_dir in os.environ["PATH"].split(os.pathsep): hint_dir = hint_dir.strip('"') - hint_path = os.path.join(hint_dir, 'nuget') + hint_path = os.path.join(hint_dir, "nuget") 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' + if os.path.isfile(hint_path + ".exe") and os.access(hint_path + ".exe", os.X_OK): + return hint_path + ".exe" return None @@ -44,30 +46,30 @@ def find_nuget_unix(): def find_nuget_windows(env): import os - if 'NUGET_PATH' in os.environ: - hint_path = os.environ['NUGET_PATH'] + if "NUGET_PATH" in os.environ: + hint_path = os.environ["NUGET_PATH"] if os.path.isfile(hint_path) and os.access(hint_path, os.X_OK): return hint_path - hint_path = os.path.join(hint_path, 'nuget.exe') + hint_path = os.path.join(hint_path, "nuget.exe") if os.path.isfile(hint_path) and os.access(hint_path, os.X_OK): return hint_path - from . mono_reg_utils import find_mono_root_dir + from .mono_reg_utils import find_mono_root_dir - mono_root = env['mono_prefix'] or find_mono_root_dir(env['bits']) + mono_root = env["mono_prefix"] or find_mono_root_dir(env["bits"]) if mono_root: - mono_bin_dir = os.path.join(mono_root, 'bin') - nuget_mono = os.path.join(mono_bin_dir, 'nuget.bat') + mono_bin_dir = os.path.join(mono_root, "bin") + nuget_mono = os.path.join(mono_bin_dir, "nuget.bat") if os.path.isfile(nuget_mono): return nuget_mono # Standalone NuGet - for hint_dir in os.environ['PATH'].split(os.pathsep): + for hint_dir in os.environ["PATH"].split(os.pathsep): hint_dir = hint_dir.strip('"') - hint_path = os.path.join(hint_dir, 'nuget.exe') + hint_path = os.path.join(hint_dir, "nuget.exe") if os.path.isfile(hint_path) and os.access(hint_path, os.X_OK): return hint_path @@ -78,52 +80,55 @@ def find_msbuild_unix(filename): import os.path import sys - hint_dirs = ['/opt/novell/mono/bin'] - if sys.platform == 'darwin': - hint_dirs = ['/Library/Frameworks/Mono.framework/Versions/Current/bin', '/usr/local/var/homebrew/linked/mono/bin'] + hint_dirs + hint_dirs = ["/opt/novell/mono/bin"] + if sys.platform == "darwin": + hint_dirs = [ + "/Library/Frameworks/Mono.framework/Versions/Current/bin", + "/usr/local/var/homebrew/linked/mono/bin", + ] + hint_dirs for hint_dir in hint_dirs: hint_path = os.path.join(hint_dir, filename) if os.path.isfile(hint_path): return hint_path - elif os.path.isfile(hint_path + '.exe'): - return hint_path + '.exe' + elif os.path.isfile(hint_path + ".exe"): + return hint_path + ".exe" - for hint_dir in os.environ['PATH'].split(os.pathsep): + for hint_dir in os.environ["PATH"].split(os.pathsep): hint_dir = hint_dir.strip('"') hint_path = os.path.join(hint_dir, filename) 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' + 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 + 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']) + mono_root = env["mono_prefix"] or find_mono_root_dir(env["bits"]) if not mono_root: - raise RuntimeError('Cannot find mono root directory') + 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') + 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'), {}) + 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') + "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) @@ -132,7 +137,7 @@ def find_msbuild_windows(env): 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]) + return " ".join([arg if not " " in arg else '"%s"' % arg for arg in cmd_args]) args = [command] + args @@ -143,6 +148,7 @@ def run_command(command, args, env_override=None, name=None): print("Running '%s': %s" % (name, cmd_args_to_str(args))) import subprocess + try: if env_override is None: subprocess.check_call(args) @@ -154,61 +160,61 @@ def run_command(command, args, env_override=None, name=None): def nuget_restore(env, *args): global verbose - verbose = env['verbose'] + verbose = env["verbose"] # Find NuGet - nuget_path = find_nuget_windows(env) if os.name == 'nt' else find_nuget_unix() + nuget_path = find_nuget_windows(env) if os.name == "nt" else find_nuget_unix() if nuget_path is None: - raise RuntimeError('Cannot find NuGet executable') + raise RuntimeError("Cannot find NuGet executable") - print('NuGet path: ' + nuget_path) + print("NuGet path: " + nuget_path) # Do NuGet restore - run_command(nuget_path, ['restore'] + list(args), name='nuget restore') + run_command(nuget_path, ["restore"] + list(args), name="nuget restore") def build_solution(env, solution_path, build_config, extra_msbuild_args=[]): global verbose - verbose = env['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'] + if "PLATFORM" in msbuild_env: + del msbuild_env["PLATFORM"] # Find MSBuild - if os.name == 'nt': + if os.name == "nt": msbuild_info = find_msbuild_windows(env) if msbuild_info is None: - raise RuntimeError('Cannot find MSBuild executable') + raise RuntimeError("Cannot find MSBuild executable") msbuild_path = msbuild_info[0] msbuild_env.update(msbuild_info[1]) else: - msbuild_path = find_msbuild_unix('msbuild') + msbuild_path = find_msbuild_unix("msbuild") if msbuild_path is None: - xbuild_fallback = env['xbuild_fallback'] + xbuild_fallback = env["xbuild_fallback"] - if xbuild_fallback and os.name == 'nt': - print('Option \'xbuild_fallback\' not supported on Windows') + if xbuild_fallback and os.name == "nt": + print("Option 'xbuild_fallback' not supported on Windows") xbuild_fallback = False if xbuild_fallback: - print('Cannot find MSBuild executable, trying with xbuild') - print('Warning: xbuild is deprecated') + print("Cannot find MSBuild executable, trying with xbuild") + print("Warning: xbuild is deprecated") - msbuild_path = find_msbuild_unix('xbuild') + msbuild_path = find_msbuild_unix("xbuild") if msbuild_path is None: - raise RuntimeError('Cannot find xbuild executable') + raise RuntimeError("Cannot find xbuild executable") else: - raise RuntimeError('Cannot find MSBuild executable') + raise RuntimeError("Cannot find MSBuild executable") - print('MSBuild path: ' + msbuild_path) + print("MSBuild path: " + msbuild_path) # Build solution - msbuild_args = [solution_path, '/p:Configuration=' + build_config] + msbuild_args = [solution_path, "/p:Configuration=" + build_config] msbuild_args += extra_msbuild_args - run_command(msbuild_path, msbuild_args, env_override=msbuild_env, name='msbuild') + run_command(msbuild_path, msbuild_args, env_override=msbuild_env, name="msbuild") |