diff options
author | Roman Lacko <backup.rlacko@gmail.com> | 2013-04-25 12:49:09 +0200 |
---|---|---|
committer | Roman Lacko <backup.rlacko@gmail.com> | 2013-04-25 12:49:09 +0200 |
commit | 5601a57afc1742e007bfa6150ef04903163d4f64 (patch) | |
tree | 693cdc9566b5823b0442acc198412b29debd813b | |
parent | f9933ac4fb362e68acafeb725db499567e3d3747 (diff) |
Introduce option --msvc-version to specify version of MSVC compiler. Use that optition to get MSVC environment variables.
-rw-r--r-- | setup.py | 23 | ||||
-rw-r--r-- | utils.py | 69 |
2 files changed, 87 insertions, 5 deletions
@@ -82,6 +82,8 @@ from utils import copydir from utils import run_process from utils import has_option from utils import option_value +from utils import find_vcvarsall +from utils import get_environment_from_batch_command # Declare options OPTION_DEBUG = has_option("debug") @@ -94,6 +96,7 @@ OPTION_VERSION = option_value("version") OPTION_LISTVERSIONS = has_option("list-versions") OPTION_MAKESPEC = option_value("make-spec") OPTION_IGNOREGIT = has_option("ignore-git") +OPTION_MSVCVERSION = option_value("msvc-version") if OPTION_QMAKE is None: OPTION_QMAKE = find_executable("qmake") @@ -106,6 +109,13 @@ if sys.platform == "win32": if not OPTION_MAKESPEC in ["msvc", "mingw"]: print("Invalid option --make-spec. Available values are %s" % (["msvc", "mingw"])) sys.exit(1) + if OPTION_MSVCVERSION: + if OPTION_MAKESPEC != "msvc": + print("Option --msvc-version can be used only with option --make-spec=msvc") + sys.exit(1) + if not OPTION_MSVCVERSION in ["9.0", "10.0", "11.0"]: + print("Invalid option --msvc-version. Available values are %s" % (["9.0", "10.0", "11.0"])) + sys.exit(1) else: if OPTION_MAKESPEC is None: OPTION_MAKESPEC = "make" @@ -235,8 +245,21 @@ class pyside_build(_build): self.py_version = None self.build_type = "Release" self.qtinfo = None + self.msvc_env = None def run(self): + # Try to get MSVC env + if sys.platform == "win32" and OPTION_MSVCVERSION: + log.info("Searching vcvarsall.bat for MSVC version %s" % OPTION_MSVCVERSION) + msvc_version = float(OPTION_MSVCVERSION) + vcvarsall_path = find_vcvarsall(msvc_version) + if not vcvarsall_path: + raise DistutilsSetupError( + "Failed to find the vcvarsall.bat for MSVC version %s." % OPTION_MSVCVERSION) + log.info("Found %s" % vcvarsall_path) + vcvarsall_cmd = ["call", vcvarsall_path] + self.msvc_env = get_environment_from_batch_command(vcvarsall_path) + # Check env make_path = None make_generator = None @@ -6,17 +6,17 @@ import time import shutil import subprocess import fnmatch +import itertools +import popenasync + +from distutils.spawn import spawn +from distutils.spawn import DistutilsExecError try: WindowsError except NameError: WindowsError = None -from distutils.spawn import spawn -from distutils.spawn import DistutilsExecError - -import popenasync - def has_option(name): try: @@ -53,6 +53,12 @@ def filter_match(name, patterns): return False +def find_vcvarsall(version): + from distutils import msvc9compiler + vcvarsall_path = msvc9compiler.find_vcvarsall(version) + return vcvarsall_path + + def copyfile(src, dst, logger=None, force=True, vars=None, subst_content=False): if vars is not None: src = src.format(**vars) @@ -217,3 +223,56 @@ def run_process(args, logger=None): proc.wait() return proc.returncode + + +def get_environment_from_batch_command(env_cmd, initial=None): + """ + Take a command (either a single command or list of arguments) + and return the environment created after running that command. + Note that if the command must be a batch file or .cmd file, or the + changes to the environment will not be captured. + + If initial is supplied, it is used as the initial environment passed + to the child process. + """ + + def validate_pair(ob): + try: + if not (len(ob) == 2): + print("Unexpected result: %s" % ob) + raise ValueError + except: + return False + return True + + def consume(iter): + try: + while True: next(iter) + except StopIteration: + pass + + if not isinstance(env_cmd, (list, tuple)): + env_cmd = [env_cmd] + # construct the command that will alter the environment + env_cmd = subprocess.list2cmdline(env_cmd) + # create a tag so we can tell in the output when the proc is done + tag = 'Done running command' + # construct a cmd.exe command to do accomplish this + cmd = 'cmd.exe /s /c "{env_cmd} && echo "{tag}" && set"'.format(**vars()) + # launch the process + proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, env=initial) + # parse the output sent to stdout + lines = proc.stdout + # consume whatever output occurs until the tag is reached + consume(itertools.takewhile(lambda l: tag not in l, lines)) + # define a way to handle each KEY=VALUE line + handle_line = lambda l: l.rstrip().split('=',1) + # parse key/values into pairs + pairs = map(handle_line, lines) + # make sure the pairs are valid + valid_pairs = filter(validate_pair, pairs) + # construct a dictionary of the pairs + result = dict(valid_pairs) + # let the process finish + proc.communicate() + return result |