Issue #2513: enable 64bit cross compilation on windows.
diff --git a/Lib/distutils/command/bdist.py b/Lib/distutils/command/bdist.py
index d6897d2..ca3da74 100644
--- a/Lib/distutils/command/bdist.py
+++ b/Lib/distutils/command/bdist.py
@@ -97,7 +97,10 @@
     def finalize_options (self):
         # have to finalize 'plat_name' before 'bdist_base'
         if self.plat_name is None:
-            self.plat_name = get_platform()
+            if self.skip_build:
+                self.plat_name = get_platform()
+            else:
+                self.plat_name = self.get_finalized_command('build').plat_name
 
         # 'bdist_base' -- parent of per-built-distribution-format
         # temporary directories (eg. we'll probably have
@@ -121,7 +124,6 @@
 
     # finalize_options()
 
-
     def run (self):
 
         # Figure out which sub-commands we need to run.
diff --git a/Lib/distutils/command/bdist_msi.py b/Lib/distutils/command/bdist_msi.py
index a401452..f94d957 100644
--- a/Lib/distutils/command/bdist_msi.py
+++ b/Lib/distutils/command/bdist_msi.py
@@ -9,11 +9,11 @@
 
 import sys, os
 from distutils.core import Command
-from distutils.util import get_platform
 from distutils.dir_util import remove_tree
 from distutils.sysconfig import get_python_version
 from distutils.version import StrictVersion
 from distutils.errors import DistutilsOptionError
+from distutils.util import get_platform
 from distutils import log
 import msilib
 from msilib import schema, sequence, text
@@ -87,6 +87,9 @@
 
     user_options = [('bdist-dir=', None,
                      "temporary directory for creating the distribution"),
+                    ('plat-name=', 'p',
+                     "platform name to embed in generated filenames "
+                     "(default: %s)" % get_platform()),
                     ('keep-temp', 'k',
                      "keep the pseudo-installation tree around after " +
                      "creating the distribution archive"),
@@ -116,6 +119,7 @@
 
     def initialize_options (self):
         self.bdist_dir = None
+        self.plat_name = None
         self.keep_temp = 0
         self.no_target_compile = 0
         self.no_target_optimize = 0
@@ -139,7 +143,10 @@
         else:
             self.target_version = short_version
 
-        self.set_undefined_options('bdist', ('dist_dir', 'dist_dir'))
+        self.set_undefined_options('bdist',
+                                   ('dist_dir', 'dist_dir'),
+                                   ('plat_name', 'plat_name'),
+                                   )
 
         if self.pre_install_script:
             raise DistutilsOptionError, "the pre-install-script feature is not yet implemented"
@@ -181,7 +188,7 @@
             if not target_version:
                 assert self.skip_build, "Should have already checked this"
                 target_version = sys.version[0:3]
-            plat_specifier = ".%s-%s" % (get_platform(), target_version)
+            plat_specifier = ".%s-%s" % (self.plat_name, target_version)
             build = self.get_finalized_command('build')
             build.build_lib = os.path.join(build.build_base,
                                            'lib' + plat_specifier)
@@ -633,8 +640,7 @@
 
     def get_installer_filename(self, fullname):
         # Factored out to allow overriding in subclasses
-        plat = get_platform()
-        installer_name = os.path.join(self.dist_dir,
-                                      "%s.%s-py%s.msi" %
-                                       (fullname, plat, self.target_version))
+        base_name = "%s.%s-py%s.msi" % (fullname, self.plat_name,
+                                        self.target_version)
+        installer_name = os.path.join(self.dist_dir, base_name)
         return installer_name
diff --git a/Lib/distutils/command/bdist_wininst.py b/Lib/distutils/command/bdist_wininst.py
index b0691fb..02542af 100644
--- a/Lib/distutils/command/bdist_wininst.py
+++ b/Lib/distutils/command/bdist_wininst.py
@@ -21,6 +21,9 @@
 
     user_options = [('bdist-dir=', None,
                      "temporary directory for creating the distribution"),
+                    ('plat-name=', 'p',
+                     "platform name to embed in generated filenames "
+                     "(default: %s)" % get_platform()),
                     ('keep-temp', 'k',
                      "keep the pseudo-installation tree around after " +
                      "creating the distribution archive"),
@@ -54,6 +57,7 @@
 
     def initialize_options (self):
         self.bdist_dir = None
+        self.plat_name = None
         self.keep_temp = 0
         self.no_target_compile = 0
         self.no_target_optimize = 0
@@ -82,7 +86,10 @@
                       " option must be specified" % (short_version,)
             self.target_version = short_version
 
-        self.set_undefined_options('bdist', ('dist_dir', 'dist_dir'))
+        self.set_undefined_options('bdist',
+                                   ('dist_dir', 'dist_dir'),
+                                   ('plat_name', 'plat_name'),
+                                  )
 
         if self.install_script:
             for script in self.distribution.scripts:
@@ -110,6 +117,7 @@
         install.root = self.bdist_dir
         install.skip_build = self.skip_build
         install.warn_dir = 0
+        install.plat_name = self.plat_name
 
         install_lib = self.reinitialize_command('install_lib')
         # we do not want to include pyc or pyo files
@@ -127,7 +135,7 @@
             if not target_version:
                 assert self.skip_build, "Should have already checked this"
                 target_version = sys.version[0:3]
-            plat_specifier = ".%s-%s" % (get_platform(), target_version)
+            plat_specifier = ".%s-%s" % (self.plat_name, target_version)
             build = self.get_finalized_command('build')
             build.build_lib = os.path.join(build.build_base,
                                            'lib' + plat_specifier)
@@ -285,11 +293,11 @@
             # if we create an installer for a specific python version,
             # it's better to include this in the name
             installer_name = os.path.join(self.dist_dir,
-                                          "%s.win32-py%s.exe" %
-                                           (fullname, self.target_version))
+                                          "%s.%s-py%s.exe" %
+                                           (fullname, self.plat_name, self.target_version))
         else:
             installer_name = os.path.join(self.dist_dir,
-                                          "%s.win32.exe" % fullname)
+                                          "%s.%s.exe" % (fullname, self.plat_name))
         return installer_name
     # get_installer_filename()
 
@@ -312,9 +320,9 @@
                 bv = get_build_version()
             else:
                 if self.target_version < "2.4":
-                    bv = "6"
+                    bv = 6.0
                 else:
-                    bv = "7.1"
+                    bv = 7.1
         else:
             # for current version - use authoritative check.
             bv = get_build_version()
@@ -323,6 +331,10 @@
         directory = os.path.dirname(__file__)
         # we must use a wininst-x.y.exe built with the same C compiler
         # used for python.  XXX What about mingw, borland, and so on?
-        filename = os.path.join(directory, "wininst-%.1f.exe" % bv)
+        if self.plat_name == 'win32':
+            sfix = ''
+        else:
+            sfix = self.plat_name[3:] # strip 'win' - leaves eg '-amd64'
+        filename = os.path.join(directory, "wininst-%.1f%s.exe" % (bv, sfix))
         return open(filename, "rb").read()
 # class bdist_wininst
diff --git a/Lib/distutils/command/build.py b/Lib/distutils/command/build.py
index bca031f..7462e93 100644
--- a/Lib/distutils/command/build.py
+++ b/Lib/distutils/command/build.py
@@ -8,6 +8,7 @@
 
 import sys, os
 from distutils.core import Command
+from distutils.errors import DistutilsOptionError
 from distutils.util import get_platform
 
 
@@ -34,6 +35,9 @@
          "build directory for scripts"),
         ('build-temp=', 't',
          "temporary build directory"),
+        ('plat-name=', 'p',
+         "platform name to build for, if supported "
+         "(default: %s)" % get_platform()),
         ('compiler=', 'c',
          "specify the compiler type"),
         ('debug', 'g',
@@ -61,13 +65,25 @@
         self.build_temp = None
         self.build_scripts = None
         self.compiler = None
+        self.plat_name = None
         self.debug = None
         self.force = 0
         self.executable = None
 
     def finalize_options (self):
 
-        plat_specifier = ".%s-%s" % (get_platform(), sys.version[0:3])
+        if self.plat_name is None:
+            self.plat_name = get_platform()
+        else:
+            # plat-name only supported for windows (other platforms are
+            # supported via ./configure flags, if at all).  Avoid misleading
+            # other platforms.
+            if os.name != 'nt':
+                raise DistutilsOptionError(
+                            "--plat-name only supported on Windows (try "
+                            "using './configure --help' on your platform)")
+
+        plat_specifier = ".%s-%s" % (self.plat_name, sys.version[0:3])
 
         # Make it so Python 2.x and Python 2.x with --with-pydebug don't
         # share the same build directories. Doing so confuses the build
diff --git a/Lib/distutils/command/build_ext.py b/Lib/distutils/command/build_ext.py
index 3042fe0..bf5ad7e 100644
--- a/Lib/distutils/command/build_ext.py
+++ b/Lib/distutils/command/build_ext.py
@@ -15,6 +15,7 @@
 from distutils.sysconfig import customize_compiler, get_python_version
 from distutils.dep_util import newer_group
 from distutils.extension import Extension
+from distutils.util import get_platform
 from distutils import log
 
 if os.name == 'nt':
@@ -60,6 +61,9 @@
          "directory for compiled extension modules"),
         ('build-temp=', 't',
          "directory for temporary files (build by-products)"),
+        ('plat-name=', 'p',
+         "platform name to cross-compile for, if supported "
+         "(default: %s)" % get_platform()),
         ('inplace', 'i',
          "ignore build-lib and put compiled extensions into the source " +
          "directory alongside your pure Python modules"),
@@ -101,6 +105,7 @@
     def initialize_options (self):
         self.extensions = None
         self.build_lib = None
+        self.plat_name = None
         self.build_temp = None
         self.inplace = 0
         self.package = None
@@ -127,7 +132,9 @@
                                    ('build_temp', 'build_temp'),
                                    ('compiler', 'compiler'),
                                    ('debug', 'debug'),
-                                   ('force', 'force'))
+                                   ('force', 'force'),
+                                   ('plat_name', 'plat_name'),
+                                   )
 
         if self.package is None:
             self.package = self.distribution.ext_package
@@ -171,6 +178,9 @@
         # for Release and Debug builds.
         # also Python's library directory must be appended to library_dirs
         if os.name == 'nt':
+            # the 'libs' directory is for binary installs - we assume that
+            # must be the *native* platform.  But we don't really support
+            # cross-compiling via a binary install anyway, so we let it go.
             self.library_dirs.append(os.path.join(sys.exec_prefix, 'libs'))
             if self.debug:
                 self.build_temp = os.path.join(self.build_temp, "Debug")
@@ -181,8 +191,17 @@
             # this allows distutils on windows to work in the source tree
             self.include_dirs.append(os.path.join(sys.exec_prefix, 'PC'))
             if MSVC_VERSION == 9:
-                self.library_dirs.append(os.path.join(sys.exec_prefix,
-                                         'PCbuild'))
+                # Use the .lib files for the correct architecture
+                if self.plat_name == 'win32':
+                    suffix = ''
+                else:
+                    # win-amd64 or win-ia64
+                    suffix = self.plat_name[4:]
+                new_lib = os.path.join(sys.exec_prefix, 'PCbuild')
+                if suffix:
+                    new_lib = os.path.join(new_lib, suffix)
+                self.library_dirs.append(new_lib)
+
             elif MSVC_VERSION == 8:
                 self.library_dirs.append(os.path.join(sys.exec_prefix,
                                          'PC', 'VS8.0', 'win32release'))
@@ -275,6 +294,11 @@
                                      dry_run=self.dry_run,
                                      force=self.force)
         customize_compiler(self.compiler)
+        # If we are cross-compiling, init the compiler now (if we are not
+        # cross-compiling, init would not hurt, but people may rely on
+        # late initialization of compiler even if they shouldn't...)
+        if os.name == 'nt' and self.plat_name != get_platform():
+            self.compiler.initialize(self.plat_name)
 
         # And make sure that any compile/link-related options (which might
         # come from the command-line or from the setup script) are set in
diff --git a/Lib/distutils/command/install.py b/Lib/distutils/command/install.py
index 0d39b91..33a1212 100644
--- a/Lib/distutils/command/install.py
+++ b/Lib/distutils/command/install.py
@@ -16,6 +16,7 @@
 from distutils.errors import DistutilsPlatformError
 from distutils.file_util import write_file
 from distutils.util import convert_path, subst_vars, change_root
+from distutils.util import get_platform
 from distutils.errors import DistutilsOptionError
 
 if sys.version < "2.2":
@@ -503,6 +504,14 @@
         # Obviously have to build before we can install
         if not self.skip_build:
             self.run_command('build')
+            # If we built for any other platform, we can't install.
+            build_plat = self.distribution.get_command_obj('build').plat_name
+            # check warn_dir - it is a clue that the 'install' is happening
+            # internally, and not to sys.path, so we don't check the platform
+            # matches what we are running.
+            if self.warn_dir and build_plat != get_platform():
+                raise DistutilsPlatformError("Can't install when "
+                                             "cross-compiling")
 
         # Run all sub-commands (at least those that need to be run)
         for cmd_name in self.get_sub_commands():
diff --git a/Lib/distutils/command/wininst-9.0-amd64.exe b/Lib/distutils/command/wininst-9.0-amd64.exe
new file mode 100644
index 0000000..c99ede4
--- /dev/null
+++ b/Lib/distutils/command/wininst-9.0-amd64.exe
Binary files differ