Index: scons-2.0.1/engine/SCons/Tool/MSCommon/common.py |
=================================================================== |
--- scons-2.0.1/engine/SCons/Tool/MSCommon/common.py (revision 0) |
+++ scons-2.0.1/engine/SCons/Tool/MSCommon/common.py (revision 0) |
@@ -0,0 +1,240 @@ |
+# |
+# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 The SCons Foundation |
+# |
+# Permission is hereby granted, free of charge, to any person obtaining |
+# a copy of this software and associated documentation files (the |
+# "Software"), to deal in the Software without restriction, including |
+# without limitation the rights to use, copy, modify, merge, publish, |
+# distribute, sublicense, and/or sell copies of the Software, and to |
+# permit persons to whom the Software is furnished to do so, subject to |
+# the following conditions: |
+# |
+# The above copyright notice and this permission notice shall be included |
+# in all copies or substantial portions of the Software. |
+# |
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY |
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE |
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE |
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION |
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION |
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
+# |
+ |
+__revision__ = "src/engine/SCons/Tool/MSCommon/common.py 5134 2010/08/16 23:02:40 bdeegan" |
+ |
+__doc__ = """ |
+Common helper functions for working with the Microsoft tool chain. |
+""" |
+ |
+import copy |
+import os |
+import subprocess |
+import re |
+ |
+import SCons.Util |
+ |
+ |
+logfile = os.environ.get('SCONS_MSCOMMON_DEBUG') |
+if logfile == '-': |
+ def debug(x): |
+ print x |
+elif logfile: |
+ try: |
+ import logging |
+ except ImportError: |
+ debug = lambda x: open(logfile, 'a').write(x + '\n') |
+ else: |
+ logging.basicConfig(filename=logfile, level=logging.DEBUG) |
+ debug = logging.debug |
+else: |
+ debug = lambda x: None |
+ |
+ |
+_is_win64 = None |
+ |
+def is_win64(): |
+ """Return true if running on windows 64 bits. |
+ |
+ Works whether python itself runs in 64 bits or 32 bits.""" |
+ # Unfortunately, python does not provide a useful way to determine |
+ # if the underlying Windows OS is 32-bit or 64-bit. Worse, whether |
+ # the Python itself is 32-bit or 64-bit affects what it returns, |
+ # so nothing in sys.* or os.* help. |
+ |
+ # Apparently the best solution is to use env vars that Windows |
+ # sets. If PROCESSOR_ARCHITECTURE is not x86, then the python |
+ # process is running in 64 bit mode (on a 64-bit OS, 64-bit |
+ # hardware, obviously). |
+ # If this python is 32-bit but the OS is 64, Windows will set |
+ # ProgramW6432 and PROCESSOR_ARCHITEW6432 to non-null. |
+ # (Checking for HKLM\Software\Wow6432Node in the registry doesn't |
+ # work, because some 32-bit installers create it.) |
+ global _is_win64 |
+ if _is_win64 is None: |
+ # I structured these tests to make it easy to add new ones or |
+ # add exceptions in the future, because this is a bit fragile. |
+ _is_win64 = False |
+ if os.environ.get('PROCESSOR_ARCHITECTURE','x86') != 'x86': |
+ _is_win64 = True |
+ if os.environ.get('PROCESSOR_ARCHITEW6432'): |
+ _is_win64 = True |
+ if os.environ.get('ProgramW6432'): |
+ _is_win64 = True |
+ return _is_win64 |
+ |
+ |
+def read_reg(value): |
+ return SCons.Util.RegGetValue(SCons.Util.HKEY_LOCAL_MACHINE, value)[0] |
+ |
+def has_reg(value): |
+ """Return True if the given key exists in HKEY_LOCAL_MACHINE, False |
+ otherwise.""" |
+ try: |
+ SCons.Util.RegOpenKeyEx(SCons.Util.HKEY_LOCAL_MACHINE, value) |
+ ret = True |
+ except WindowsError: |
+ ret = False |
+ return ret |
+ |
+# Functions for fetching environment variable settings from batch files. |
+ |
+def normalize_env(env, keys, force=False): |
+ """Given a dictionary representing a shell environment, add the variables |
+ from os.environ needed for the processing of .bat files; the keys are |
+ controlled by the keys argument. |
+ |
+ It also makes sure the environment values are correctly encoded. |
+ |
+ If force=True, then all of the key values that exist are copied |
+ into the returned dictionary. If force=false, values are only |
+ copied if the key does not already exist in the copied dictionary. |
+ |
+ Note: the environment is copied.""" |
+ normenv = {} |
+ if env: |
+ for k in env.keys(): |
+ normenv[k] = copy.deepcopy(env[k]).encode('mbcs') |
+ |
+ for k in keys: |
+ if k in os.environ and (force or not k in normenv): |
+ normenv[k] = os.environ[k].encode('mbcs') |
+ |
+ return normenv |
+ |
+def get_output(vcbat, args = None, env = None): |
+ """Parse the output of given bat file, with given args.""" |
+ |
+ if env is None: |
+ # Create a blank environment, for use in launching the tools |
+ env = SCons.Environment.Environment(tools=[]) |
+ |
+ # TODO: This is a hard-coded list of the variables that (may) need |
+ # to be imported from os.environ[] for v[sc]*vars*.bat file |
+ # execution to work. This list should really be either directly |
+ # controlled by vc.py, or else derived from the common_tools_var |
+ # settings in vs.py. |
+ vars = [ |
+ 'COMSPEC', |
+ 'VS90COMNTOOLS', |
+ 'VS80COMNTOOLS', |
+ 'VS71COMNTOOLS', |
+ 'VS70COMNTOOLS', |
+ 'VS60COMNTOOLS', |
+ ] |
+ env['ENV'] = normalize_env(env['ENV'], vars, force=False) |
+ |
+ if args: |
+ debug("Calling '%s %s'" % (vcbat, args)) |
+ popen = SCons.Action._subproc(env, |
+ '"%s" %s & set' % (vcbat, args), |
+ stdin = 'devnull', |
+ stdout=subprocess.PIPE, |
+ stderr=subprocess.PIPE) |
+ else: |
+ debug("Calling '%s'" % vcbat) |
+ popen = SCons.Action._subproc(env, |
+ '"%s" & set' % vcbat, |
+ stdin = 'devnull', |
+ stdout=subprocess.PIPE, |
+ stderr=subprocess.PIPE) |
+ |
+ # Use the .stdout and .stderr attributes directly because the |
+ # .communicate() method uses the threading module on Windows |
+ # and won't work under Pythons not built with threading. |
+ stdout = popen.stdout.read() |
+ stderr = popen.stderr.read() |
+ if stderr: |
+ # TODO: find something better to do with stderr; |
+ # this at least prevents errors from getting swallowed. |
+ import sys |
+ sys.stderr.write(stderr) |
+ if popen.wait() != 0: |
+ raise IOError(stderr.decode("mbcs")) |
+ |
+ output = stdout.decode("mbcs") |
+ return output |
+ |
+def parse_output(output, keep = ("INCLUDE", "LIB", "LIBPATH", "PATH")): |
+ # dkeep is a dict associating key: path_list, where key is one item from |
+ # keep, and pat_list the associated list of paths |
+ |
+ dkeep = dict([(i, []) for i in keep]) |
+ |
+ # rdk will keep the regex to match the .bat file output line starts |
+ rdk = {} |
+ for i in keep: |
+ rdk[i] = re.compile('%s=(.*)' % i, re.I) |
+ |
+ def add_env(rmatch, key, dkeep=dkeep): |
+ plist = rmatch.group(1).split(os.pathsep) |
+ for p in plist: |
+ # Do not add empty paths (when a var ends with ;) |
+ if p: |
+ p = p.encode('mbcs') |
+ # XXX: For some reason, VC98 .bat file adds "" around the PATH |
+ # values, and it screws up the environment later, so we strip |
+ # it. |
+ p = p.strip('"') |
+ dkeep[key].append(p) |
+ |
+ for line in output.splitlines(): |
+ for k,v in rdk.items(): |
+ m = v.match(line) |
+ if m: |
+ add_env(m, k) |
+ |
+ return dkeep |
+ |
+# TODO(sgk): unused |
+def output_to_dict(output): |
+ """Given an output string, parse it to find env variables. |
+ |
+ Return a dict where keys are variables names, and values their content""" |
+ envlinem = re.compile(r'^([a-zA-z0-9]+)=([\S\s]*)$') |
+ parsedenv = {} |
+ for line in output.splitlines(): |
+ m = envlinem.match(line) |
+ if m: |
+ parsedenv[m.group(1)] = m.group(2) |
+ return parsedenv |
+ |
+# TODO(sgk): unused |
+def get_new(l1, l2): |
+ """Given two list l1 and l2, return the items in l2 which are not in l1. |
+ Order is maintained.""" |
+ |
+ # We don't try to be smart: lists are small, and this is not the bottleneck |
+ # is any case |
+ new = [] |
+ for i in l2: |
+ if i not in l1: |
+ new.append(i) |
+ |
+ return new |
+ |
+# Local Variables: |
+# tab-width:4 |
+# indent-tabs-mode:nil |
+# End: |
+# vim: set expandtab tabstop=4 shiftwidth=4: |
Property changes on: scons-2.0.1/engine/SCons/Tool/MSCommon/common.py |
___________________________________________________________________ |
Added: svn:eol-style |
+ LF |