Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(4)

Unified Diff: setup.py

Issue 3871: cross and native build of python for mingw32 with distutils
Patch Set: Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « setup_info.in ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
--- a/setup.py Thu Dec 27 23:52:36 2012 +0200
+++ b/setup.py Thu Dec 27 17:35:12 2012 -0500
@@ -191,7 +191,7 @@
# with Modules/.
srcdir = sysconfig.get_config_var('srcdir')
if not srcdir:
- # Maybe running on Windows but not using CYGWIN?
+ # Maybe running on Windows but not using posix build?
raise ValueError("No source directory; cannot proceed.")
srcdir = os.path.abspath(srcdir)
moddirlist = [os.path.join(srcdir, 'Modules')]
@@ -245,8 +245,38 @@
# compilers
if compiler is not None:
(ccshared,cflags) = sysconfig.get_config_vars('CCSHARED','CFLAGS')
- args['compiler_so'] = compiler + ' ' + ccshared + ' ' + cflags
- self.compiler.set_executables(**args)
+ # distutils set first cflags then ccshared
+ args['compiler_so'] = compiler + ' ' + cflags + ' ' + ccshared
+
+ # FIXME: Is next correct ?
+ # To link modules we need LDSHARED passed to setup.py otherwise
+ # distutils will use linker from build system if cross-compiling.
+ linker_so = os.environ.get('LDSHARED')
+ if linker_so is not None:
+ args['linker_so'] = linker_so
+
+ #NO. lines above just override already customised compiler values
+ #self.compiler.set_executables(**args)
+
+ if host_platform in ['mingw', 'win32']:
+ data = open('pyconfig.h').read()
+ m = re.search(r"#s*define\s+Py_DEBUG\s+1\s*", data)
+ if m is not None:
+ self.compiler.libraries.append("python" + str(sysconfig.get_config_var('VERSION')) + "_d")
+ else:
+ self.compiler.libraries.append("python" + str(sysconfig.get_config_var('VERSION')))
+
+ if host_platform in ['mingw', 'win32']:
+ # NOTE: See comment for SHLIBS in configure.in .
+ # Although it look obsolete since setup.py add module
+ # required libraries we will pass list too.
+ # As example this will allow us to propage static
+ # libraries like mingwex to modules.
+ for lib in sysconfig.get_config_var('SHLIBS').split():
+ if lib.startswith('-l'):
+ self.compiler.libraries.append(lib[2:])
+ else:
+ self.compiler.libraries.append(lib)
build_ext.build_extensions(self)
@@ -318,6 +348,10 @@
self.announce('WARNING: skipping import check for Cygwin-based "%s"'
% ext.name)
return
+ if cross_compiling:
+ self.announce('WARNING: skipping import check for cross-compiled "%s"'
+ % ext.name)
+ return
ext_filename = os.path.join(
self.build_lib,
self.get_ext_filename(self.get_ext_fullname(ext.name)))
@@ -441,6 +475,9 @@
os.unlink(tmpfile)
def detect_modules(self):
+ pyconfig_h_data = open('pyconfig.h').read()
+ setup_info_data = open('setup_info').read()
+
# Ensure that /usr/local is always used, but the local build
# directories (i.e. '.' and 'Include') must be first. See issue
# 10520.
@@ -492,6 +529,11 @@
# (PYTHONFRAMEWORK is set) to avoid # linking problems when
# building a framework with different architectures than
# the one that is currently installed (issue #7473)
+ # NOTE: revision 25103:[ #420565 ] add search in sys.prefix
+ # before current source tree !?!?!?! No comment!
+ # Since add_dir_to_list prepend path issue with library paths
+ # is silently fixed ;) but introduce new one for header paths
+ # as path must be appended !
add_dir_to_list(self.compiler.library_dirs,
sysconfig.get_config_var("LIBDIR"))
add_dir_to_list(self.compiler.include_dirs,
@@ -526,7 +568,7 @@
if host_platform == 'hp-ux11':
lib_dirs += ['/usr/lib/hpux64', '/usr/lib/hpux32']
- if host_platform == 'darwin':
+ if host_platform in ['darwin', 'mingw', 'win32']:
# This should work on any unixy platform ;-)
# If the user has bothered specifying additional -I and -L flags
# in OPT and LDFLAGS we might as well use them here.
@@ -534,6 +576,7 @@
# NOTE: using shlex.split would technically be more correct, but
# also gives a bootstrap problem. Let's hope nobody uses
# directories with whitespace in the name to store libraries.
+ # FIXME: Why LDFLAGS again ?
cflags, ldflags = sysconfig.get_config_vars(
'CFLAGS', 'LDFLAGS')
for item in cflags.split():
@@ -546,7 +589,7 @@
# Check for MacOS X, which doesn't need libm.a at all
math_libs = ['m']
- if host_platform == 'darwin':
+ if host_platform in ['darwin', 'mingw', 'win32']:
math_libs = []
# XXX Omitted modules: gl, pure, dl, SGI-specific modules
@@ -570,6 +613,7 @@
# time libraries: librt may be needed for clock_gettime()
time_libs = []
lib = sysconfig.get_config_var('TIMEMODULE_LIB')
+
if lib:
time_libs.append(lib)
@@ -604,24 +648,35 @@
# supported...)
# fcntl(2) and ioctl(2)
- libs = []
- if (config_h_vars.get('FLOCK_NEEDS_LIBBSD', False)):
- # May be necessary on AIX for flock function
- libs = ['bsd']
- exts.append( Extension('fcntl', ['fcntlmodule.c'], libraries=libs) )
- # pwd(3)
- exts.append( Extension('pwd', ['pwdmodule.c']) )
- # grp(3)
- exts.append( Extension('grp', ['grpmodule.c']) )
- # spwd, shadow passwords
- if (config_h_vars.get('HAVE_GETSPNAM', False) or
- config_h_vars.get('HAVE_GETSPENT', False)):
- exts.append( Extension('spwd', ['spwdmodule.c']) )
+ if host_platform not in ['mingw', 'win32']:
+ libs = []
+ if (config_h_vars.get('FLOCK_NEEDS_LIBBSD', False)):
+ # May be necessary on AIX for flock function
+ libs = ['bsd']
+ exts.append( Extension('fcntl', ['fcntlmodule.c'], libraries=libs) )
else:
- missing.append('spwd')
+ missing.append('fcntl')
+ if host_platform not in ['mingw', 'win32']:
+ # pwd(3)
+ exts.append( Extension('pwd', ['pwdmodule.c']) )
+ # grp(3)
+ exts.append( Extension('grp', ['grpmodule.c']) )
+ # spwd, shadow passwords
+ if (config_h_vars.get('HAVE_GETSPNAM', False) or
+ config_h_vars.get('HAVE_GETSPENT', False)):
+ exts.append( Extension('spwd', ['spwdmodule.c']) )
+ else:
+ missing.append('spwd')
+ else:
+ missing.extend(['pwd', 'grp', 'spwd'])
# select(2); not on ancient System V
- exts.append( Extension('select', ['selectmodule.c']) )
+ if host_platform in ['mingw', 'win32']:
+ select_libs = ['ws2_32']
+ else:
+ select_libs = []
+ exts.append( Extension('select', ['selectmodule.c'],
+ libraries=select_libs) )
# Fred Drake's interface to the Python parser
exts.append( Extension('parser', ['parsermodule.c']) )
@@ -630,8 +685,11 @@
exts.append( Extension('mmap', ['mmapmodule.c']) )
# Lance Ellinghaus's syslog module
- # syslog daemon interface
- exts.append( Extension('syslog', ['syslogmodule.c']) )
+ if host_platform not in ['mingw', 'win32']:
+ # syslog daemon interface
+ exts.append( Extension('syslog', ['syslogmodule.c']) )
+ else:
+ missing.append('syslog')
#
# Here ends the simple stuff. From here on, modules need certain
@@ -648,7 +706,8 @@
exts.append( Extension('audioop', ['audioop.c']) )
# readline
- do_readline = self.compiler.find_library_file(lib_dirs, 'readline')
+ do_readline = re.search(r"#s*define\s+HAVE_LIBREADLINE\s+1\s*", pyconfig_h_data)
+
readline_termcap_library = ""
curses_library = ""
# Cannot use os.popen here in py3k.
@@ -656,9 +715,31 @@
if not os.path.exists(self.build_temp):
os.makedirs(self.build_temp)
# Determine if readline is already linked against curses or tinfo.
+ # NOTE readline_termcap_library flag is used only if
+ # cannot determine readline libs (see configure.in checks)
+ readline_conf = False
+ readline_conf_termcap = ""
if do_readline:
+ m = re.search(
+ r"\s*READLINE_LIBS\s*=\s*(?P<rl>-l.*)",
+ setup_info_data
+ )
+ if m:
+ readline_conf = True
+ ln = m.group('rl')
+ if 'curses' in ln:
+ readline_conf_termcap = re.sub(
+ r'.*-l(n?cursesw?).*', r'\1', ln
+ ).rstrip()
+ elif 'tinfo' in ln: # termcap interface split out from ncurses
+ readline_conf_termcap = 'tinfo'
+ else: # may be readline is linked with termcap interface library
+ readline_conf = False
+
+ if do_readline and not readline_conf and find_executable('ldd'):
+ do_readline = self.compiler.find_library_file(lib_dirs, 'readline')
if cross_compiling:
- ret = os.system("%s -d %s | grep '(NEEDED)' > %s" \
+ ret = os.system("%s -d %s 2>/dev/null | grep '(NEEDED)' > %s" \
% (sysconfig.get_config_var('READELF'),
do_readline, tmpfile))
elif find_executable('ldd'):
@@ -681,7 +762,9 @@
os.unlink(tmpfile)
# Issue 7384: If readline is already linked against curses,
# use the same library for the readline and curses modules.
- if 'curses' in readline_termcap_library:
+ if 'curses' in readline_conf_termcap:
+ curses_library = readline_conf_termcap
+ elif 'curses' in readline_termcap_library:
curses_library = readline_termcap_library
elif self.compiler.find_library_file(lib_dirs, 'ncursesw'):
curses_library = 'ncursesw'
@@ -730,20 +813,31 @@
# crypt module.
- if self.compiler.find_library_file(lib_dirs, 'crypt'):
- libs = ['crypt']
+ if host_platform not in ['mingw', 'win32']:
+ if self.compiler.find_library_file(lib_dirs, 'crypt'):
+ libs = ['crypt']
+ else:
+ libs = []
+ exts.append( Extension('_crypt', ['_cryptmodule.c'], libraries=libs) )
else:
- libs = []
- exts.append( Extension('_crypt', ['_cryptmodule.c'], libraries=libs) )
+ missing.append('_crypt')
# CSV files
exts.append( Extension('_csv', ['_csv.c']) )
# POSIX subprocess module helper.
- exts.append( Extension('_posixsubprocess', ['_posixsubprocess.c']) )
+ if host_platform not in ['mingw', 'win32']:
+ exts.append( Extension('_posixsubprocess', ['_posixsubprocess.c']) )
+ else:
+ missing.append('_posixsubprocess')
# socket(2)
+ if host_platform in ['mingw', 'win32']:
+ socket_libs = ['ws2_32']
+ else:
+ socket_libs = []
exts.append( Extension('_socket', ['socketmodule.c'],
+ libraries=socket_libs,
depends = ['socketmodule.h']) )
# Detect SSL support for the socket module (via _ssl)
search_for_ssl_incs_in = [
@@ -765,10 +859,13 @@
if (ssl_incs is not None and
ssl_libs is not None):
+ _ssl_libs = ['ssl', 'crypto']
+ if host_platform in ['mingw', 'win32']:
+ _ssl_libs.append('ws2_32')
exts.append( Extension('_ssl', ['_ssl.c'],
include_dirs = ssl_incs,
library_dirs = ssl_libs,
- libraries = ['ssl', 'crypto'],
+ libraries = _ssl_libs,
depends = ['socketmodule.h']), )
else:
missing.append('_ssl')
@@ -805,15 +902,18 @@
if have_usable_openssl:
# The _hashlib module wraps optimized implementations
# of hash functions from the OpenSSL library.
+ # NOTE: _hashlib require only OpenSSL crypto library !
exts.append( Extension('_hashlib', ['_hashopenssl.c'],
depends = ['hashlib.h'],
include_dirs = ssl_incs,
library_dirs = ssl_libs,
- libraries = ['ssl', 'crypto']) )
+ libraries = ['crypto']) )
else:
print("warning: openssl 0x%08x is too old for _hashlib" %
openssl_ver)
missing.append('_hashlib')
+ # NOTE: MSVC build alwais include _md5 and _sha modules
+ # as build-in modules
# We always compile these even when OpenSSL is available (issue #14693).
# It's harmless and the object code is tiny (40-50 KB per module,
@@ -846,6 +946,30 @@
min_db_ver = (3, 3)
db_setup_debug = False # verbose debug prints from this script?
+ # Modules with some Windows dependencies:
+ if host_platform in ['mingw', 'win32']:
+ srcdir = sysconfig.get_config_var('srcdir')
+ pc_srcdir = os.path.abspath(os.path.join(srcdir, 'PC'))
+
+ exts.append( Extension('msvcrt', [os.path.join(pc_srcdir, p)
+ for p in ['msvcrtmodule.c']]) )
+
+ #Note that PCbuild use fci but MSDN document as cabinet
+ exts.append( Extension('_msi', [os.path.join(pc_srcdir, p)
+ for p in ['_msi.c']],
+ libraries=['msi','cabinet','rpcrt4']) )
+
+ exts.append( Extension('_winapi', ['_winapi.c']) )
+
+ # On win32 host(mingw build in MSYS environment) show that site.py
+ # fail to load if some modules are not build-in:
+ #exts.append( Extension('winreg', [os.path.join(pc_srcdir, p)
+ # for p in ['winreg.c']]) )
+
+ exts.append( Extension('winsound', [os.path.join(pc_srcdir, p)
+ for p in ['winsound.c']],
+ libraries=['winmm']) )
+
def allow_db_ver(db_ver):
"""Returns a boolean if the given BerkeleyDB version is acceptable.
@@ -1104,6 +1228,7 @@
'_sqlite/util.c', ]
sqlite_defines = []
+ #NOTE: don't add mingw here
if host_platform != "win32":
sqlite_defines.append(('MODULE_NAME', '"sqlite3"'))
else:
@@ -1217,7 +1342,8 @@
missing.append('_dbm')
# Anthony Baxter's gdbm module. GNU dbm(3) will require -lgdbm:
- if ('gdbm' in dbm_order and
+ if (host_platform not in ['mingw', 'win32'] and
+ 'gdbm' in dbm_order and
self.compiler.find_library_file(lib_dirs, 'gdbm')):
exts.append( Extension('_gdbm', ['_gdbmmodule.c'],
libraries = ['gdbm'] ) )
@@ -1225,7 +1351,7 @@
missing.append('_gdbm')
# Unix-only modules
- if host_platform != 'win32':
+ if host_platform not in ['mingw', 'win32']:
# Steen Lumholt's termios module
exts.append( Extension('termios', ['termios.c']) )
# Jeremy Hylton's rlimit interface
@@ -1439,7 +1565,7 @@
self.detect_ctypes(inc_dirs, lib_dirs)
# Richard Oudkerk's multiprocessing module
- if host_platform == 'win32': # Windows
+ if host_platform in ['mingw', 'win32']:
macros = dict()
libraries = ['ws2_32']
@@ -1467,9 +1593,11 @@
else: # Linux and other unices
macros = dict()
- libraries = ['rt']
+ # NOTE: line below is never used before to add MINGW platform
+ #libraries = ['rt']
+ libraries = []
- if host_platform == 'win32':
+ if host_platform in ['mingw', 'win32']:
multiprocessing_srcs = [ '_multiprocessing/multiprocessing.c',
'_multiprocessing/semaphore.c',
]
@@ -1482,7 +1610,9 @@
multiprocessing_srcs.append('_multiprocessing/semaphore.c')
if sysconfig.get_config_var('WITH_THREAD'):
+ #FIXME: why above set libraries aren't used ?
exts.append ( Extension('_multiprocessing', multiprocessing_srcs,
+ libraries=libraries,
define_macros=list(macros.items()),
include_dirs=["Modules/_multiprocessing"]))
else:
@@ -1665,6 +1795,9 @@
if host_platform == 'sunos5':
include_dirs.append('/usr/openwin/include')
added_lib_dirs.append('/usr/openwin/lib')
+ elif host_platform in ['mingw', 'win32']:
+ # mingw&win32 don't use X11 headers and libraries
+ pass
elif os.path.exists('/usr/X11R6/include'):
include_dirs.append('/usr/X11R6/include')
added_lib_dirs.append('/usr/X11R6/lib64')
@@ -1679,6 +1812,7 @@
# If Cygwin, then verify that X is installed before proceeding
if host_platform == 'cygwin':
+ include_dirs.append('/usr/include')
x11_inc = find_file('X11/Xlib.h', [], include_dirs)
if x11_inc is None:
return
@@ -1700,8 +1834,8 @@
if host_platform in ['aix3', 'aix4']:
libs.append('ld')
- # Finally, link with the X11 libraries (not appropriate on cygwin)
- if host_platform != "cygwin":
+ # Finally, link with the X11 libraries (not appropriate on cygwin, mingw)
+ if not host_platform in ['cygwin', 'mingw', 'win32']:
libs.append('X11')
ext = Extension('_tkinter', ['_tkinter.c', 'tkappinit.c'],
@@ -1756,6 +1890,38 @@
return True
def configure_ctypes(self, ext):
+ if host_platform in ['mingw', 'win32']:
+ # win32 platform use own sources and includes
+ # from Modules/_ctypes/libffi_msvc/
+ srcdir = sysconfig.get_config_var('srcdir')
+
+ ffi_srcdir = os.path.abspath(os.path.join(srcdir, 'Modules',
+ '_ctypes'))
+ sources = [os.path.join(ffi_srcdir, p)
+ for p in ['malloc_closure.c',
+ ]]
+ ext.sources.extend(sources)
+
+ ffi_srcdir = os.path.abspath(os.path.join(srcdir, 'Modules',
+ '_ctypes', 'libffi_msvc'))
+ #FIXME: _ctypes/libffi_msvc/win64.asm ?
+ sources = [os.path.join(ffi_srcdir, p)
+ for p in ['ffi.c',
+ 'prep_cif.c',
+ 'win32.S',
+ ]]
+ # NOTE: issue2942 don't resolve problem with assembler code.
+ # It seems to me that python refuse to build an extension
+ # if exist a source with unknown suffix.
+ self.compiler.src_extensions.append('.s')
+ self.compiler.src_extensions.append('.S')
+ ext.include_dirs.append(ffi_srcdir)
+ ext.sources.extend(sources)
+ ext.libraries.extend(['ole32', 'oleaut32', 'uuid'])
+ #AdditionalOptions="/EXPORT:DllGetClassObject,PRIVATE /EXPORT:DllCanUnloadNow,PRIVATE"
+ ext.export_symbols.extend(['DllGetClassObject PRIVATE',
+ 'DllCanUnloadNow PRIVATE'])
+ return True
if not self.use_system_libffi:
if host_platform == 'darwin':
return self.configure_ctypes_darwin(ext)
@@ -1806,6 +1972,11 @@
fficonfig['ffi_sources'])
ext.include_dirs.extend(include_dirs)
ext.extra_compile_args.extend(extra_compile_args)
+ if host_platform in ['mingw', 'win32']:
+ ext.libraries.extend(['ole32', 'oleaut32', 'uuid'])
+ #AdditionalOptions="/EXPORT:DllGetClassObject,PRIVATE /EXPORT:DllCanUnloadNow,PRIVATE"
+ ext.export_symbols.extend(['DllGetClassObject PRIVATE',
+ 'DllCanUnloadNow PRIVATE'])
return True
def detect_ctypes(self, inc_dirs, lib_dirs):
@@ -1849,7 +2020,12 @@
libraries=[],
sources=sources,
depends=depends)
+ if host_platform in ['mingw', 'win32']:
+ ctypes_test_libs = ['oleaut32']
+ else:
+ ctypes_test_libs = []
ext_test = Extension('_ctypes_test',
+ libraries=ctypes_test_libs,
sources=['_ctypes/_ctypes_test.c'])
self.extensions.extend([ext, ext_test])
@@ -2063,8 +2239,9 @@
class PyBuildScripts(build_scripts):
def copy_scripts(self):
outfiles, updated_files = build_scripts.copy_scripts(self)
- fullversion = '-{0[0]}.{0[1]}'.format(sys.version_info)
- minoronly = '.{0[1]}'.format(sys.version_info)
+ print('sys.version_info=%s' % str(sys.version_info))
+ fullversion = '-{0[0]}{0[1]}'.format(sys.version_info)
+ minoronly = '{0[1]}'.format(sys.version_info)
newoutfiles = []
newupdated_files = []
for filename in outfiles:
@@ -2073,6 +2250,8 @@
else:
newfilename = filename + minoronly
log.info('renaming {} to {}'.format(filename, newfilename))
+ if os.path.isfile(newfilename):
+ os.remove(newfilename)
os.rename(filename, newfilename)
newoutfiles.append(newfilename)
if filename in updated_files:
« no previous file with comments | « setup_info.in ('k') | no next file » | no next file with comments »

RSS Feeds Recent Issues | This issue
This is Rietveld 894c83f36cb7+