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")