mirror of https://github.com/python/cpython
Issue #2513: enable 64bit cross compilation on windows.
This commit is contained in:
parent
aa63d0d4af
commit
495cf99aaf
|
@ -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
|
The installer file will be written to the "distribution directory" --- normally
|
||||||
:file:`dist/`, but customizable with the :option:`--dist-dir` option.
|
: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:
|
.. _postinstallation-script:
|
||||||
|
|
||||||
|
|
|
@ -97,7 +97,10 @@ class bdist (Command):
|
||||||
def finalize_options (self):
|
def finalize_options (self):
|
||||||
# have to finalize 'plat_name' before 'bdist_base'
|
# have to finalize 'plat_name' before 'bdist_base'
|
||||||
if self.plat_name is None:
|
if self.plat_name is None:
|
||||||
|
if self.skip_build:
|
||||||
self.plat_name = get_platform()
|
self.plat_name = get_platform()
|
||||||
|
else:
|
||||||
|
self.plat_name = self.get_finalized_command('build').plat_name
|
||||||
|
|
||||||
# 'bdist_base' -- parent of per-built-distribution-format
|
# 'bdist_base' -- parent of per-built-distribution-format
|
||||||
# temporary directories (eg. we'll probably have
|
# temporary directories (eg. we'll probably have
|
||||||
|
@ -121,7 +124,6 @@ class bdist (Command):
|
||||||
|
|
||||||
# finalize_options()
|
# finalize_options()
|
||||||
|
|
||||||
|
|
||||||
def run (self):
|
def run (self):
|
||||||
|
|
||||||
# Figure out which sub-commands we need to run.
|
# Figure out which sub-commands we need to run.
|
||||||
|
|
|
@ -9,11 +9,11 @@ Implements the bdist_msi command.
|
||||||
|
|
||||||
import sys, os
|
import sys, os
|
||||||
from distutils.core import Command
|
from distutils.core import Command
|
||||||
from distutils.util import get_platform
|
|
||||||
from distutils.dir_util import remove_tree
|
from distutils.dir_util import remove_tree
|
||||||
from distutils.sysconfig import get_python_version
|
from distutils.sysconfig import get_python_version
|
||||||
from distutils.version import StrictVersion
|
from distutils.version import StrictVersion
|
||||||
from distutils.errors import DistutilsOptionError
|
from distutils.errors import DistutilsOptionError
|
||||||
|
from distutils.util import get_platform
|
||||||
from distutils import log
|
from distutils import log
|
||||||
import msilib
|
import msilib
|
||||||
from msilib import schema, sequence, text
|
from msilib import schema, sequence, text
|
||||||
|
@ -87,6 +87,9 @@ class bdist_msi (Command):
|
||||||
|
|
||||||
user_options = [('bdist-dir=', None,
|
user_options = [('bdist-dir=', None,
|
||||||
"temporary directory for creating the distribution"),
|
"temporary directory for creating the distribution"),
|
||||||
|
('plat-name=', 'p',
|
||||||
|
"platform name to embed in generated filenames "
|
||||||
|
"(default: %s)" % get_platform()),
|
||||||
('keep-temp', 'k',
|
('keep-temp', 'k',
|
||||||
"keep the pseudo-installation tree around after " +
|
"keep the pseudo-installation tree around after " +
|
||||||
"creating the distribution archive"),
|
"creating the distribution archive"),
|
||||||
|
@ -116,6 +119,7 @@ class bdist_msi (Command):
|
||||||
|
|
||||||
def initialize_options (self):
|
def initialize_options (self):
|
||||||
self.bdist_dir = None
|
self.bdist_dir = None
|
||||||
|
self.plat_name = None
|
||||||
self.keep_temp = 0
|
self.keep_temp = 0
|
||||||
self.no_target_compile = 0
|
self.no_target_compile = 0
|
||||||
self.no_target_optimize = 0
|
self.no_target_optimize = 0
|
||||||
|
@ -139,7 +143,10 @@ class bdist_msi (Command):
|
||||||
else:
|
else:
|
||||||
self.target_version = 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.pre_install_script:
|
if self.pre_install_script:
|
||||||
raise DistutilsOptionError, "the pre-install-script feature is not yet implemented"
|
raise DistutilsOptionError, "the pre-install-script feature is not yet implemented"
|
||||||
|
@ -181,7 +188,7 @@ class bdist_msi (Command):
|
||||||
if not target_version:
|
if not target_version:
|
||||||
assert self.skip_build, "Should have already checked this"
|
assert self.skip_build, "Should have already checked this"
|
||||||
target_version = sys.version[0:3]
|
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 = self.get_finalized_command('build')
|
||||||
build.build_lib = os.path.join(build.build_base,
|
build.build_lib = os.path.join(build.build_base,
|
||||||
'lib' + plat_specifier)
|
'lib' + plat_specifier)
|
||||||
|
@ -633,8 +640,7 @@ class bdist_msi (Command):
|
||||||
|
|
||||||
def get_installer_filename(self, fullname):
|
def get_installer_filename(self, fullname):
|
||||||
# Factored out to allow overriding in subclasses
|
# Factored out to allow overriding in subclasses
|
||||||
plat = get_platform()
|
base_name = "%s.%s-py%s.msi" % (fullname, self.plat_name,
|
||||||
installer_name = os.path.join(self.dist_dir,
|
self.target_version)
|
||||||
"%s.%s-py%s.msi" %
|
installer_name = os.path.join(self.dist_dir, base_name)
|
||||||
(fullname, plat, self.target_version))
|
|
||||||
return installer_name
|
return installer_name
|
||||||
|
|
|
@ -21,6 +21,9 @@ class bdist_wininst (Command):
|
||||||
|
|
||||||
user_options = [('bdist-dir=', None,
|
user_options = [('bdist-dir=', None,
|
||||||
"temporary directory for creating the distribution"),
|
"temporary directory for creating the distribution"),
|
||||||
|
('plat-name=', 'p',
|
||||||
|
"platform name to embed in generated filenames "
|
||||||
|
"(default: %s)" % get_platform()),
|
||||||
('keep-temp', 'k',
|
('keep-temp', 'k',
|
||||||
"keep the pseudo-installation tree around after " +
|
"keep the pseudo-installation tree around after " +
|
||||||
"creating the distribution archive"),
|
"creating the distribution archive"),
|
||||||
|
@ -54,6 +57,7 @@ class bdist_wininst (Command):
|
||||||
|
|
||||||
def initialize_options (self):
|
def initialize_options (self):
|
||||||
self.bdist_dir = None
|
self.bdist_dir = None
|
||||||
|
self.plat_name = None
|
||||||
self.keep_temp = 0
|
self.keep_temp = 0
|
||||||
self.no_target_compile = 0
|
self.no_target_compile = 0
|
||||||
self.no_target_optimize = 0
|
self.no_target_optimize = 0
|
||||||
|
@ -82,7 +86,10 @@ class bdist_wininst (Command):
|
||||||
" option must be specified" % (short_version,)
|
" option must be specified" % (short_version,)
|
||||||
self.target_version = 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:
|
if self.install_script:
|
||||||
for script in self.distribution.scripts:
|
for script in self.distribution.scripts:
|
||||||
|
@ -110,6 +117,7 @@ class bdist_wininst (Command):
|
||||||
install.root = self.bdist_dir
|
install.root = self.bdist_dir
|
||||||
install.skip_build = self.skip_build
|
install.skip_build = self.skip_build
|
||||||
install.warn_dir = 0
|
install.warn_dir = 0
|
||||||
|
install.plat_name = self.plat_name
|
||||||
|
|
||||||
install_lib = self.reinitialize_command('install_lib')
|
install_lib = self.reinitialize_command('install_lib')
|
||||||
# we do not want to include pyc or pyo files
|
# we do not want to include pyc or pyo files
|
||||||
|
@ -127,7 +135,7 @@ class bdist_wininst (Command):
|
||||||
if not target_version:
|
if not target_version:
|
||||||
assert self.skip_build, "Should have already checked this"
|
assert self.skip_build, "Should have already checked this"
|
||||||
target_version = sys.version[0:3]
|
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 = self.get_finalized_command('build')
|
||||||
build.build_lib = os.path.join(build.build_base,
|
build.build_lib = os.path.join(build.build_base,
|
||||||
'lib' + plat_specifier)
|
'lib' + plat_specifier)
|
||||||
|
@ -285,11 +293,11 @@ class bdist_wininst (Command):
|
||||||
# if we create an installer for a specific python version,
|
# if we create an installer for a specific python version,
|
||||||
# it's better to include this in the name
|
# it's better to include this in the name
|
||||||
installer_name = os.path.join(self.dist_dir,
|
installer_name = os.path.join(self.dist_dir,
|
||||||
"%s.win32-py%s.exe" %
|
"%s.%s-py%s.exe" %
|
||||||
(fullname, self.target_version))
|
(fullname, self.plat_name, self.target_version))
|
||||||
else:
|
else:
|
||||||
installer_name = os.path.join(self.dist_dir,
|
installer_name = os.path.join(self.dist_dir,
|
||||||
"%s.win32.exe" % fullname)
|
"%s.%s.exe" % (fullname, self.plat_name))
|
||||||
return installer_name
|
return installer_name
|
||||||
# get_installer_filename()
|
# get_installer_filename()
|
||||||
|
|
||||||
|
@ -312,9 +320,9 @@ class bdist_wininst (Command):
|
||||||
bv = get_build_version()
|
bv = get_build_version()
|
||||||
else:
|
else:
|
||||||
if self.target_version < "2.4":
|
if self.target_version < "2.4":
|
||||||
bv = "6"
|
bv = 6.0
|
||||||
else:
|
else:
|
||||||
bv = "7.1"
|
bv = 7.1
|
||||||
else:
|
else:
|
||||||
# for current version - use authoritative check.
|
# for current version - use authoritative check.
|
||||||
bv = get_build_version()
|
bv = get_build_version()
|
||||||
|
@ -323,6 +331,10 @@ class bdist_wininst (Command):
|
||||||
directory = os.path.dirname(__file__)
|
directory = os.path.dirname(__file__)
|
||||||
# we must use a wininst-x.y.exe built with the same C compiler
|
# 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?
|
# 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()
|
return open(filename, "rb").read()
|
||||||
# class bdist_wininst
|
# class bdist_wininst
|
||||||
|
|
|
@ -8,6 +8,7 @@ __revision__ = "$Id$"
|
||||||
|
|
||||||
import sys, os
|
import sys, os
|
||||||
from distutils.core import Command
|
from distutils.core import Command
|
||||||
|
from distutils.errors import DistutilsOptionError
|
||||||
from distutils.util import get_platform
|
from distutils.util import get_platform
|
||||||
|
|
||||||
|
|
||||||
|
@ -34,6 +35,9 @@ class build (Command):
|
||||||
"build directory for scripts"),
|
"build directory for scripts"),
|
||||||
('build-temp=', 't',
|
('build-temp=', 't',
|
||||||
"temporary build directory"),
|
"temporary build directory"),
|
||||||
|
('plat-name=', 'p',
|
||||||
|
"platform name to build for, if supported "
|
||||||
|
"(default: %s)" % get_platform()),
|
||||||
('compiler=', 'c',
|
('compiler=', 'c',
|
||||||
"specify the compiler type"),
|
"specify the compiler type"),
|
||||||
('debug', 'g',
|
('debug', 'g',
|
||||||
|
@ -61,13 +65,25 @@ class build (Command):
|
||||||
self.build_temp = None
|
self.build_temp = None
|
||||||
self.build_scripts = None
|
self.build_scripts = None
|
||||||
self.compiler = None
|
self.compiler = None
|
||||||
|
self.plat_name = None
|
||||||
self.debug = None
|
self.debug = None
|
||||||
self.force = 0
|
self.force = 0
|
||||||
self.executable = None
|
self.executable = None
|
||||||
|
|
||||||
def finalize_options (self):
|
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
|
# 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
|
# share the same build directories. Doing so confuses the build
|
||||||
|
|
|
@ -15,6 +15,7 @@ from distutils.errors import *
|
||||||
from distutils.sysconfig import customize_compiler, get_python_version
|
from distutils.sysconfig import customize_compiler, get_python_version
|
||||||
from distutils.dep_util import newer_group
|
from distutils.dep_util import newer_group
|
||||||
from distutils.extension import Extension
|
from distutils.extension import Extension
|
||||||
|
from distutils.util import get_platform
|
||||||
from distutils import log
|
from distutils import log
|
||||||
|
|
||||||
if os.name == 'nt':
|
if os.name == 'nt':
|
||||||
|
@ -60,6 +61,9 @@ class build_ext (Command):
|
||||||
"directory for compiled extension modules"),
|
"directory for compiled extension modules"),
|
||||||
('build-temp=', 't',
|
('build-temp=', 't',
|
||||||
"directory for temporary files (build by-products)"),
|
"directory for temporary files (build by-products)"),
|
||||||
|
('plat-name=', 'p',
|
||||||
|
"platform name to cross-compile for, if supported "
|
||||||
|
"(default: %s)" % get_platform()),
|
||||||
('inplace', 'i',
|
('inplace', 'i',
|
||||||
"ignore build-lib and put compiled extensions into the source " +
|
"ignore build-lib and put compiled extensions into the source " +
|
||||||
"directory alongside your pure Python modules"),
|
"directory alongside your pure Python modules"),
|
||||||
|
@ -101,6 +105,7 @@ class build_ext (Command):
|
||||||
def initialize_options (self):
|
def initialize_options (self):
|
||||||
self.extensions = None
|
self.extensions = None
|
||||||
self.build_lib = None
|
self.build_lib = None
|
||||||
|
self.plat_name = None
|
||||||
self.build_temp = None
|
self.build_temp = None
|
||||||
self.inplace = 0
|
self.inplace = 0
|
||||||
self.package = None
|
self.package = None
|
||||||
|
@ -127,7 +132,9 @@ class build_ext (Command):
|
||||||
('build_temp', 'build_temp'),
|
('build_temp', 'build_temp'),
|
||||||
('compiler', 'compiler'),
|
('compiler', 'compiler'),
|
||||||
('debug', 'debug'),
|
('debug', 'debug'),
|
||||||
('force', 'force'))
|
('force', 'force'),
|
||||||
|
('plat_name', 'plat_name'),
|
||||||
|
)
|
||||||
|
|
||||||
if self.package is None:
|
if self.package is None:
|
||||||
self.package = self.distribution.ext_package
|
self.package = self.distribution.ext_package
|
||||||
|
@ -171,6 +178,9 @@ class build_ext (Command):
|
||||||
# for Release and Debug builds.
|
# for Release and Debug builds.
|
||||||
# also Python's library directory must be appended to library_dirs
|
# also Python's library directory must be appended to library_dirs
|
||||||
if os.name == 'nt':
|
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'))
|
self.library_dirs.append(os.path.join(sys.exec_prefix, 'libs'))
|
||||||
if self.debug:
|
if self.debug:
|
||||||
self.build_temp = os.path.join(self.build_temp, "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
|
# this allows distutils on windows to work in the source tree
|
||||||
self.include_dirs.append(os.path.join(sys.exec_prefix, 'PC'))
|
self.include_dirs.append(os.path.join(sys.exec_prefix, 'PC'))
|
||||||
if MSVC_VERSION == 9:
|
if MSVC_VERSION == 9:
|
||||||
self.library_dirs.append(os.path.join(sys.exec_prefix,
|
# Use the .lib files for the correct architecture
|
||||||
'PCbuild'))
|
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:
|
elif MSVC_VERSION == 8:
|
||||||
self.library_dirs.append(os.path.join(sys.exec_prefix,
|
self.library_dirs.append(os.path.join(sys.exec_prefix,
|
||||||
'PC', 'VS8.0', 'win32release'))
|
'PC', 'VS8.0', 'win32release'))
|
||||||
|
@ -275,6 +294,11 @@ class build_ext (Command):
|
||||||
dry_run=self.dry_run,
|
dry_run=self.dry_run,
|
||||||
force=self.force)
|
force=self.force)
|
||||||
customize_compiler(self.compiler)
|
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
|
# And make sure that any compile/link-related options (which might
|
||||||
# come from the command-line or from the setup script) are set in
|
# come from the command-line or from the setup script) are set in
|
||||||
|
|
|
@ -16,6 +16,7 @@ from distutils.sysconfig import get_config_vars
|
||||||
from distutils.errors import DistutilsPlatformError
|
from distutils.errors import DistutilsPlatformError
|
||||||
from distutils.file_util import write_file
|
from distutils.file_util import write_file
|
||||||
from distutils.util import convert_path, subst_vars, change_root
|
from distutils.util import convert_path, subst_vars, change_root
|
||||||
|
from distutils.util import get_platform
|
||||||
from distutils.errors import DistutilsOptionError
|
from distutils.errors import DistutilsOptionError
|
||||||
|
|
||||||
if sys.version < "2.2":
|
if sys.version < "2.2":
|
||||||
|
@ -503,6 +504,14 @@ class install (Command):
|
||||||
# Obviously have to build before we can install
|
# Obviously have to build before we can install
|
||||||
if not self.skip_build:
|
if not self.skip_build:
|
||||||
self.run_command('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)
|
# Run all sub-commands (at least those that need to be run)
|
||||||
for cmd_name in self.get_sub_commands():
|
for cmd_name in self.get_sub_commands():
|
||||||
|
|
Binary file not shown.
|
@ -22,6 +22,7 @@ from distutils.errors import (DistutilsExecError, DistutilsPlatformError,
|
||||||
from distutils.ccompiler import (CCompiler, gen_preprocess_options,
|
from distutils.ccompiler import (CCompiler, gen_preprocess_options,
|
||||||
gen_lib_options)
|
gen_lib_options)
|
||||||
from distutils import log
|
from distutils import log
|
||||||
|
from distutils.util import get_platform
|
||||||
|
|
||||||
import _winreg
|
import _winreg
|
||||||
|
|
||||||
|
@ -38,13 +39,15 @@ HKEYS = (_winreg.HKEY_USERS,
|
||||||
VS_BASE = r"Software\Microsoft\VisualStudio\%0.1f"
|
VS_BASE = r"Software\Microsoft\VisualStudio\%0.1f"
|
||||||
WINSDK_BASE = r"Software\Microsoft\Microsoft SDKs\Windows"
|
WINSDK_BASE = r"Software\Microsoft\Microsoft SDKs\Windows"
|
||||||
NET_BASE = r"Software\Microsoft\.NETFramework"
|
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:
|
class Reg:
|
||||||
"""Helper class to read values from the registry
|
"""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
|
# else we don't know what version of the compiler this is
|
||||||
return None
|
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):
|
def normalize_and_reduce_paths(paths):
|
||||||
"""Return a list of normalized paths with duplicates removed.
|
"""Return a list of normalized paths with duplicates removed.
|
||||||
|
|
||||||
|
@ -251,6 +237,7 @@ def query_vcvarsall(version, arch="x86"):
|
||||||
|
|
||||||
if vcvarsall is None:
|
if vcvarsall is None:
|
||||||
raise IOError("Unable to find vcvarsall.bat")
|
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),
|
popen = subprocess.Popen('"%s" %s & set' % (vcvarsall, arch),
|
||||||
stdout=subprocess.PIPE,
|
stdout=subprocess.PIPE,
|
||||||
stderr=subprocess.PIPE)
|
stderr=subprocess.PIPE)
|
||||||
|
@ -281,9 +268,7 @@ def query_vcvarsall(version, arch="x86"):
|
||||||
VERSION = get_build_version()
|
VERSION = get_build_version()
|
||||||
if VERSION < 8.0:
|
if VERSION < 8.0:
|
||||||
raise DistutilsPlatformError("VC %0.1f is not supported by this module" % VERSION)
|
raise DistutilsPlatformError("VC %0.1f is not supported by this module" % VERSION)
|
||||||
ARCH = get_build_architecture()
|
|
||||||
# MACROS = MacroExpander(VERSION)
|
# MACROS = MacroExpander(VERSION)
|
||||||
VC_ENV = query_vcvarsall(VERSION, ARCH)
|
|
||||||
|
|
||||||
class MSVCCompiler(CCompiler) :
|
class MSVCCompiler(CCompiler) :
|
||||||
"""Concrete class that implements an interface to Microsoft Visual C++,
|
"""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):
|
def __init__(self, verbose=0, dry_run=0, force=0):
|
||||||
CCompiler.__init__ (self, verbose, dry_run, force)
|
CCompiler.__init__ (self, verbose, dry_run, force)
|
||||||
self.__version = VERSION
|
self.__version = VERSION
|
||||||
self.__arch = ARCH
|
|
||||||
self.__root = r"Software\Microsoft\VisualStudio"
|
self.__root = r"Software\Microsoft\VisualStudio"
|
||||||
# self.__macros = MACROS
|
# self.__macros = MACROS
|
||||||
self.__path = []
|
self.__path = []
|
||||||
|
# target platform (.plat_name is consistent with 'bdist')
|
||||||
|
self.plat_name = None
|
||||||
|
self.__arch = None # deprecated name
|
||||||
self.initialized = False
|
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"):
|
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
|
# Assume that the SDK set up everything alright; don't try to be
|
||||||
# smarter
|
# smarter
|
||||||
|
@ -334,9 +331,24 @@ class MSVCCompiler(CCompiler) :
|
||||||
self.rc = "rc.exe"
|
self.rc = "rc.exe"
|
||||||
self.mc = "mc.exe"
|
self.mc = "mc.exe"
|
||||||
else:
|
else:
|
||||||
self.__paths = VC_ENV['path'].split(os.pathsep)
|
# On x86, 'vcvars32.bat amd64' creates an env that doesn't work;
|
||||||
os.environ['lib'] = VC_ENV['lib']
|
# to cross compile, you use 'x86_amd64'.
|
||||||
os.environ['include'] = VC_ENV['include']
|
# 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:
|
if len(self.__paths) == 0:
|
||||||
raise DistutilsPlatformError("Python was built with %s, "
|
raise DistutilsPlatformError("Python was built with %s, "
|
||||||
|
|
|
@ -656,5 +656,5 @@ if get_build_version() >= 8.0:
|
||||||
log.debug("Importing new compiler from distutils.msvc9compiler")
|
log.debug("Importing new compiler from distutils.msvc9compiler")
|
||||||
OldMSVCCompiler = MSVCCompiler
|
OldMSVCCompiler = MSVCCompiler
|
||||||
from distutils.msvc9compiler import 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
|
from distutils.msvc9compiler import MacroExpander
|
||||||
|
|
|
@ -30,7 +30,7 @@ def get_platform ():
|
||||||
irix64-6.2
|
irix64-6.2
|
||||||
|
|
||||||
Windows will return one of:
|
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)
|
win-ia64 (64bit Windows on Itanium)
|
||||||
win32 (all others - specifically, sys.platform is returned)
|
win32 (all others - specifically, sys.platform is returned)
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ def get_platform ():
|
||||||
j = string.find(sys.version, ")", i)
|
j = string.find(sys.version, ")", i)
|
||||||
look = sys.version[i+len(prefix):j].lower()
|
look = sys.version[i+len(prefix):j].lower()
|
||||||
if look=='amd64':
|
if look=='amd64':
|
||||||
return 'win-x86_64'
|
return 'win-amd64'
|
||||||
if look=='itanium':
|
if look=='itanium':
|
||||||
return 'win-ia64'
|
return 'win-ia64'
|
||||||
return sys.platform
|
return sys.platform
|
||||||
|
|
|
@ -18,6 +18,10 @@ Extensions Modules
|
||||||
Library
|
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
|
- Issue #815646: Individual file objects may now be used from multiple
|
||||||
threads at once without fear of crashing the Python interpreter. If
|
threads at once without fear of crashing the Python interpreter. If
|
||||||
file.close() is called while an object is in use by another thread
|
file.close() is called while an object is in use by another thread
|
||||||
|
|
|
@ -2,12 +2,34 @@ Example Python extension for Windows NT
|
||||||
=======================================
|
=======================================
|
||||||
|
|
||||||
This directory contains everything needed (except for the Python
|
This directory contains everything needed (except for the Python
|
||||||
distribution!) to build a Python extension module using Microsoft VC++
|
distribution!) to build a Python extension module using Microsoft VC++.
|
||||||
("Developer Studio") version 7.1. It has been tested with VC++ 7.1 on
|
Notice that you need to use the same compiler version that was used to build
|
||||||
Python 2.4. You can also use earlier versions of VC to build Python
|
Python itself.
|
||||||
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
|
The simplest way to build this example is to use the distutils script
|
||||||
that was used to build Python itself.
|
'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!
|
COPY THIS DIRECTORY!
|
||||||
--------------------
|
--------------------
|
||||||
|
|
|
@ -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],
|
||||||
|
)
|
|
@ -1,7 +1,7 @@
|
||||||
<?xml version="1.0" encoding="Windows-1252"?>
|
<?xml version="1.0" encoding="Windows-1252"?>
|
||||||
<VisualStudioProject
|
<VisualStudioProject
|
||||||
ProjectType="Visual C++"
|
ProjectType="Visual C++"
|
||||||
Version="9,00"
|
Version="9.00"
|
||||||
Name="bdist_wininst"
|
Name="bdist_wininst"
|
||||||
ProjectGUID="{EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}"
|
ProjectGUID="{EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}"
|
||||||
RootNamespace="wininst"
|
RootNamespace="wininst"
|
||||||
|
@ -11,6 +11,9 @@
|
||||||
<Platform
|
<Platform
|
||||||
Name="Win32"
|
Name="Win32"
|
||||||
/>
|
/>
|
||||||
|
<Platform
|
||||||
|
Name="x64"
|
||||||
|
/>
|
||||||
</Platforms>
|
</Platforms>
|
||||||
<ToolFiles>
|
<ToolFiles>
|
||||||
</ToolFiles>
|
</ToolFiles>
|
||||||
|
@ -104,6 +107,96 @@
|
||||||
Name="VCPostBuildEventTool"
|
Name="VCPostBuildEventTool"
|
||||||
/>
|
/>
|
||||||
</Configuration>
|
</Configuration>
|
||||||
|
<Configuration
|
||||||
|
Name="Release|x64"
|
||||||
|
OutputDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||||
|
ConfigurationType="1"
|
||||||
|
InheritedPropertySheets=".\pyproject.vsprops;.\release.vsprops"
|
||||||
|
UseOfMFC="0"
|
||||||
|
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||||
|
CharacterSet="0"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
PreprocessorDefinitions="NDEBUG"
|
||||||
|
MkTypLibCompatible="true"
|
||||||
|
SuppressStartupBanner="true"
|
||||||
|
TargetEnvironment="3"
|
||||||
|
TypeLibraryName=".\..\lib\distutils\command\wininst.tlb"
|
||||||
|
HeaderFileName=""
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="1"
|
||||||
|
InlineFunctionExpansion="1"
|
||||||
|
AdditionalIncludeDirectories="..\PC\bdist_wininst;..\Include;..\Modules\zlib"
|
||||||
|
PreprocessorDefinitions="_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE"
|
||||||
|
StringPooling="true"
|
||||||
|
RuntimeLibrary="2"
|
||||||
|
EnableFunctionLevelLinking="true"
|
||||||
|
WarningLevel="3"
|
||||||
|
SuppressStartupBanner="true"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
PreprocessorDefinitions="NDEBUG"
|
||||||
|
Culture="0"
|
||||||
|
AdditionalIncludeDirectories="..\PC;..\PC\bdist_wininst;..\Include"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLinkerTool"
|
||||||
|
AdditionalDependencies="comctl32.lib imagehlp.lib"
|
||||||
|
OutputFile="..\lib\distutils\command\wininst-9.0-amd64.exe"
|
||||||
|
LinkIncremental="1"
|
||||||
|
SuppressStartupBanner="true"
|
||||||
|
IgnoreDefaultLibraryNames="LIBC"
|
||||||
|
ProgramDatabaseFile="..\lib\distutils\command\wininst-9.0-amd64.pdb"
|
||||||
|
SubSystem="2"
|
||||||
|
RandomizedBaseAddress="1"
|
||||||
|
DataExecutionPrevention="0"
|
||||||
|
TargetMachine="17"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManifestTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCAppVerifierTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
</Configurations>
|
</Configurations>
|
||||||
<References>
|
<References>
|
||||||
</References>
|
</References>
|
||||||
|
|
|
@ -482,13 +482,13 @@ Global
|
||||||
{D06B6426-4762-44CC-8BAD-D79052507F2F}.Release|x64.ActiveCfg = Release|x64
|
{D06B6426-4762-44CC-8BAD-D79052507F2F}.Release|x64.ActiveCfg = Release|x64
|
||||||
{D06B6426-4762-44CC-8BAD-D79052507F2F}.Release|x64.Build.0 = 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|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|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|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|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.ActiveCfg = Debug|Win32
|
||||||
{447F05A8-F581-4CAC-A466-5AC7936E207E}.Debug|Win32.Build.0 = Debug|Win32
|
{447F05A8-F581-4CAC-A466-5AC7936E207E}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
{447F05A8-F581-4CAC-A466-5AC7936E207E}.Debug|x64.ActiveCfg = Debug|x64
|
{447F05A8-F581-4CAC-A466-5AC7936E207E}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
|
Loading…
Reference in New Issue