godot/modules/mono/build_scripts/solution_builder.py
Ignacio Etcheverry 270af6fa08 Re-write mono module editor code in C#
Make the build system automatically build the C# Api assemblies to be shipped with the editor.
Make the editor, editor player and debug export templates use Api assemblies built with debug symbols.
Always run MSBuild to build the editor tools and Api assemblies when building Godot.
Several bugs fixed related to assembly hot reloading and restoring state.
Fix StringExtensions internal calls not being registered correctly, resulting in MissingMethodException.
2019-07-05 09:38:23 +02:00

219 lines
7.1 KiB
Python

import os
verbose = False
def find_nuget_unix():
import os
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')
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
for hint_dir in hint_dirs:
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'
for hint_dir in os.environ['PATH'].split(os.pathsep):
hint_dir = hint_dir.strip('"')
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'
return None
def find_nuget_windows(env):
import os
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')
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
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')
if os.path.isfile(nuget_mono):
return nuget_mono
# Standalone NuGet
for hint_dir in os.environ['PATH'].split(os.pathsep):
hint_dir = hint_dir.strip('"')
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
return None
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
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'
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'
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')
framework_path = os.path.join(mono_root, 'lib', 'mono', '4.5')
mono_bin_dir = os.path.join(mono_root, 'bin')
msbuild_mono = os.path.join(mono_bin_dir, 'msbuild.bat')
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, framework_path, mono_msbuild_env)
msbuild_tools_path = find_msbuild_tools_path_reg()
if msbuild_tools_path:
return (os.path.join(msbuild_tools_path, 'MSBuild.exe'), framework_path, {})
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 nuget_restore(env, *args):
global verbose
verbose = env['verbose']
# Find NuGet
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')
print('NuGet path: ' + nuget_path)
# Do 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']
framework_path = ''
msbuild_env = os.environ.copy()
# Needed when running from Developer Command Prompt for VS
if 'PLATFORM' in msbuild_env:
del msbuild_env['PLATFORM']
# 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]
framework_path = msbuild_info[1]
msbuild_env.update(msbuild_info[2])
else:
msbuild_path = find_msbuild_unix('msbuild')
if msbuild_path is None:
xbuild_fallback = env['xbuild_fallback']
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')
msbuild_path = find_msbuild_unix('xbuild')
if msbuild_path is None:
raise RuntimeError('Cannot find xbuild executable')
else:
raise RuntimeError('Cannot find MSBuild executable')
print('MSBuild path: ' + msbuild_path)
# Build solution
msbuild_args = [solution_path, '/p:Configuration=' + build_config]
msbuild_args += ['/p:FrameworkPathOverride=' + framework_path] if framework_path else []
msbuild_args += extra_msbuild_args
run_command(msbuild_path, msbuild_args, env_override=msbuild_env, name='msbuild')