aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoman Lacko <backup.rlacko@gmail.com>2013-04-25 12:49:09 +0200
committerRoman Lacko <backup.rlacko@gmail.com>2013-04-25 12:49:09 +0200
commit5601a57afc1742e007bfa6150ef04903163d4f64 (patch)
tree693cdc9566b5823b0442acc198412b29debd813b
parentf9933ac4fb362e68acafeb725db499567e3d3747 (diff)
Introduce option --msvc-version to specify version of MSVC compiler. Use that optition to get MSVC environment variables.
-rw-r--r--setup.py23
-rw-r--r--utils.py69
2 files changed, 87 insertions, 5 deletions
diff --git a/setup.py b/setup.py
index f84d47fdd..438dd9fae 100644
--- a/setup.py
+++ b/setup.py
@@ -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
diff --git a/utils.py b/utils.py
index 66f1eb457..669314add 100644
--- a/utils.py
+++ b/utils.py
@@ -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