solution_builder.py 4.6 KB

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