]> granicus.if.org Git - python/commitdiff
Issue #2513: enable 64bit cross compilation on windows.
authorMark Hammond <mhammond@skippinet.com.au>
Mon, 7 Apr 2008 01:53:39 +0000 (01:53 +0000)
committerMark Hammond <mhammond@skippinet.com.au>
Mon, 7 Apr 2008 01:53:39 +0000 (01:53 +0000)
16 files changed:
Doc/distutils/builtdist.rst
Lib/distutils/command/bdist.py
Lib/distutils/command/bdist_msi.py
Lib/distutils/command/bdist_wininst.py
Lib/distutils/command/build.py
Lib/distutils/command/build_ext.py
Lib/distutils/command/install.py
Lib/distutils/command/wininst-9.0-amd64.exe [new file with mode: 0644]
Lib/distutils/msvc9compiler.py
Lib/distutils/msvccompiler.py
Lib/distutils/util.py
Misc/NEWS
PC/example_nt/readme.txt
PC/example_nt/setup.py [new file with mode: 0644]
PCbuild/bdist_wininst.vcproj
PCbuild/pcbuild.sln

index 2ebc9860f1e9008c45fe8e4449533a9c87431c41..f009bbb9288d2062ebd6a10e24593f64420a5be0 100644 (file)
@@ -329,6 +329,42 @@ version number.  This can be changed to another text by using the
 The installer file will be written to the "distribution directory" --- normally
 :file:`dist/`, but customizable with the :option:`--dist-dir` option.
 
+.. _cross-compile-windows:
+
+Cross-compiling on Windows
+=====================
+
+Starting with Python 2.6, distutils is capable of cross-compiling between 
+Windows platforms.  In practice, this means that with the correct tools 
+installed, you can use a 32bit version of Windows to create 64bit extensions
+and vice-versa.
+
+To build for an alternate platform, specify the :option:`--plat-name` option 
+to the build command.  Valid values are currently 'win32', 'win-amd64' and 
+'win-ia64'.  For example, on a 32bit version of Windows, you could execute::
+
+   python setup.py build --plat-name=win-amd64
+
+to build a 64bit version of your extension.  The Windows Installers also 
+support this option, so the command::
+
+   python setup.py build --plat-name=win-amd64 bdist_wininst
+
+would create a 64bit installation executable on your 32bit version of Windows.
+
+To cross-compile, you must download the Python source code and cross-compile 
+Python itself for the platform you are targetting - it is not possible from a
+binary installtion of Python (as the .lib etc file for other platforms are
+not included.)  In practice, this means the user of a 32 bit operating 
+system will need to use Visual Studio 2008 to open the 
+:file:`PCBuild/PCbuild.sln` solution in the Python source tree and build the 
+"x64" configuration of the 'pythoncore' project before cross-compiling 
+extensions is possible.
+
+Note that by default, Visual Studio 2008 does not install 64bit compilers or
+tools.  You may need to reexecute the Visual Studio setup process and select
+these tools (using Control Panel->[Add/Remove] Programs is a convenient way to
+check or modify your existing install.)
 
 .. _postinstallation-script:
 
index d6897d2d09b1ea085b0ea7aac87cd84c324f20cb..ca3da74c0672e7284e0c3fe1dfb82f9ca88ef8ee 100644 (file)
@@ -97,7 +97,10 @@ class bdist (Command):
     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 @@ class bdist (Command):
 
     # finalize_options()
 
-
     def run (self):
 
         # Figure out which sub-commands we need to run.
index a4014525b72ca341e4a1868e140e0a3f5d30a073..f94d9579d216c0cc14261cc83c887a9c59ce2e2f 100644 (file)
@@ -9,11 +9,11 @@ Implements the bdist_msi command.
 
 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 @@ class bdist_msi (Command):
 
     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 @@ class bdist_msi (Command):
 
     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 @@ class bdist_msi (Command):
         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 @@ class bdist_msi (Command):
             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 @@ class bdist_msi (Command):
 
     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
index b0691fb823b66b50be1cf42609cd47a702d006d2..02542afbd3fcd4141ddde9fb02962516399770ee 100644 (file)
@@ -21,6 +21,9 @@ class bdist_wininst (Command):
 
     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 @@ class bdist_wininst (Command):
 
     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 @@ class bdist_wininst (Command):
                       " 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 @@ class bdist_wininst (Command):
         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 @@ class bdist_wininst (Command):
             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 @@ class bdist_wininst (Command):
             # 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 @@ class bdist_wininst (Command):
                 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 @@ class bdist_wininst (Command):
         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
index bca031f73013c755711b2cdf0f5f5eaf69ef77a1..7462e9348fcddb271b7e12800b2696cf46d0fcbb 100644 (file)
@@ -8,6 +8,7 @@ __revision__ = "$Id$"
 
 import sys, os
 from distutils.core import Command
+from distutils.errors import DistutilsOptionError
 from distutils.util import get_platform
 
 
@@ -34,6 +35,9 @@ class build (Command):
          "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 @@ class build (Command):
         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
index 3042fe0223443da4150e87e81b9cafc7a7c25221..bf5ad7e00b763d233340baab54335e1530a0e762 100644 (file)
@@ -15,6 +15,7 @@ from distutils.errors import *
 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 @@ class build_ext (Command):
          "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 @@ class build_ext (Command):
     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 @@ class build_ext (Command):
                                    ('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 @@ class build_ext (Command):
         # 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 @@ class build_ext (Command):
             # 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 @@ class build_ext (Command):
                                      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
index 0d39b91cc3e89d3adfaf5c37eb8c859e070cb3ab..33a1212b0a9d4d8c61d0de5c937c94cba33a8f60 100644 (file)
@@ -16,6 +16,7 @@ from distutils.sysconfig import get_config_vars
 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 @@ class install (Command):
         # 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 (file)
index 0000000..c99ede4
Binary files /dev/null and b/Lib/distutils/command/wininst-9.0-amd64.exe differ
index 828d7fbf7a153df6311273d7117682dcfc7675eb..8b1cf9a9109cd295760425a739d3c57e9d4c43f2 100644 (file)
@@ -22,6 +22,7 @@ from distutils.errors import (DistutilsExecError, DistutilsPlatformError,
 from distutils.ccompiler import (CCompiler, gen_preprocess_options,
     gen_lib_options)
 from distutils import log
+from distutils.util import get_platform
 
 import _winreg
 
@@ -38,13 +39,15 @@ HKEYS = (_winreg.HKEY_USERS,
 VS_BASE = r"Software\Microsoft\VisualStudio\%0.1f"
 WINSDK_BASE = r"Software\Microsoft\Microsoft SDKs\Windows"
 NET_BASE = r"Software\Microsoft\.NETFramework"
-ARCHS = {'DEFAULT' : 'x86',
-    'intel' : 'x86', 'x86' : 'x86',
-    'amd64' : 'x64', 'x64' : 'x64',
-    'itanium' : 'ia64', 'ia64' : 'ia64',
-    }
 
-# The globals VERSION, ARCH, MACROS and VC_ENV are defined later
+# A map keyed by get_platform() return values to values accepted by
+# 'vcvarsall.bat'.  Note a cross-compile may combine these (eg, 'x86_amd64' is
+# the param to cross-compile on x86 targetting amd64.)
+PLAT_TO_VCVARS = {
+    'win32' : 'x86',
+    'win-amd64' : 'amd64',
+    'win-ia64' : 'ia64',
+}
 
 class Reg:
     """Helper class to read values from the registry
@@ -176,23 +179,6 @@ def get_build_version():
     # else we don't know what version of the compiler this is
     return None
 
-def get_build_architecture():
-    """Return the processor architecture.
-
-    Possible results are "x86" or "amd64".
-    """
-    prefix = " bit ("
-    i = sys.version.find(prefix)
-    if i == -1:
-        return "x86"
-    j = sys.version.find(")", i)
-    sysarch = sys.version[i+len(prefix):j].lower()
-    arch = ARCHS.get(sysarch, None)
-    if arch is None:
-        return ARCHS['DEFAULT']
-    else:
-        return arch
-
 def normalize_and_reduce_paths(paths):
     """Return a list of normalized paths with duplicates removed.
 
@@ -251,6 +237,7 @@ def query_vcvarsall(version, arch="x86"):
 
     if vcvarsall is None:
         raise IOError("Unable to find vcvarsall.bat")
+    log.debug("Calling 'vcvarsall.bat %s' (version=%s)", arch, version)
     popen = subprocess.Popen('"%s" %s & set' % (vcvarsall, arch),
                              stdout=subprocess.PIPE,
                              stderr=subprocess.PIPE)
@@ -281,9 +268,7 @@ def query_vcvarsall(version, arch="x86"):
 VERSION = get_build_version()
 if VERSION < 8.0:
     raise DistutilsPlatformError("VC %0.1f is not supported by this module" % VERSION)
-ARCH = get_build_architecture()
 # MACROS = MacroExpander(VERSION)
-VC_ENV = query_vcvarsall(VERSION, ARCH)
 
 class MSVCCompiler(CCompiler) :
     """Concrete class that implements an interface to Microsoft Visual C++,
@@ -318,13 +303,25 @@ class MSVCCompiler(CCompiler) :
     def __init__(self, verbose=0, dry_run=0, force=0):
         CCompiler.__init__ (self, verbose, dry_run, force)
         self.__version = VERSION
-        self.__arch = ARCH
         self.__root = r"Software\Microsoft\VisualStudio"
         # self.__macros = MACROS
         self.__path = []
+        # target platform (.plat_name is consistent with 'bdist')
+        self.plat_name = None
+        self.__arch = None # deprecated name
         self.initialized = False
 
-    def initialize(self):
+    def initialize(self, plat_name=None):
+        # multi-init means we would need to check platform same each time...
+        assert not self.initialized, "don't init multiple times"
+        if plat_name is None:
+            plat_name = get_platform()
+        # sanity check for platforms to prevent obscure errors later.
+        ok_plats = 'win32', 'win-amd64', 'win-ia64'
+        if plat_name not in ok_plats:
+            raise DistutilsPlatformError("--plat-name must be one of %s" %
+                                         (ok_plats,))
+
         if "DISTUTILS_USE_SDK" in os.environ and "MSSdk" in os.environ and self.find_exe("cl.exe"):
             # Assume that the SDK set up everything alright; don't try to be
             # smarter
@@ -334,9 +331,24 @@ class MSVCCompiler(CCompiler) :
             self.rc = "rc.exe"
             self.mc = "mc.exe"
         else:
-            self.__paths = VC_ENV['path'].split(os.pathsep)
-            os.environ['lib'] = VC_ENV['lib']
-            os.environ['include'] = VC_ENV['include']
+            # On x86, 'vcvars32.bat amd64' creates an env that doesn't work;
+            # to cross compile, you use 'x86_amd64'.
+            # On AMD64, 'vcvars32.bat amd64' is a native build env; to cross
+            # compile use 'x86' (ie, it runs the x86 compiler directly)
+            # No idea how itanium handles this, if at all.
+            if plat_name == get_platform() or plat_name == 'win32':
+                # native build or cross-compile to win32
+                plat_spec = PLAT_TO_VCVARS[plat_name]
+            else:
+                # cross compile from win32 -> some 64bit
+                plat_spec = PLAT_TO_VCVARS[get_platform()] + '_' + \
+                            PLAT_TO_VCVARS[plat_name]
+
+            vc_env = query_vcvarsall(VERSION, plat_spec)
+
+            self.__paths = vc_env['path'].split(os.pathsep)
+            os.environ['lib'] = vc_env['lib']
+            os.environ['include'] = vc_env['include']
 
             if len(self.__paths) == 0:
                 raise DistutilsPlatformError("Python was built with %s, "
index f3acb53477e5a0035e4ff564d182dbbf2b018fd5..30a9fc6f223e32a7b52f8d5d9cb66e11d0caf8d0 100644 (file)
@@ -656,5 +656,5 @@ if get_build_version() >= 8.0:
     log.debug("Importing new compiler from distutils.msvc9compiler")
     OldMSVCCompiler = MSVCCompiler
     from distutils.msvc9compiler import MSVCCompiler
-    from distutils.msvc9compiler import get_build_architecture
+    # get_build_architecture not really relevant now we support cross-compile
     from distutils.msvc9compiler import MacroExpander
index deb9a0a0f1a551d664e2357522a523d17f1c0810..69d90cffb87d7acf1b3165a0cd8ff7ef95fc7475 100644 (file)
@@ -30,7 +30,7 @@ def get_platform ():
        irix64-6.2
 
     Windows will return one of:
-       win-x86_64 (64bit Windows on x86_64 (AMD64))
+       win-amd64 (64bit Windows on AMD64 (aka x86_64, Intel64, EM64T, etc)
        win-ia64 (64bit Windows on Itanium)
        win32 (all others - specifically, sys.platform is returned)
 
@@ -45,7 +45,7 @@ def get_platform ():
         j = string.find(sys.version, ")", i)
         look = sys.version[i+len(prefix):j].lower()
         if look=='amd64':
-            return 'win-x86_64'
+            return 'win-amd64'
         if look=='itanium':
             return 'win-ia64'
         return sys.platform
index a87d3e0a935bd7f309c172d605a3a10c6bce3777..eaabcb2f7dd2f15ebafccde21e8207295171b2c8 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -18,6 +18,10 @@ Extensions Modules
 Library
 -------
 
+- Issue #2513: distutils on Windows is now capable of cross-compiling 
+  extension modules between 32 and 64 bit platforms.  See the distutls
+  build documentation for more information.
+
 - Issue #815646: Individual file objects may now be used from multiple
   threads at once without fear of crashing the Python interpreter.  If
   file.close() is called while an object is in use by another thread
index 37a9c29cafc96a15b519bd85cb17f1879149981b..b83888c991647b3440fc1f125cffc5a2b4ad2dfe 100644 (file)
@@ -2,12 +2,34 @@ Example Python extension for Windows NT
 =======================================
 
 This directory contains everything needed (except for the Python
-distribution!) to build a Python extension module using Microsoft VC++
-("Developer Studio") version 7.1.  It has been tested with VC++ 7.1 on 
-Python 2.4.  You can also use earlier versions of VC to build Python 
-extensions, but the sample VC project file (example.dsw in this directory) 
-is in VC 7.1 format. Notice that you need to use the same compiler version
-that was used to build Python itself.
+distribution!) to build a Python extension module using Microsoft VC++.
+Notice that you need to use the same compiler version that was used to build 
+Python itself.
+
+The simplest way to build this example is to use the distutils script
+'setup.py'.  To do this, simply execute:
+
+  % python setup.py install
+
+after everything builds and installs, you can test it:
+
+  % python -c "import example; example.foo()"
+  Hello, world
+
+See setup.py for more details.  alternatively, see below for instructions on 
+how to build inside the Visual Studio environment.
+
+Visual Studio Build Instructions
+================================
+
+These are instructions how to build an extension using Visual C++.  The
+instructions and project files have not been updated to the latest VC
+version.  In general, it is recommended you use the 'setup.py' instructions
+above.
+
+It has been tested with VC++ 7.1 on Python 2.4.  You can also use earlier 
+versions of VC to build Python extensions, but the sample VC project file 
+(example.dsw in this directory) is in VC 7.1 format.
 
 COPY THIS DIRECTORY!
 --------------------
diff --git a/PC/example_nt/setup.py b/PC/example_nt/setup.py
new file mode 100644 (file)
index 0000000..0443bc7
--- /dev/null
@@ -0,0 +1,22 @@
+# This is an example of a distutils 'setup' script for the example_nt
+# sample.  This provides a simpler way of building your extension
+# and means you can avoid keeping MSVC solution files etc in source-control.
+# It also means it should magically build with all compilers supported by
+# python.
+
+# USAGE: you probably want 'setup.py install' - but execute 'setup.py --help'
+# for all the details.
+
+# NOTE: This is *not* a sample for distutils - it is just the smallest
+# script that can build this.  See distutils docs for more info.
+
+from distutils.core import setup, Extension
+
+example_mod = Extension('example', sources = ['example.c'])
+
+
+setup(name = "example",
+    version = "1.0",
+    description = "A sample extension module",
+    ext_modules = [example_mod],
+)
index 414f7edae503c473df4c4ad9f423a8e48a9e0675..1f96826bfa38f4f398a0389b9f25f009a6e0f75c 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="Windows-1252"?>\r
 <VisualStudioProject\r
        ProjectType="Visual C++"\r
-       Version="9,00"\r
+       Version="9.00"\r
        Name="bdist_wininst"\r
        ProjectGUID="{EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}"\r
        RootNamespace="wininst"\r
@@ -11,6 +11,9 @@
                <Platform\r
                        Name="Win32"\r
                />\r
+               <Platform\r
+                       Name="x64"\r
+               />\r
        </Platforms>\r
        <ToolFiles>\r
        </ToolFiles>\r
                                Name="VCPostBuildEventTool"\r
                        />\r
                </Configuration>\r
+               <Configuration\r
+                       Name="Release|x64"\r
+                       OutputDirectory="$(PlatformName)\$(ConfigurationName)"\r
+                       IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"\r
+                       ConfigurationType="1"\r
+                       InheritedPropertySheets=".\pyproject.vsprops;.\release.vsprops"\r
+                       UseOfMFC="0"\r
+                       ATLMinimizesCRunTimeLibraryUsage="false"\r
+                       CharacterSet="0"\r
+                       >\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXMLDataGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                               PreprocessorDefinitions="NDEBUG"\r
+                               MkTypLibCompatible="true"\r
+                               SuppressStartupBanner="true"\r
+                               TargetEnvironment="3"\r
+                               TypeLibraryName=".\..\lib\distutils\command\wininst.tlb"\r
+                               HeaderFileName=""\r
+                       />\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               Optimization="1"\r
+                               InlineFunctionExpansion="1"\r
+                               AdditionalIncludeDirectories="..\PC\bdist_wininst;..\Include;..\Modules\zlib"\r
+                               PreprocessorDefinitions="_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE"\r
+                               StringPooling="true"\r
+                               RuntimeLibrary="2"\r
+                               EnableFunctionLevelLinking="true"\r
+                               WarningLevel="3"\r
+                               SuppressStartupBanner="true"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManagedResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                               PreprocessorDefinitions="NDEBUG"\r
+                               Culture="0"\r
+                               AdditionalIncludeDirectories="..\PC;..\PC\bdist_wininst;..\Include"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               AdditionalDependencies="comctl32.lib imagehlp.lib"\r
+                               OutputFile="..\lib\distutils\command\wininst-9.0-amd64.exe"\r
+                               LinkIncremental="1"\r
+                               SuppressStartupBanner="true"\r
+                               IgnoreDefaultLibraryNames="LIBC"\r
+                               ProgramDatabaseFile="..\lib\distutils\command\wininst-9.0-amd64.pdb"\r
+                               SubSystem="2"\r
+                               RandomizedBaseAddress="1"\r
+                               DataExecutionPrevention="0"\r
+                               TargetMachine="17"\r
+                       />\r
+                       <Tool\r
+                               Name="VCALinkTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManifestTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXDCMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCBscMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCFxCopTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCAppVerifierTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"\r
+                       />\r
+               </Configuration>\r
        </Configurations>\r
        <References>\r
        </References>\r
index a12c05592317facc2ca2fec467b1d60693fc48ab..d534d7ee540d46e4b3a73d5faa744c3a5da663d6 100644 (file)
@@ -482,13 +482,13 @@ Global
                {D06B6426-4762-44CC-8BAD-D79052507F2F}.Release|x64.ActiveCfg = Release|x64
                {D06B6426-4762-44CC-8BAD-D79052507F2F}.Release|x64.Build.0 = Release|x64
                {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.Debug|Win32.ActiveCfg = Release|Win32
-               {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.Debug|x64.ActiveCfg = Release|Win32
+               {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.Debug|x64.ActiveCfg = Release|x64
                {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.PGInstrument|Win32.ActiveCfg = Release|Win32
-               {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.PGInstrument|x64.ActiveCfg = Release|Win32
+               {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.PGInstrument|x64.ActiveCfg = Release|x64
                {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.PGUpdate|Win32.ActiveCfg = Release|Win32
-               {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.PGUpdate|x64.ActiveCfg = Release|Win32
+               {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.PGUpdate|x64.ActiveCfg = Release|x64
                {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.Release|Win32.ActiveCfg = Release|Win32
-               {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.Release|x64.ActiveCfg = Release|Win32
+               {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.Release|x64.ActiveCfg = Release|x64
                {447F05A8-F581-4CAC-A466-5AC7936E207E}.Debug|Win32.ActiveCfg = Debug|Win32
                {447F05A8-F581-4CAC-A466-5AC7936E207E}.Debug|Win32.Build.0 = Debug|Win32
                {447F05A8-F581-4CAC-A466-5AC7936E207E}.Debug|x64.ActiveCfg = Debug|x64