diff -r a2cd25d434b3 -r 029d1cdf6422 .hgignore --- a/.hgignore Mon Oct 22 12:58:34 2012 +0000 +++ b/.hgignore Mon Oct 22 06:07:55 2012 -0600 @@ -81,6 +81,7 @@ PCbuild/Win32-temp-* PCbuild/x64-temp-* PCbuild/amd64 +PCbuild/tcltk BuildLog.htm __pycache__ Modules/_freeze_importlib diff -r a2cd25d434b3 -r 029d1cdf6422 Lib/tkinter/_fix.py --- a/Lib/tkinter/_fix.py Mon Oct 22 12:58:34 2012 +0000 +++ b/Lib/tkinter/_fix.py Mon Oct 22 06:07:55 2012 -0600 @@ -48,8 +48,11 @@ prefix = os.path.join(sys.base_prefix,"tcl") if not os.path.exists(prefix): - # devdir/../tcltk/lib - prefix = os.path.join(sys.base_prefix, os.path.pardir, "tcltk", "lib") + # devdir/PCBuild/[amd64/]tcltk/lib + prefix = os.path.join(sys.base_prefix, "PCBuild") + if sys.maxsize > 2**32: + prefix = os.path.join(prefix, "amd64") + prefix = os.path.join("tcltk", "lib") prefix = os.path.abspath(prefix) # if this does not exist, no further search is needed if os.path.exists(prefix): diff -r a2cd25d434b3 -r 029d1cdf6422 PCbuild/_tkinter.vcxproj --- a/PCbuild/_tkinter.vcxproj Mon Oct 22 12:58:34 2012 +0000 +++ b/PCbuild/_tkinter.vcxproj Mon Oct 22 06:07:55 2012 -0600 @@ -155,7 +155,7 @@ WITH_APPINIT;%(PreprocessorDefinitions) - $(tcltkLibDebug);%(AdditionalDependencies) + $(tcltkDir)\lib\tcl85g.lib;$(tcltkDir)\lib\tk85g.lib @@ -163,11 +163,12 @@ X64 - $(tcltk64Dir)\include;%(AdditionalIncludeDirectories) + $(tcltkDir)\include;%(AdditionalIncludeDirectories) WITH_APPINIT;%(PreprocessorDefinitions) - $(tcltk64LibDebug);%(AdditionalDependencies) + $(tcltkDir)\lib\tcl85g.lib;$(tcltkDir)\lib\tk85g.lib + $(OutDir);$(tcltkDir)\lib;%(AdditionalLibraryDirectories) @@ -176,7 +177,7 @@ WITH_APPINIT;%(PreprocessorDefinitions) - $(tcltkLib);%(AdditionalDependencies) + $(tcltkDir)\lib\tcl85.lib;$(tcltkDir)\lib\tk85.lib @@ -184,11 +185,11 @@ X64 - $(tcltk64Dir)\include;%(AdditionalIncludeDirectories) + $(tcltkDir)\include;%(AdditionalIncludeDirectories) WITH_APPINIT;%(PreprocessorDefinitions) - $(tcltk64Lib);%(AdditionalDependencies) + $(tcltkDir)\lib\tcl85.lib;$(tcltkDir)\lib\tk85.lib @@ -197,7 +198,7 @@ WITH_APPINIT;%(PreprocessorDefinitions) - $(tcltkLib);%(AdditionalDependencies) + $(tcltkDir)\lib\tcl85.lib;$(tcltkDir)\lib\tk85.lib @@ -205,11 +206,11 @@ X64 - $(tcltk64Dir)\include;%(AdditionalIncludeDirectories) + $(tcltkDir)\include;%(AdditionalIncludeDirectories) WITH_APPINIT;%(PreprocessorDefinitions) - $(tcltk64Lib);%(AdditionalDependencies) + $(tcltkDir)\lib\tcl85.lib;$(tcltkDir)\lib\tk85.lib MachineX64 @@ -219,7 +220,7 @@ WITH_APPINIT;%(PreprocessorDefinitions) - $(tcltkLib);%(AdditionalDependencies) + $(tcltkDir)\lib\tcl85.lib;$(tcltkDir)\lib\tk85.lib @@ -227,11 +228,11 @@ X64 - $(tcltk64Dir)\include;%(AdditionalIncludeDirectories) + $(tcltkDir)\include;%(AdditionalIncludeDirectories) WITH_APPINIT;%(PreprocessorDefinitions) - $(tcltk64Lib);%(AdditionalDependencies) + $(tcltkDir)\lib\tcl85.lib;$(tcltkDir)\lib\tk85.lib MachineX64 @@ -244,8 +245,12 @@ {cf7ac3d1-e2df-41d2-bea6-1e2556cdea26} false + + {F9B75318-C258-4652-BF17-CA0C492B931B} + false + - \ No newline at end of file + diff -r a2cd25d434b3 -r 029d1cdf6422 PCbuild/build_ssl.py --- a/PCbuild/build_ssl.py Mon Oct 22 12:58:34 2012 +0000 +++ b/PCbuild/build_ssl.py Mon Oct 22 06:07:55 2012 -0600 @@ -24,6 +24,7 @@ # python.exe build_ssl.py Release Win32 import os, sys, re, shutil +from buildlib import get_properties # Find all "foo.exe" files on the PATH. def find_all_on_path(filename, extras = None): @@ -63,13 +64,6 @@ print(" Please install ActivePerl and ensure it appears on your path") return None -# Fetch SSL directory from VC properties -def get_ssl_dir(): - propfile = (os.path.join(os.path.dirname(__file__), 'pyproject.props')) - with open(propfile) as f: - m = re.search('openssl-([^<]+)<', f.read()) - return "..\..\openssl-"+m.group(1) - def create_makefile64(makefile, m32): """Create and fix makefile for 64bit @@ -139,7 +133,6 @@ shutil.copy(src, dst) def main(): - build_all = "-a" in sys.argv if sys.argv[1] == "Release": debug = False elif sys.argv[1] == "Debug": @@ -165,9 +158,12 @@ else: raise ValueError(str(sys.argv)) - make_flags = "" - if build_all: - make_flags = "-a" + if len(sys.argv) > 3: + target = sys.argv[3] + else: + # use the default target + target = '' + # perl should be on the path, but we also look in "\perl" and "c:\\perl" # as "well known" locations perls = find_all_on_path("perl.exe", ["\\perl\\bin", "C:\\perl\\bin"]) @@ -177,10 +173,10 @@ else: print("No Perl installation was found. Existing Makefiles are used.") sys.stdout.flush() - # Look for SSL 2 levels up from pcbuild - ie, same place zlib etc all live. - ssl_dir = get_ssl_dir() - if ssl_dir is None: - sys.exit(1) + + # Fetch SSL directory from VC properties + props = get_properties('ssl', sys.argv[2], sys.argv[1]) + ssl_dir = os.path.join(props['SolutionDir'], props['opensslDir']) old_cd = os.getcwd() try: @@ -237,7 +233,7 @@ copy(r"crypto\opensslconf_%s.h" % arch, r"crypto\opensslconf.h") #makeCommand = "nmake /nologo PERL=\"%s\" -f \"%s\"" %(perl, makefile) - makeCommand = "nmake /nologo -f \"%s\"" % makefile + makeCommand = "nmake /nologo -f \"%s\" %s" % (makefile, target) print("Executing ssl makefiles:", makeCommand) sys.stdout.flush() rc = os.system(makeCommand) diff -r a2cd25d434b3 -r 029d1cdf6422 PCbuild/build_tkinter.py --- a/PCbuild/build_tkinter.py Mon Oct 22 12:58:34 2012 +0000 +++ b/PCbuild/build_tkinter.py Mon Oct 22 06:07:55 2012 -0600 @@ -7,15 +7,9 @@ import os import sys +import getopt +from buildlib import get_properties -here = os.path.abspath(os.path.dirname(__file__)) -par = os.path.pardir - -TCL = "tcl8.5.11" -TK = "tk8.5.11" -TIX = "tix-8.4.3.x" - -ROOT = os.path.abspath(os.path.join(here, par, par)) # Windows 2000 compatibility: WINVER 0x0500 # http://msdn2.microsoft.com/en-us/library/aa383745.aspx NMAKE = ('nmake /nologo /f %s ' @@ -29,53 +23,98 @@ if os.system(cmd) != 0: raise RuntimeError(cmd) -def build(platform, clean): - if platform == "Win32": - dest = os.path.join(ROOT, "tcltk") + +def build(platform, target, debug): + # Allow both processor architecture and platform names as valid arguments + if platform in ("Win32", "x86"): machine = "IX86" - elif platform == "AMD64": - dest = os.path.join(ROOT, "tcltk64") + platform = "Win32" + elif platform in ("x64", "AMD64"): machine = "AMD64" + platform = "x64" else: - raise ValueError(platform) + raise ValueError('unsupported platform: %r' % (platform,)) + if target not in ('build', 'rebuild', 'clean'): + raise ValueError("no rule to make target '%s'" % (target,)) + + if debug: + configuration = 'Debug' + else: + configuration = 'Release' + props = get_properties('tcltk', platform, configuration) + + if target == 'clean': + # Nuke the installation directory + cmd = 'rmdir /s /q "%s"' % props['tcltkDir'] + print('\n\n' + cmd) + if os.path.exists(props['tcltkDir']): + os.system(cmd) + + slndir = props['SolutionDir'] # TCL - tcldir = os.path.join(ROOT, TCL) if 1: - os.chdir(os.path.join(tcldir, "win")) - if clean: - nmake("makefile.vc", "clean") - nmake("makefile.vc", MACHINE=machine) - nmake("makefile.vc", "install", INSTALLDIR=dest, MACHINE=machine) + os.chdir(os.path.join(slndir, props['tclDir'], "win")) + defines = dict(MACHINE=machine, DEBUG=(1 if debug else 0), + INSTALLDIR=os.path.relpath(props['tcltkDir'])) + if target in ('clean', 'rebuild'): + nmake("makefile.vc", "clean", **defines) + if target in ('build', 'rebuild'): + nmake("makefile.vc", "release", **defines) + nmake("makefile.vc", "install", **defines) # TK if 1: - os.chdir(os.path.join(ROOT, TK, "win")) - if clean: - nmake("makefile.vc", "clean", DEBUG=0, TCLDIR=tcldir) - nmake("makefile.vc", DEBUG=0, MACHINE=machine, TCLDIR=tcldir) - nmake("makefile.vc", "install", DEBUG=0, INSTALLDIR=dest, MACHINE=machine, TCLDIR=tcldir) + os.chdir(os.path.join(slndir, props['tkDir'], "win")) + defines = dict(MACHINE=machine, DEBUG=(1 if debug else 0), + INSTALLDIR=os.path.relpath(props['tcltkDir']), + TCLDIR=os.path.relpath(props['tclDir'])) + if target in ('clean', 'rebuild'): + nmake("makefile.vc", "clean", **defines) + if target in ('build', 'rebuild'): + nmake("makefile.vc", "release", **defines) + nmake("makefile.vc", "install", **defines) # TIX if 1: - # python9.mak is available at http://svn.python.org - os.chdir(os.path.join(ROOT, TIX, "win")) - if clean: - nmake("python.mak", "clean") - nmake("python.mak", MACHINE=machine, INSTALL_DIR=dest) - nmake("python.mak", "install", MACHINE=machine, INSTALL_DIR=dest) + # python.mak is available when fetched from: + # http://svn.python.org/external/projects/tix-8.4.3.2 + os.chdir(os.path.join(slndir, props['tixDir'], "win")) + defines = dict(MACHINE=machine, + INSTALL_DIR=os.path.relpath(props['tcltkDir']), + TCL_DIR=os.path.relpath(props['tclDir']), + TK_DIR=os.path.relpath(props['tkDir'])) + if target in ('clean', 'rebuild'): + nmake("python.mak", "clean", **defines) + if target in ('build', 'rebuild'): + nmake("python.mak", "install", **defines) + def main(): - if len(sys.argv) < 2 or sys.argv[1] not in ("Win32", "AMD64"): - print("%s Win32|AMD64" % sys.argv[0]) - sys.exit(1) - - if "-c" in sys.argv: - clean = True - else: - clean = False - - build(sys.argv[1], clean) + args = sys.argv[1:] + opts, args = getopt.getopt(args, 'cdt:', ['debug', 'target=']) + # default settings are for a release build + try: + platform = args[0] + except IndexError: + raise SystemExit("usage: %s Win32|AMD64" % sys.argv[0]) + # Allow both processor architecture and platform names as valid arguments + if platform not in ('Win32', 'x86', 'AMD64', 'x64'): + raise SystemExit("%s: unsupported platform '%r'" % + (sys.argv[0], platform)) + debug = False + target = 'build' + for n, v in opts: + if n in ('-t', '--target'): + target = v.lower() + if target not in ('build', 'rebuild', 'clean'): + raise SystemExit("%s: don't know how to make '%s'" % + (sys.argv[0], v)) + elif n in ('-d', '--debug'): + debug = True + elif n == '-c': + target = 'rebuild' + build(platform, target, debug) if __name__ == '__main__': diff -r a2cd25d434b3 -r 029d1cdf6422 PCbuild/buildlib.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/PCbuild/buildlib.py Mon Oct 22 06:07:55 2012 -0600 @@ -0,0 +1,506 @@ +# Fetch an external directory from the MSVC properties + +import os +import re +import ast +import winreg +from html import parser + +# Regular exressions for tokenizing an MSBuild conditional expression +_group = lambda *choices: '(' + '|'.join(choices) + ')' +_choice = lambda *choices: '(?:' + '|'.join(choices) + ')' +_ws = r'[ \f\t\r\n]*' +_string = _group(r"'[^']*'") +_floatnumber = r'[0-9]+\.[0-9]*' +_hexadecimal = r'0x[0-9a-fA-F]+' +_integer = r'[0-9]+' +_number = _group(_floatnumber, _hexadecimal, _integer) +_operator = _group(r'[<>]=?', '[!=]=') +_keywords = _group('and', 'or') +_special = _group(r'[!()]|\$\(') +_name = _group(r'[a-zA-Z0-9_]+') +_token = _choice(_string, _number, _operator, _keywords, _special, _name) + +_trailing_slash = re.compile(r'[\\/]\s*$').search +def _has_trailing_slash(path): + return _trailing_slash(path) is not None + +# Fixup HTMLParser to handle valid XML (add '_' to NameStartChar) +parser.starttagopen = re.compile('<[a-zA-Z_]') +parser.tagfind = re.compile('([a-zA-Z_][-.a-zA-Z0-9:_]*)') +parser.endtagfind = re.compile('') +parser.locatestarttagend = re.compile( + r"<[a-zA-Z_][-.a-zA-Z0-9:_]*" + r"(?:\s+[a-zA-Z_][-.:a-zA-Z0-9_]*\s*=\s*(['\"])[^\1]*?\1)*" + r"\s*") +class Parser(parser.HTMLParser): + + def __init__(self, platform=None, configuration=None, properties=None): + parser.HTMLParser.__init__(self) + self.strict = True + if properties is None: + properties = self._get_msbuild_properties(platform, configuration) + self.properties = properties + + def _get_msbuild_properties(self, platform, configuration): + props = {} + # Initialize th properties with those from the environment + import nt + for name in nt.environ: + if name.isidentifier(): + props[name] = nt.environ[name] + props['Platform'] = platform + props['Configuration'] = configuration + path = os.path.join(os.environ['ProgramFiles'], 'MSBuild') + if 'ProgramFiles(x86)' in os.environ: + path32 = os.path.join(os.environ['ProgramFiles(x86)'], 'MSBuild') + else: + path32 = path + props['MSBuildExtensionsPath'] = path + props['MSBuildExtensionsPath32'] = path32 + if 'ProgramFiles(x86)' in os.environ: + # 64-bit platform + if 'ProgramW6432' in os.environ: + path64 = os.path.join(os.environ['ProgramW6432'], 'MSBuild') + else: + path64 = path + props['MSBuildExtensionsPath64'] = path64 + props['MSBuildToolsVersion'] = '2.0' + return props + + def _set_msbuild_file(self, path): + this_dir, this_file = os.path.split(path) + this_name, this_ext = os.path.splitext(this_file) + self.properties['MSBuildThisFile'] = this_file + self.properties['MSBuildThisFileName'] = this_name + self.properties['MSBuildThisFileDirectory'] = this_dir + '\\' + self.properties['MSBuildThisFileExtension'] = this_ext + self.properties['MSBuildThisFileFullPath'] = path + + def _init_msbuild_tools(self): + version = self.properties['MSBuildToolsVersion'] + key = 'SOFTWARE\\Microsoft\\MSBuild\\ToolsVersions\\' + version + try: + hkey = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, key) + except WindowsError: + return + keys, values, timestamp = winreg.QueryInfoKey(hkey) + for i in range(values): + name, value, typecode = winreg.EnumValue(hkey, i) + self.properties[name] = self._expand_properties(value) + hkey.Close() + self.properties['MSBuildBinPath'] = self.properties['MSBuildToolsPath'] + + def _parse(self, project_path): + #print('DEBUG: parsing',project_path) + with open(project_path, encoding='utf-8') as f: + data = f.read() + self._set_msbuild_file(project_path) + self.filename = project_path + self.rawdata = data + self.parsing_state = ['#document'] + self.goahead(1) + return self.properties + + def parse(self, project_path): + project_dir, project_file = os.path.split(project_path) + project_name, project_ext = os.path.splitext(project_file) + self.properties['MSBuildProjectFile'] = project_file + self.properties['MSBuildProjectName'] = project_name + self.properties['MSBuildProjectExtension'] = project_ext + self.properties['MSBuildProjectDirectory'] = project_dir + '\\' + self.properties['MSBuildProjectFullPath'] = project_path + return self._parse(project_path) + + def _call_function(self, cls, member, args): + if cls == 'System.IO.Path': + if member == 'Combine': + + return os.path.join(*args) + elif member == 'GetFullPath': + path, = args + # abspath() removes any existing trailing slash + addsep = _has_trailing_slash(path) + path = os.path.abspath(path) + if addsep: + path += os.path.sep + return path + elif member == 'GetTempPath': + return os.environ['TEMP'] + elif cls == 'MSBuild': + if member == 'Escape': + repl = lambda m: '%%%02x' % ord(m.group()) + string, = args + return re.sub("[%$@';?*]", repl, string) + elif cls == 'Microsoft.Build.Utilities.ToolLocationHelper': + if member == 'GetPathToStandardLibraries': + # This function is used for the inproc VisualBasic compiler, so + # the value doesn't matter for Python projects. Defined just to + # silence warnings. + return '' + print("WARNING: unsupported member '%s' on class '%s'" % (member, cls)) + return '' + + # The allowed optional whitespace has been determined via trial and + # error with the MSBuild command line. + _find_function = re.compile(r'\s*\[\s*([^]]+)\]::\s*([^(]+)').match + _find_interesting = re.compile("\$\(|\(\)|[),'`]").search + def _expand_function(self, string, warn=False): + m = self._find_function(string) + if m is None: + print("WARNING: instance methods are unsupported") + return '' + cls, member = m.groups() + pos = m.end() + end = len(string) + asstring = False + args = [] + arg = '' + while pos < end: + m = self._find_interesting(string, pos) + if m: + i, epos = m.span() + c = string[i] + else: + epos = end + c = None + if c == '$': + # property reference + value, spos, epos = self._find_reference(string, pos) + value = self._expand_reference(value, asstring, warn) + if asstring: + arg += value + else: + arg = value + elif c in ("'", "`"): + asstring = not asstring + elif c in (',', ')'): + args.append(arg) + arg = '' + elif c == '(': + args = [] + else: + assert False, "interesting lied" + pos = epos + value = self._call_function(cls, member, args) + return value + + def _expand_registry(self, string, warn=False): + hive, sep, key = string.partition('\\') + key, sep, value = key.partition('@') + # We know the hive to exist as MSBuild gives an error for invalid + # values. + hive = getattr(winreg, hive.upper()) + try: + with winreg.OpenKey(hive, key) as hkey: + value, typecode = winreg.QueryValueEx(hkey, value) + except WindowsError: + # It is not an error for the key to be missing + if warn: + print("WARNING: registry reference '%s' not found" % string) + value = '' + return value + + def _expand_property(self, string, warn=False): + # property names are case-insensitive + name = string.lower() + for key in self.properties: + if key.lower() == name: + value = self.properties[key] + break + else: + if warn: + print("WARNING: property '%s' not found" % string) + value = '' + return value + + _registry_ref = re.compile(r"registry:(.*)", re.IGNORECASE).match + def _evaluate_property(self, source, warn=False): + m = self._registry_ref(source) + if m: + value = self._expand_registry(m.group(1), warn) + elif '(' in source: + value = self._expand_function(source, warn) + else: + value = self._expand_property(source, warn) + return value + + def _expand_reference(self, source, asstring=True, warn=False): + value = self._evaluate_property(source, warn) + if asstring: + if isinstance(value, list): + value = ';'.join(value) + else: + value = str(value) + return value + + _find_varref = re.compile(r"\$\(([^)]+)\)").search + def _find_reference(self, string, start=0): + m = self._find_varref(string, start) + if m is None: + return None + spos, epos = m.span() + ref = m.group(1) + # Property functions contain a closing parenthesis so the + # simple matching pattern will fail in those cases. + if '(' in ref: + # Find the matching ')' for this reference. Note that the + # regex has already matched a closing parenthesis. + start = spos + 2 + parens = string.count('(', start, epos) + while parens: + last = epos + epos = string.index(')', last) + parens -= 1 + parens += string.count('(', last, epos) + epos += 1 + ref = string[start:epos-1] + return ref, spos, epos + + def _expand_properties(self, string, warn=False): + while True: + match = self._find_reference(string) + if match is None: + break + value, spos, epos = match + value = self._expand_reference(value, warn=warn) + string = string[:spos] + value + string[epos:] + return string + + _find_token = re.compile(_ws + _token + _ws, re.IGNORECASE).match + def _translate(self, source): + """Tokenizes an MSBuild conditional expression as an equivalent + Python expression.""" + pos, end = 0, len(source) + while pos < end: + m = self._find_token(source, pos) + if m is None: + raise RuntimeError("invalid token" + repr(source[pos:pos+1])) + token = m.lastindex + value = m.group(token) + epos = m.end() + if token == 1: # strings + value = self._expand_properties(value) + elif token == 4: # keywords + # Python keywords are lowercase only + value = value.lower() + elif token == 5: # specials + if value == '!': # logical not + value = 'not' + elif value == '$(': # property reference + value, spos, epos = self._find_reference(source, pos) + value = 'property("' + value + '")' + yield value + pos = epos + + def _evaluate_ast(self, node): + def _boolean(value): + if isinstance(value, str): + value = (value.lower() == 'true') + return value + def _number(value): + if isinstance(value, str): + if '.' in value: + value = float(value) + elif 'x' in value or 'X' in value: + value = int(value, 16) + else: + value = int(value, 10) + return value + def _string(value): + if not isinstance(value, str): + value = str(value) + return value.lower() + def _convert(node): + if isinstance(node, ast.Str): + return node.s + elif isinstance(node, ast.Num): + return node.n + elif isinstance(node, ast.Name): + name = node.id.lower() + if name == 'true': + return True + elif name == 'false': + return False + return node.id + elif isinstance(node, ast.BoolOp): + if isinstance(node.op, ast.And): + for value in node.values: + if not _convert(value): + return False + return True + else: + for value in node.values: + if _convert(value): + return True + return False + elif isinstance(node, ast.UnaryOp) and isinstance(node.op, ast.Not): + return not _convert(node.operand) + elif isinstance(node, ast.Compare): + # MSBuild restricts comparisons to just 2 operands + op = node.ops[0] + left = _convert(node.left) + right = _convert(node.comparators[0]) + if isinstance(op, (ast.Eq, ast.NotEq)): + # string or boolean comparison (==, !=) + if isinstance(left, bool) or isinstance(right, bool): + left = _boolean(left) + right = _boolean(right) + else: + left = _string(left) + right = _string(right) + if isinstance(op, ast.Eq): + return left == right + else: + return left != right + else: + # number comparison (<, <=, >=, >) + left = _number(left) + right = _number(right) + if isinstance(op, ast.Lt): + return left < right + elif isinstance(op, ast.LtE): + return left <= right + elif isinstance(op, ast.GtE): + return left >= right + elif isinstance(op, ast.Gt): + return left > right + elif isinstance(node, ast.Call): + func = _convert(node.func).lower() + args = map(_convert, node.args) + if func == 'exists': + return os.path.exists(*args) + elif func == 'hastrailingslash': + return _has_trailing_slash(*args) + elif func == 'property': + return self._evaluate_property(*args) + raise ValueError('malformed node or string: ' + repr(node)) + return _convert(node.body) + + def _evaluate(self, cond): + """Evaluates a MSBuild conitional expression as a boolean.""" + # If a conditional expression is not given, it is the same as + # evaluating to True. + if cond is None: + return True + # Convert the MSBuild condition to valid a Python expression + expr = ' '.join(self._translate(cond)) + # Escape backslashes ('\') as the the strings are to be parsed + expr = expr.replace('\\', '\\\\') + node = ast.parse(expr, self.filename, 'eval') + return self._evaluate_ast(node) + + def handle_import(self, project, condition=None, label=None): + if self._evaluate(condition): + project = self._expand_properties(project, warn=True) + project = os.path.join(os.path.dirname(self.filename), project) + if os.path.exists(project): + subparser = Parser(properties=self.properties) + subparser._parse(project) + # Restore the "current" filename properties + self._set_msbuild_file(self.filename) + # Ignore the endtag event for this element. There is no need for + # an additional parsing state as 'Import' elements cannot have any + # child elements per the MSBuild schema. + self.element_depth = 1 + + def handle_starttag(self, tag, attrs): + parsing = self.parsing_state[-1] + if parsing == 'propertygroup': + # all child elements are property name/value pairs + condition = None + for name, value in attrs: + if name == 'condition': + condition = value + if self._evaluate(condition): + rawtag = self.get_starttag_text() + match = parser.tagfind.search(rawtag) + self.property_name = match.group(1) + self.property_value = [] + self.handle_data = self.property_value.append + self.parsing_state.append('#property') + else: + self.parsing_state.append('#ignore') + self.element_depth = 0 + + elif parsing == 'importgroup': + # per the MSBuild XML Schema only 'Import' elements are allowed + self.handle_import(**dict(attrs)) + + elif parsing == 'project': + # look for 'Import', 'ImportGroup' and 'PropertyGroup' elements + if tag == 'import': + self.handle_import(**dict(attrs)) + else: + # process the attributes common to the elements being checked + condition = label = None + for name, value in attrs: + if name == 'condition': + condition = value + elif name == 'label': + label = value + if tag == 'importgroup' and (label == 'PropertySheets' and + self._evaluate(condition)): + parsing = tag + elif tag == 'propertygroup' and self._evaluate(condition): + parsing = tag + else: + parsing = '#ignore' + self.parsing_state.append(parsing) + self.element_depth = 0 + + elif parsing == '#document': + # look for 'Project' element + if tag == 'project': + for name, value in attrs: + if name == 'toolsversion': + self.properties['MSBuildToolsVersion'] = value + self._init_msbuild_tools() + self.parsing_state.append(tag) + self.element_depth = 0 + + else: + self.element_depth += 1 + + def handle_endtag(self, tag): + if self.element_depth: + self.element_depth -= 1 + return + parsing = self.parsing_state.pop() + if parsing == '#property': + value = ''.join(self.property_value) + value = self._expand_properties(value, warn=False) + if ';' in value: + value = value.split(';') + value = [ v for v in (v.strip() for v in value) if v ] + else: + value = value.strip() + self.properties[self.property_name] = value + del self.handle_data, self.property_value, self.property_name + + def handle_charref(self, name): + """Convert character references to their character data equivalent.""" + try: + if name[0] in 'xX': + c = int(name[1:], 16) + else: + c = int(name, 10) + data = chr(c) + except ValueError: + data = '&#' + name + ';' + self.handle_data(data) + + entitydefs = {'lt': '<', 'gt': '>', 'apos': "'", 'quot': '"'} + def handle_entityref(self, name): + """Convert entity references to their character data equivalent.""" + try: + data = self.entitydefs[name] + except KeyError: + data = '&' + name + ';' + self.handle_data(data) + + +def get_properties(project, platform, configuration): + p = Parser(platform, configuration) + fn = os.path.join(os.path.dirname(__file__), project + '.vcxproj') + return p.parse(fn) diff -r a2cd25d434b3 -r 029d1cdf6422 PCbuild/pcbuild.sln --- a/PCbuild/pcbuild.sln Mon Oct 22 12:58:34 2012 +0000 +++ b/PCbuild/pcbuild.sln Mon Oct 22 06:07:55 2012 -0600 @@ -74,6 +74,8 @@ EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_freeze_importlib", "_freeze_importlib.vcxproj", "{19C0C13F-47CA-4432-AFF3-799A296A4DDC}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tcltk", "tcltk.vcxproj", "{F9B75318-C258-4652-BF17-CA0C492B931B}" +EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_sha3", "_sha3.vcxproj", "{254A0C05-6696-4B08-8CB2-EF7D533AEE01}" EndProject Global @@ -613,6 +615,22 @@ {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.PGUpdate|x64.ActiveCfg = Release|Win32 {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.Release|Win32.ActiveCfg = Release|Win32 {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.Release|x64.ActiveCfg = Release|x64 + {F9B75318-C258-4652-BF17-CA0C492B931B}.Debug|Win32.ActiveCfg = Debug|Win32 + {F9B75318-C258-4652-BF17-CA0C492B931B}.Debug|Win32.Build.0 = Debug|Win32 + {F9B75318-C258-4652-BF17-CA0C492B931B}.Debug|x64.ActiveCfg = Debug|x64 + {F9B75318-C258-4652-BF17-CA0C492B931B}.Debug|x64.Build.0 = Debug|x64 + {F9B75318-C258-4652-BF17-CA0C492B931B}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 + {F9B75318-C258-4652-BF17-CA0C492B931B}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 + {F9B75318-C258-4652-BF17-CA0C492B931B}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 + {F9B75318-C258-4652-BF17-CA0C492B931B}.PGInstrument|x64.Build.0 = PGInstrument|x64 + {F9B75318-C258-4652-BF17-CA0C492B931B}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 + {F9B75318-C258-4652-BF17-CA0C492B931B}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 + {F9B75318-C258-4652-BF17-CA0C492B931B}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 + {F9B75318-C258-4652-BF17-CA0C492B931B}.PGUpdate|x64.Build.0 = PGUpdate|x64 + {F9B75318-C258-4652-BF17-CA0C492B931B}.Release|Win32.ActiveCfg = Release|Win32 + {F9B75318-C258-4652-BF17-CA0C492B931B}.Release|Win32.Build.0 = Release|Win32 + {F9B75318-C258-4652-BF17-CA0C492B931B}.Release|x64.ActiveCfg = Release|x64 + {F9B75318-C258-4652-BF17-CA0C492B931B}.Release|x64.Build.0 = Release|x64 {254A0C05-6696-4B08-8CB2-EF7D533AEE01}.Debug|Win32.ActiveCfg = Debug|Win32 {254A0C05-6696-4B08-8CB2-EF7D533AEE01}.Debug|Win32.Build.0 = Debug|Win32 {254A0C05-6696-4B08-8CB2-EF7D533AEE01}.Debug|x64.ActiveCfg = Debug|x64 @@ -629,7 +647,7 @@ {254A0C05-6696-4B08-8CB2-EF7D533AEE01}.Release|Win32.Build.0 = Release|Win32 {254A0C05-6696-4B08-8CB2-EF7D533AEE01}.Release|x64.ActiveCfg = Release|x64 {254A0C05-6696-4B08-8CB2-EF7D533AEE01}.Release|x64.Build.0 = Release|x64 - EndGlobalSection + EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection diff -r a2cd25d434b3 -r 029d1cdf6422 PCbuild/pyproject.props --- a/PCbuild/pyproject.props Mon Oct 22 12:58:34 2012 +0000 +++ b/PCbuild/pyproject.props Mon Oct 22 06:07:55 2012 -0600 @@ -1,4 +1,4 @@ - + <_ProjectFileVersion>10.0.30319.1 @@ -21,12 +21,10 @@ $(externalsDir)\bzip2-1.0.6 $(externalsDir)\xz-5.0.3 $(externalsDir)\openssl-1.0.1c - $(externalsDir)\tcltk - $(externalsDir)\tcltk64 - $(tcltkDir)\lib\tcl85.lib;$(tcltkDir)\lib\tk85.lib - $(tcltkDir)\lib\tcl85g.lib;$(tcltkDir)\lib\tk85g.lib - $(tcltk64Dir)\lib\tcl85.lib;$(tcltk64Dir)\lib\tk85.lib - $(tcltk64Dir)\lib\tcl85g.lib;$(tcltk64Dir)\lib\tk85g.lib + $(externalsDir)\tcl-8.5.11.0 + $(externalsDir)\tk-8.5.11.0 + $(externalsDir)\tix-8.4.3.2 + $(OutDir)tcltk @@ -83,23 +81,17 @@ $(opensslDir) + + $(tcltkDir) + + + $(tcltkDir) + + + $(tcltkDir) + $(tcltkDir) - - $(tcltk64Dir) - - - $(tcltkLib) - - - $(tcltkLibDebug) - - - $(tcltk64Lib) - - - $(tcltk64LibDebug) - diff -r a2cd25d434b3 -r 029d1cdf6422 PCbuild/readme.txt --- a/PCbuild/readme.txt Mon Oct 22 12:58:34 2012 +0000 +++ b/PCbuild/readme.txt Mon Oct 22 06:07:55 2012 -0600 @@ -103,12 +103,21 @@ _sqlite3 Wraps SQLite 3.7.4, which is currently built by sqlite3.vcproj (see below). _tkinter - Wraps the Tk windowing system. Unlike _sqlite3, there's no - corresponding tcltk.vcproj-type project that builds Tcl/Tk from vcproj's - within our pcbuild.sln, which means this module expects to find a - pre-built Tcl/Tk in either ..\..\tcltk for 32-bit or ..\..\tcltk64 for - 64-bit (relative to this directory). See below for instructions to build - Tcl/Tk. + Wraps the Tk windowing system, which is currently built by tcltk.vcproj. + + Get the source code through + + svn export http://svn.python.org/projects/external/tcl-8.5.11.0 + svn export http://svn.python.org/projects/external/tk-8.5.11.0 + svn export http://svn.python.org/projects/external/tix-8.4.3.2 + + ** NOTE: if you use the Tools\buildbot\external(-amd64).bat approach for + obtaining external sources then you don't need to manually get the source + above via subversion. ** + + The tcltk project simply invokes PCBuild/build_tkinter.py to perform + the build. This Python script locates and builds the Tcl/Tk/Tix + installations. _bz2 Python wrapper for the libbzip2 compression library. Homepage http://www.bzip.org/ @@ -196,27 +205,7 @@ This extracts all the external subprojects from http://svn.python.org/external via Subversion (so you'll need an svn.exe on your PATH) and places them in -..\.. (relative to this directory). The external(-amd64).bat scripts will -also build a debug build of Tcl/Tk; there aren't any equivalent batch files -for building release versions of Tcl/Tk lying around in the Tools\buildbot -directory. If you need to build a release version of Tcl/Tk it isn't hard -though, take a look at the relevant external(-amd64).bat file and find the -two nmake lines, then call each one without the 'DEBUG=1' parameter, i.e.: - -The external-amd64.bat file contains this for tcl: - nmake -f makefile.vc COMPILERFLAGS=-DWINVER=0x0500 DEBUG=1 MACHINE=AMD64 INSTALLDIR=..\..\tcltk64 clean all install - -So for a release build, you'd call it as: - nmake -f makefile.vc COMPILERFLAGS=-DWINVER=0x0500 MACHINE=AMD64 INSTALLDIR=..\..\tcltk64 clean all install - - XXX Should we compile with OPTS=threads? - XXX Our installer copies a lot of stuff out of the Tcl/Tk install - XXX directory. Is all of that really needed for Python use of Tcl/Tk? - -This will be cleaned up in the future; ideally Tcl/Tk will be brought into our -pcbuild.sln as custom .vcproj files, just as we've recently done with the -sqlite3.vcproj file, which will remove the need for Tcl/Tk to be built -separately via a batch file. +..\.. (relative to this directory). XXX trent.nelson 02-Apr-08: Having the external subprojects in ..\.. relative to this directory is a diff -r a2cd25d434b3 -r 029d1cdf6422 PCbuild/select.vcxproj --- a/PCbuild/select.vcxproj Mon Oct 22 12:58:34 2012 +0000 +++ b/PCbuild/select.vcxproj Mon Oct 22 06:07:55 2012 -0600 @@ -151,7 +151,7 @@ - ws2_32.lib;%(AdditionalDependencies) + wsock32.lib;%(AdditionalDependencies) libc;%(IgnoreSpecificDefaultLibraries) 0x1D110000 @@ -161,14 +161,14 @@ X64 - ws2_32.lib;%(AdditionalDependencies) + wsock32.lib;%(AdditionalDependencies) libc;%(IgnoreSpecificDefaultLibraries) 0x1D110000 - ws2_32.lib;%(AdditionalDependencies) + wsock32.lib;%(AdditionalDependencies) libc;%(IgnoreSpecificDefaultLibraries) 0x1D110000 @@ -178,14 +178,14 @@ X64 - ws2_32.lib;%(AdditionalDependencies) + wsock32.lib;%(AdditionalDependencies) libc;%(IgnoreSpecificDefaultLibraries) 0x1D110000 - ws2_32.lib;%(AdditionalDependencies) + wsock32.lib;%(AdditionalDependencies) libc;%(IgnoreSpecificDefaultLibraries) 0x1D110000 @@ -195,7 +195,7 @@ X64 - ws2_32.lib;%(AdditionalDependencies) + wsock32.lib;%(AdditionalDependencies) libc;%(IgnoreSpecificDefaultLibraries) 0x1D110000 MachineX64 @@ -203,7 +203,7 @@ - ws2_32.lib;%(AdditionalDependencies) + wsock32.lib;%(AdditionalDependencies) libc;%(IgnoreSpecificDefaultLibraries) 0x1D110000 @@ -213,7 +213,7 @@ X64 - ws2_32.lib;%(AdditionalDependencies) + wsock32.lib;%(AdditionalDependencies) libc;%(IgnoreSpecificDefaultLibraries) 0x1D110000 MachineX64 diff -r a2cd25d434b3 -r 029d1cdf6422 PCbuild/ssl.vcxproj --- a/PCbuild/ssl.vcxproj Mon Oct 22 12:58:34 2012 +0000 +++ b/PCbuild/ssl.vcxproj Mon Oct 22 06:07:55 2012 -0600 @@ -118,94 +118,11 @@ <_ProjectFileVersion>10.0.30319.1 - cd "$(SolutionDir)" -"$(PythonExe)" build_ssl.py Release $(Platform) -a - - - - - $(NMakePreprocessorDefinitions) - $(NMakeIncludeSearchPath) - $(NMakeForcedIncludes) - $(NMakeAssemblySearchPath) - $(NMakeForcedUsingAssemblies) - cd "$(SolutionDir)" -"$(PythonExe)" build_ssl.py Release $(Platform) -a - - - - - $(NMakePreprocessorDefinitions) - $(NMakeIncludeSearchPath) - $(NMakeForcedIncludes) - $(NMakeAssemblySearchPath) - $(NMakeForcedUsingAssemblies) - cd "$(SolutionDir)" -"$(PythonExe)" build_ssl.py Release $(Platform) -a - - - - - $(NMakePreprocessorDefinitions) - $(NMakeIncludeSearchPath) - $(NMakeForcedIncludes) - $(NMakeAssemblySearchPath) - $(NMakeForcedUsingAssemblies) - cd "$(SolutionDir)" -"$(PythonExe)" build_ssl.py Release $(Platform) -a - - - - - $(NMakePreprocessorDefinitions) - $(NMakeIncludeSearchPath) - $(NMakeForcedIncludes) - $(NMakeAssemblySearchPath) - $(NMakeForcedUsingAssemblies) - cd "$(SolutionDir)" -"$(PythonExe)" build_ssl.py Release $(Platform) -a - - - - - $(NMakePreprocessorDefinitions) - $(NMakeIncludeSearchPath) - $(NMakeForcedIncludes) - $(NMakeAssemblySearchPath) - $(NMakeForcedUsingAssemblies) - cd "$(SolutionDir)" -"$(PythonExe)" build_ssl.py Release $(Platform) -a - - - - - $(NMakePreprocessorDefinitions) - $(NMakeIncludeSearchPath) - $(NMakeForcedIncludes) - $(NMakeAssemblySearchPath) - $(NMakeForcedUsingAssemblies) - cd "$(SolutionDir)" -"$(PythonExe)" build_ssl.py Release $(Platform) -a - - - - - $(NMakePreprocessorDefinitions) - $(NMakeIncludeSearchPath) - $(NMakeForcedIncludes) - $(NMakeAssemblySearchPath) - $(NMakeForcedUsingAssemblies) - cd "$(SolutionDir)" -"$(PythonExe)" build_ssl.py Release $(Platform) -a - - - - - $(NMakePreprocessorDefinitions) - $(NMakeIncludeSearchPath) - $(NMakeForcedIncludes) - $(NMakeAssemblySearchPath) - $(NMakeForcedUsingAssemblies) + + "$(PythonExe)" "$(SolutionDir)build_ssl.py" Release $(Platform) + + + "$(PythonExe)" "$(SolutionDir)build_ssl.py" Release $(Platform) clean @@ -218,4 +135,4 @@ - \ No newline at end of file + diff -r a2cd25d434b3 -r 029d1cdf6422 PCbuild/tcltk.vcxproj --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/PCbuild/tcltk.vcxproj Mon Oct 22 06:07:55 2012 -0600 @@ -0,0 +1,152 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + PGInstrument + Win32 + + + PGInstrument + x64 + + + PGUpdate + Win32 + + + PGUpdate + x64 + + + Release + Win32 + + + Release + x64 + + + + {F9B75318-C258-4652-BF17-CA0C492B931B} + tcltk + MakeFileProj + + + + Makefile + NotSet + + + Makefile + NotSet + + + Makefile + NotSet + + + Makefile + NotSet + + + Makefile + NotSet + + + Makefile + NotSet + + + Makefile + NotSet + + + Makefile + NotSet + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $(VCInstallDir) + true + + + + + true + Document + + + + "$(PythonExe)" "$(SolutionDir)build_tkinter.py" --debug --target=build $(Platform) + "$(PythonExe)" "$(SolutionDir)build_tkinter.py" --debug --target=build $(Platform) + "$(PythonExe)" "$(SolutionDir)build_tkinter.py" --debug --target=clean $(Platform) + + + "$(PythonExe)" "$(SolutionDir)build_tkinter.py" --target=build $(Platform) + "$(PythonExe)" "$(SolutionDir)build_tkinter.py" --target=build $(Platform) + "$(PythonExe)" "$(SolutionDir)build_tkinter.py" --target=clean $(Platform) + + + + + + {b11d750f-cd1f-4a96-85ce-e69a5c5259f9} + false + + + + + + diff -r a2cd25d434b3 -r 029d1cdf6422 Tools/buildbot/external-amd64.bat --- a/Tools/buildbot/external-amd64.bat Mon Oct 22 12:58:34 2012 +0000 +++ b/Tools/buildbot/external-amd64.bat Mon Oct 22 06:07:55 2012 -0600 @@ -2,20 +2,3 @@ @rem Assume we start inside the Python source directory call "Tools\buildbot\external-common.bat" -call "%VS100COMNTOOLS%\..\..\VC\vcvarsall.bat" x86_amd64 - -if not exist tcltk64\bin\tcl85g.dll ( - cd tcl-8.5.11.0\win - nmake -f makefile.vc COMPILERFLAGS=-DWINVER=0x0500 DEBUG=1 MACHINE=AMD64 INSTALLDIR=..\..\tcltk64 clean all - nmake -f makefile.vc COMPILERFLAGS=-DWINVER=0x0500 DEBUG=1 MACHINE=AMD64 INSTALLDIR=..\..\tcltk64 install - cd ..\.. -) - -if not exist tcltk64\bin\tk85g.dll ( - cd tk-8.5.11.0\win - nmake -f makefile.vc COMPILERFLAGS=-DWINVER=0x0500 OPTS=noxp DEBUG=1 MACHINE=AMD64 INSTALLDIR=..\..\tcltk64 TCLDIR=..\..\tcl-8.5.11.0 clean - nmake -f makefile.vc COMPILERFLAGS=-DWINVER=0x0500 OPTS=noxp DEBUG=1 MACHINE=AMD64 INSTALLDIR=..\..\tcltk64 TCLDIR=..\..\tcl-8.5.11.0 all - nmake -f makefile.vc COMPILERFLAGS=-DWINVER=0x0500 OPTS=noxp DEBUG=1 MACHINE=AMD64 INSTALLDIR=..\..\tcltk64 TCLDIR=..\..\tcl-8.5.11.0 install - cd ..\.. -) - diff -r a2cd25d434b3 -r 029d1cdf6422 Tools/buildbot/external-common.bat --- a/Tools/buildbot/external-common.bat Mon Oct 22 12:58:34 2012 +0000 +++ b/Tools/buildbot/external-common.bat Mon Oct 22 06:07:55 2012 -0600 @@ -29,12 +29,13 @@ svn export http://svn.python.org/projects/external/openssl-1.0.1c ) -@rem tcl/tk +@rem tcl/tk/tix if not exist tcl-8.5.11.0 ( rd /s/q tcltk tcltk64 svn export http://svn.python.org/projects/external/tcl-8.5.11.0 ) if not exist tk-8.5.11.0 svn export http://svn.python.org/projects/external/tk-8.5.11.0 +if not exist tix-8.4.3.2 svn export http://svn.python.org/projects/external/tix-8.4.3.2 @rem sqlite3 if not exist sqlite-3.7.12 ( diff -r a2cd25d434b3 -r 029d1cdf6422 Tools/buildbot/external.bat --- a/Tools/buildbot/external.bat Mon Oct 22 12:58:34 2012 +0000 +++ b/Tools/buildbot/external.bat Mon Oct 22 06:07:55 2012 -0600 @@ -2,20 +2,3 @@ @rem Assume we start inside the Python source directory call "Tools\buildbot\external-common.bat" -call "%VS100COMNTOOLS%\vsvars32.bat" - -if not exist tcltk\bin\tcl85g.dll ( - @rem all and install need to be separate invocations, otherwise nmakehlp is not found on install - cd tcl-8.5.11.0\win - nmake -f makefile.vc COMPILERFLAGS=-DWINVER=0x0500 DEBUG=1 INSTALLDIR=..\..\tcltk clean all - nmake -f makefile.vc DEBUG=1 INSTALLDIR=..\..\tcltk install - cd ..\.. -) - -if not exist tcltk\bin\tk85g.dll ( - cd tk-8.5.11.0\win - nmake -f makefile.vc COMPILERFLAGS=-DWINVER=0x0500 OPTS=noxp DEBUG=1 INSTALLDIR=..\..\tcltk TCLDIR=..\..\tcl-8.5.11.0 clean - nmake -f makefile.vc COMPILERFLAGS=-DWINVER=0x0500 OPTS=noxp DEBUG=1 INSTALLDIR=..\..\tcltk TCLDIR=..\..\tcl-8.5.11.0 all - nmake -f makefile.vc COMPILERFLAGS=-DWINVER=0x0500 OPTS=noxp DEBUG=1 INSTALLDIR=..\..\tcltk TCLDIR=..\..\tcl-8.5.11.0 install - cd ..\.. -)