solution_builder.py 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. import os
  2. verbose = False
  3. def find_msbuild_unix(filename):
  4. import os.path
  5. import sys
  6. hint_dirs = []
  7. if sys.platform == "darwin":
  8. hint_dirs[:0] = [
  9. "/Library/Frameworks/Mono.framework/Versions/Current/bin",
  10. "/usr/local/var/homebrew/linked/mono/bin",
  11. ]
  12. for hint_dir in hint_dirs:
  13. hint_path = os.path.join(hint_dir, "msbuild")
  14. if os.path.isfile(hint_path):
  15. return hint_path
  16. elif os.path.isfile(hint_path + '.exe'):
  17. return hint_path + '.exe'
  18. for hint_dir in os.environ['PATH'].split(os.pathsep):
  19. hint_dir = hint_dir.strip('"')
  20. hint_path = os.path.join(hint_dir, "msbuild")
  21. if os.path.isfile(hint_path) and os.access(hint_path, os.X_OK):
  22. return hint_path
  23. if os.path.isfile(hint_path + '.exe') and os.access(hint_path + '.exe', os.X_OK):
  24. return hint_path + '.exe'
  25. return None
  26. def find_msbuild_windows(env):
  27. from . mono_reg_utils import find_mono_root_dir, find_msbuild_tools_path_reg
  28. mono_root = env['mono_prefix'] or find_mono_root_dir(env['bits'])
  29. if not mono_root:
  30. raise RuntimeError('Cannot find mono root directory')
  31. mono_bin_dir = os.path.join(mono_root, 'bin')
  32. msbuild_mono = os.path.join(mono_bin_dir, 'msbuild.bat')
  33. msbuild_tools_path = find_msbuild_tools_path_reg()
  34. if msbuild_tools_path:
  35. return (os.path.join(msbuild_tools_path, 'MSBuild.exe'), {})
  36. if os.path.isfile(msbuild_mono):
  37. # The (Csc/Vbc/Fsc)ToolExe environment variables are required when
  38. # building with Mono's MSBuild. They must point to the batch files
  39. # in Mono's bin directory to make sure they are executed with Mono.
  40. mono_msbuild_env = {
  41. 'CscToolExe': os.path.join(mono_bin_dir, 'csc.bat'),
  42. 'VbcToolExe': os.path.join(mono_bin_dir, 'vbc.bat'),
  43. 'FscToolExe': os.path.join(mono_bin_dir, 'fsharpc.bat')
  44. }
  45. return (msbuild_mono, mono_msbuild_env)
  46. return None
  47. def run_command(command, args, env_override=None, name=None):
  48. def cmd_args_to_str(cmd_args):
  49. return ' '.join([arg if not ' ' in arg else '"%s"' % arg for arg in cmd_args])
  50. args = [command] + args
  51. if name is None:
  52. name = os.path.basename(command)
  53. if verbose:
  54. print("Running '%s': %s" % (name, cmd_args_to_str(args)))
  55. import subprocess
  56. try:
  57. if env_override is None:
  58. subprocess.check_call(args)
  59. else:
  60. subprocess.check_call(args, env=env_override)
  61. except subprocess.CalledProcessError as e:
  62. raise RuntimeError("'%s' exited with error code: %s" % (name, e.returncode))
  63. def nuget_restore(env, *args):
  64. global verbose
  65. verbose = env['verbose']
  66. # Do NuGet restore
  67. run_command(nuget_path, ['restore'] + list(args), name='nuget restore')
  68. def build_solution(env, solution_path, build_config, extra_msbuild_args=[], restore=False):
  69. global verbose
  70. verbose = env['verbose']
  71. msbuild_env = os.environ.copy()
  72. # Needed when running from Developer Command Prompt for VS
  73. if 'PLATFORM' in msbuild_env:
  74. del msbuild_env['PLATFORM']
  75. # Find MSBuild
  76. if os.name == 'nt':
  77. msbuild_info = find_msbuild_windows(env)
  78. if msbuild_info is None:
  79. raise RuntimeError('Cannot find MSBuild executable')
  80. msbuild_path = msbuild_info[0]
  81. msbuild_env.update(msbuild_info[1])
  82. else:
  83. msbuild_path = find_msbuild_unix('msbuild')
  84. if msbuild_path is None:
  85. raise RuntimeError("Cannot find MSBuild executable")
  86. print('MSBuild path: ' + msbuild_path)
  87. # Build solution
  88. targets = ["Build"]
  89. if restore:
  90. targets.insert(0, "Restore")
  91. msbuild_args = [solution_path, "/t:%s" % ",".join(targets), "/p:Configuration=" + build_config]
  92. msbuild_args += extra_msbuild_args
  93. run_command(msbuild_path, msbuild_args, env_override=msbuild_env, name='msbuild')