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

Delta Between Two Patch Sets: Lib/distutils/command/build_ext.py

Issue 3871: cross and native build of python for mingw32 with distutils
Left Patch Set: Created 9 years, 5 months ago
Right Patch Set: Created 7 years, 2 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « Lib/distutils/ccompiler.py ('k') | Lib/distutils/command/install.py » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 """distutils.command.build_ext 1 """distutils.command.build_ext
2 2
3 Implements the Distutils 'build_ext' command, for building extension 3 Implements the Distutils 'build_ext' command, for building extension
4 modules (currently limited to C extensions, should accommodate C++ 4 modules (currently limited to C extensions, should accommodate C++
5 extensions ASAP).""" 5 extensions ASAP)."""
6
7 __revision__ = "$Id$"
8 6
9 import sys, os, re 7 import sys, os, re
10 from distutils.core import Command 8 from distutils.core import Command
11 from distutils.errors import * 9 from distutils.errors import *
12 from distutils.sysconfig import customize_compiler, get_python_version 10 from distutils.sysconfig import customize_compiler, get_python_version
11 from distutils.sysconfig import get_config_h_filename
13 from distutils.dep_util import newer_group 12 from distutils.dep_util import newer_group
14 from distutils.extension import Extension 13 from distutils.extension import Extension
15 from distutils.util import get_platform, msysize 14 from distutils.util import get_platform
16 from distutils import log 15 from distutils import log
17 16
18 # this keeps compatibility from 2.3 to 2.5 17 # this keeps compatibility from 2.3 to 2.5
19 if sys.version < "2.6": 18 if sys.version < "2.6":
20 USER_BASE = None 19 USER_BASE = None
21 HAS_USER_SITE = False 20 HAS_USER_SITE = False
22 else: 21 else:
23 from site import USER_BASE 22 from site import USER_BASE
24 HAS_USER_SITE = True 23 HAS_USER_SITE = True
25 24
26 if os.name == 'nt': 25 # GCC(mingw): os.name is "nt" but build system is posix
26 if os.name == 'nt' and sys.version.find('GCC') < 0:
27 from distutils.msvccompiler import get_build_version 27 from distutils.msvccompiler import get_build_version
28 MSVC_VERSION = int(get_build_version()) 28 MSVC_VERSION = int(get_build_version())
29 29
30 # An extension name is just a dot-separated list of Python NAMEs (ie. 30 # An extension name is just a dot-separated list of Python NAMEs (ie.
31 # the same as a fully-qualified module name). 31 # the same as a fully-qualified module name).
32 extension_name_re = re.compile \ 32 extension_name_re = re.compile \
33 (r'^[a-zA-Z_][a-zA-Z_0-9]*(\.[a-zA-Z_][a-zA-Z_0-9]*)*$') 33 (r'^[a-zA-Z_][a-zA-Z_0-9]*(\.[a-zA-Z_][a-zA-Z_0-9]*)*$')
34 34
35 35
36 def show_compilers (): 36 def show_compilers ():
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
154 154
155 # Make sure Python's include directories (for Python.h, pyconfig.h, 155 # Make sure Python's include directories (for Python.h, pyconfig.h,
156 # etc.) are in the include search path. 156 # etc.) are in the include search path.
157 py_include = sysconfig.get_python_inc() 157 py_include = sysconfig.get_python_inc()
158 plat_py_include = sysconfig.get_python_inc(plat_specific=1) 158 plat_py_include = sysconfig.get_python_inc(plat_specific=1)
159 if self.include_dirs is None: 159 if self.include_dirs is None:
160 self.include_dirs = self.distribution.include_dirs or [] 160 self.include_dirs = self.distribution.include_dirs or []
161 if isinstance(self.include_dirs, str): 161 if isinstance(self.include_dirs, str):
162 self.include_dirs = self.include_dirs.split(os.pathsep) 162 self.include_dirs = self.include_dirs.split(os.pathsep)
163 163
164 # If in a virtualenv, add its include directory
165 # Issue 16116
166 if sys.exec_prefix != sys.base_exec_prefix:
167 self.include_dirs.append(os.path.join(sys.exec_prefix, 'include'))
168
164 # Put the Python "system" include dir at the end, so that 169 # Put the Python "system" include dir at the end, so that
165 # any local include dirs take precedence. 170 # any local include dirs take precedence.
166 self.include_dirs.append(py_include) 171 self.include_dirs.append(py_include)
167 if plat_py_include != py_include: 172 if plat_py_include != py_include:
168 self.include_dirs.append(plat_py_include) 173 self.include_dirs.append(plat_py_include)
169 174
170 if isinstance(self.libraries, str): 175 self.ensure_string_list('libraries')
171 self.libraries = [self.libraries]
172 176
173 # Life is easier if we're not forever checking for None, so 177 # Life is easier if we're not forever checking for None, so
174 # simplify these options to empty lists if unset 178 # simplify these options to empty lists if unset
175 if self.libraries is None: 179 if self.libraries is None:
176 self.libraries = [] 180 self.libraries = []
177 if self.library_dirs is None: 181 if self.library_dirs is None:
178 self.library_dirs = [] 182 self.library_dirs = []
179 elif isinstance(self.library_dirs, str): 183 elif isinstance(self.library_dirs, str):
180 self.library_dirs = self.library_dirs.split(os.pathsep) 184 self.library_dirs = self.library_dirs.split(os.pathsep)
181 185
182 if self.rpath is None: 186 if self.rpath is None:
183 self.rpath = [] 187 self.rpath = []
184 elif isinstance(self.rpath, str): 188 elif isinstance(self.rpath, str):
185 self.rpath = self.rpath.split(os.pathsep) 189 self.rpath = self.rpath.split(os.pathsep)
186 190
187 # for extensions under windows use different directories 191 # for extensions under windows use different directories
188 # for Release and Debug builds. 192 # for Release and Debug builds.
189 # also Python's library directory must be appended to library_dirs 193 # also Python's library directory must be appended to library_dirs
190 if os.name == 'nt' and 'msys' not in sys.builtin_module_names: 194 # GCC(mingw): os.name is "nt" but build system is posix
195 if os.name == 'nt' and sys.version.find('GCC') < 0:
191 # the 'libs' directory is for binary installs - we assume that 196 # the 'libs' directory is for binary installs - we assume that
192 # must be the *native* platform. But we don't really support 197 # must be the *native* platform. But we don't really support
193 # cross-compiling via a binary install anyway, so we let it go. 198 # cross-compiling via a binary install anyway, so we let it go.
194 self.library_dirs.append(os.path.join(sys.exec_prefix, 'libs')) 199 self.library_dirs.append(os.path.join(sys.exec_prefix, 'libs'))
200 if sys.base_exec_prefix != sys.prefix: # Issue 16116
201 self.library_dirs.append(os.path.join(sys.base_exec_prefix, 'lib s'))
195 if self.debug: 202 if self.debug:
196 self.build_temp = os.path.join(self.build_temp, "Debug") 203 self.build_temp = os.path.join(self.build_temp, "Debug")
197 else: 204 else:
198 self.build_temp = os.path.join(self.build_temp, "Release") 205 self.build_temp = os.path.join(self.build_temp, "Release")
199 206
200 # Append the source distribution include and library directories, 207 # Append the source distribution include and library directories,
201 # this allows distutils on windows to work in the source tree 208 # this allows distutils on windows to work in the source tree
202 self.include_dirs.append(os.path.join(sys.exec_prefix, 'PC')) 209 self.include_dirs.append(os.path.dirname(get_config_h_filename()))
203 if MSVC_VERSION == 9: 210 _sys_home = getattr(sys, '_home', None)
211 if _sys_home:
212 self.library_dirs.append(_sys_home)
213 if MSVC_VERSION >= 9:
204 # Use the .lib files for the correct architecture 214 # Use the .lib files for the correct architecture
205 if self.plat_name == 'win32': 215 if self.plat_name == 'win32':
206 suffix = '' 216 suffix = ''
207 else: 217 else:
208 # win-amd64 or win-ia64 218 # win-amd64 or win-ia64
209 suffix = self.plat_name[4:] 219 suffix = self.plat_name[4:]
210 new_lib = os.path.join(sys.exec_prefix, 'PCbuild') 220 new_lib = os.path.join(sys.exec_prefix, 'PCbuild')
211 if suffix: 221 if suffix:
212 new_lib = os.path.join(new_lib, suffix) 222 new_lib = os.path.join(new_lib, suffix)
213 self.library_dirs.append(new_lib) 223 self.library_dirs.append(new_lib)
214 224
215 elif MSVC_VERSION == 8: 225 elif MSVC_VERSION == 8:
216 self.library_dirs.append(os.path.join(sys.exec_prefix, 226 self.library_dirs.append(os.path.join(sys.exec_prefix,
217 'PC', 'VS8.0', 'win32release')) 227 'PC', 'VS8.0'))
218 elif MSVC_VERSION == 7: 228 elif MSVC_VERSION == 7:
219 self.library_dirs.append(os.path.join(sys.exec_prefix, 229 self.library_dirs.append(os.path.join(sys.exec_prefix,
220 'PC', 'VS7.1')) 230 'PC', 'VS7.1'))
221 else: 231 else:
222 self.library_dirs.append(os.path.join(sys.exec_prefix, 232 self.library_dirs.append(os.path.join(sys.exec_prefix,
223 'PC', 'VC6')) 233 'PC', 'VC6'))
224 elif os.name == 'nt' and 'msys' in sys.builtin_module_names:
225 self.library_dirs.append(os.path.join(sys.exec_prefix, 'libs'))
226 # This is hacky, but there is no other way to find real path to
227 # mingw directory
228 os.system ('env gcc -print-search-dirs >buildextgcccallstdout')
229 gcclibpaths = []
230 with open ('buildextgcccallstdout') as stdo:
231 for line in stdo:
232 line = line.rstrip ('\r').rstrip ('\n')
233 if line.startswith ('libraries: ='):
234 gcclibpaths = line.replace ('libraries: =', '').split (';')
235 os.system ('env rm -f buildextgcccallstdout')
236 self.library_dirs.extend (gcclibpaths)
237
238 os.system ('env sh -c echo "int main(){return 0;}" | gcc -v -x c - 2 >buildextgcccallstdout')
239 gccincpaths = []
240 with open ('buildextgcccallstdout') as stdo:
241 includequotes = False
242 includeangles = False
243 for line in stdo:
244 line = line.rstrip ('\r').rstrip ('\n')
245 if line.startswith ('#include "..." search starts here:'):
246 includequotes = True
247 includeangles = False
248 elif line.startswith ('#include <...> search starts here:'):
249 includeangles = True
250 includequotes = False
251 elif line.startswith ('End of search list.'):
252 break
253 elif includeangles or includequotes:
254 gcclibpaths.append (line.lstrip(' '))
255 os.system ('env rm -f buildextgcccallstdout')
256 self.include_dirs.extend (gcclibpaths)
257
258 # This is also a hack. There must be another place to do this.
259 # Add python.exe's directory into library path - it contains
260 # libpythonx.x.a
261 self.library_dirs.append (os.path.dirname (os.path.abspath (sys.exec utable)))
262
263 # Append the source distribution include and library directories,
264 # this allows distutils on windows to work in the source tree
265 #self.include_dirs.append(os.path.join(sys.exec_prefix, 'PC'))
266 234
267 # OS/2 (EMX) doesn't support Debug vs Release builds, but has the 235 # OS/2 (EMX) doesn't support Debug vs Release builds, but has the
268 # import libraries in its "Config" subdirectory 236 # import libraries in its "Config" subdirectory
269 if os.name == 'os2': 237 if os.name == 'os2':
270 self.library_dirs.append(os.path.join(sys.exec_prefix, 'Config')) 238 self.library_dirs.append(os.path.join(sys.exec_prefix, 'Config'))
271 239
272 # for extensions under Cygwin and AtheOS Python's library directory must be 240 # for extensions under Cygwin and AtheOS Python's library directory must be
273 # appended to library_dirs 241 # appended to library_dirs
274 if sys.platform[:6] == 'cygwin' or sys.platform[:6] == 'atheos': 242 if (sys.platform[:6] == 'cygwin' or sys.platform[:6] == 'atheos'
243 or (sys.platform == 'win32' and sys.version.find('GCC') >= 0)):
275 if sys.executable.startswith(os.path.join(sys.exec_prefix, "bin")): 244 if sys.executable.startswith(os.path.join(sys.exec_prefix, "bin")):
276 # building third party extensions 245 # building third party extensions
277 self.library_dirs.append(os.path.join(sys.prefix, "lib", 246 self.library_dirs.append(os.path.join(sys.prefix, "lib",
278 "python" + get_python_vers ion(), 247 "python" + get_python_vers ion(),
279 "config")) 248 "config"))
280 else: 249 else:
281 # building python standard extensions 250 # building python standard extensions
282 self.library_dirs.append('.') 251 self.library_dirs.append('.')
283 252
284 # for extensions under Linux or Solaris with a shared Python library, 253 # for extensions under Linux or Solaris with a shared Python library,
285 # Python's library directory must be appended to library_dirs 254 # Python's library directory must be appended to library_dirs
286 sysconfig.get_config_var('Py_ENABLE_SHARED') 255 sysconfig.get_config_var('Py_ENABLE_SHARED')
287 if ((sys.platform.startswith('linux') or sys.platform.startswith('gnu') 256 if (sys.platform.startswith(('linux', 'gnu', 'sunos'))
288 or sys.platform.startswith('sunos'))
289 and sysconfig.get_config_var('Py_ENABLE_SHARED')): 257 and sysconfig.get_config_var('Py_ENABLE_SHARED')):
290 if sys.executable.startswith(os.path.join(sys.exec_prefix, "bin")): 258 if sys.executable.startswith(os.path.join(sys.exec_prefix, "bin")):
291 # building third party extensions 259 # building third party extensions
292 self.library_dirs.append(sysconfig.get_config_var('LIBDIR')) 260 self.library_dirs.append(sysconfig.get_config_var('LIBDIR'))
293 else: 261 else:
294 # building python standard extensions 262 # building python standard extensions
295 self.library_dirs.append('.') 263 self.library_dirs.append('.')
296 264
297 # The argument parsing will result in self.define being a string, but 265 # The argument parsing will result in self.define being a string, but
298 # it has to be a list of 2-tuples. All the preprocessor symbols 266 # it has to be a list of 2-tuples. All the preprocessor symbols
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after
537 # guess it's useful) 505 # guess it's useful)
538 # The environment variable should take precedence, and 506 # The environment variable should take precedence, and
539 # any sensible compiler will give precedence to later 507 # any sensible compiler will give precedence to later
540 # command line args. Hence we combine them in order: 508 # command line args. Hence we combine them in order:
541 extra_args = ext.extra_compile_args or [] 509 extra_args = ext.extra_compile_args or []
542 510
543 macros = ext.define_macros[:] 511 macros = ext.define_macros[:]
544 for undef in ext.undef_macros: 512 for undef in ext.undef_macros:
545 macros.append((undef,)) 513 macros.append((undef,))
546 514
547 output_dir = self.build_temp
548 include_dirs = ext.include_dirs
549
550 objects = self.compiler.compile(sources, 515 objects = self.compiler.compile(sources,
551 output_dir=output_dir, 516 output_dir=self.build_temp,
552 macros=macros, 517 macros=macros,
553 include_dirs=include_dirs, 518 include_dirs=ext.include_dirs,
554 debug=self.debug, 519 debug=self.debug,
555 extra_postargs=extra_args, 520 extra_postargs=extra_args,
556 depends=ext.depends) 521 depends=ext.depends)
557 522
558 # XXX -- this is a Vile HACK! 523 # XXX -- this is a Vile HACK!
559 # 524 #
560 # The setup.py script for Python on Unix needs to be able to 525 # The setup.py script for Python on Unix needs to be able to
561 # get this list so it can perform all the clean up needed to 526 # get this list so it can perform all the clean up needed to
562 # avoid keeping object files around when cleaning out a failed 527 # avoid keeping object files around when cleaning out a failed
563 # build of an extension module. Since Distutils does not 528 # build of an extension module. Since Distutils does not
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
734 def get_libraries(self, ext): 699 def get_libraries(self, ext):
735 """Return the list of libraries to link against when building a 700 """Return the list of libraries to link against when building a
736 shared extension. On most platforms, this is just 'ext.libraries'; 701 shared extension. On most platforms, this is just 'ext.libraries';
737 on Windows and OS/2, we add the Python library (eg. python20.dll). 702 on Windows and OS/2, we add the Python library (eg. python20.dll).
738 """ 703 """
739 # The python library is always needed on Windows. For MSVC, this 704 # The python library is always needed on Windows. For MSVC, this
740 # is redundant, since the library is mentioned in a pragma in 705 # is redundant, since the library is mentioned in a pragma in
741 # pyconfig.h that MSVC groks. The other Windows compilers all seem 706 # pyconfig.h that MSVC groks. The other Windows compilers all seem
742 # to need it mentioned explicitly, though, so that's what we do. 707 # to need it mentioned explicitly, though, so that's what we do.
743 # Append '_d' to the python import library on debug builds. 708 # Append '_d' to the python import library on debug builds.
744 if sys.platform == "win32" and 'msys' in sys.builtin_module_names: 709
745 template = "python%d.%d" 710 # FIXME: What is purpose of code below ?
746 pythonlib = (template % 711 # The posix build system khow requred libraries to build a module.
747 (sys.hexversion >> 24, (sys.hexversion >> 16) & 0xff)) 712 # The libraries are stored in config(Makefile) variables BLDLIBRARY,
748 # don't extend ext.libraries, it may be shared with other 713 # MODLIBS and SHLIBS. Note that some variables may contain linker
749 # extensions, it is a reference to the original list 714 # flags.
750 return ext.libraries + [pythonlib] 715 # NOTE: For now we will check only GCC(mingw) compiler as is clear
751 elif sys.platform == "win32": 716 # that we build for windows platfrom.
717 # The code for GCC(mingw) is not correct but this is distutils
718 # limitation - we has to pass variables to the linker as is
719 # instead only library names.
720 if self.compiler.compiler_type == 'mingw32':
721 from distutils import sysconfig
722
723 template = "python%s"
724 if self.debug:
725 template = template + '_d'
726 extra = [(template % (sysconfig.get_config_var('VERSION')))]
727 for lib in sysconfig.get_config_var('BLDLIBRARY').split():
728 if lib.startswith('-l'):
729 extra.append(lib[2:])
730 for lib in sysconfig.get_config_var('MODLIBS').split():
731 if lib.startswith('-l'):
732 extra.append(lib[2:])
733 for lib in sysconfig.get_config_var('SHLIBS').split():
734 if lib.startswith('-l'):
735 extra.append(lib[2:])
736 return ext.libraries + extra
737
738 if sys.platform == "win32":
752 from distutils.msvccompiler import MSVCCompiler 739 from distutils.msvccompiler import MSVCCompiler
753 if not isinstance(self.compiler, MSVCCompiler): 740 if not isinstance(self.compiler, MSVCCompiler):
754 template = "python%d%d" 741 template = "python%d%d"
755 if self.debug: 742 if self.debug:
756 template = template + '_d' 743 template = template + '_d'
757 pythonlib = (template % 744 pythonlib = (template %
758 (sys.hexversion >> 24, (sys.hexversion >> 16) & 0xff)) 745 (sys.hexversion >> 24, (sys.hexversion >> 16) & 0xff))
759 # don't extend ext.libraries, it may be shared with other 746 # don't extend ext.libraries, it may be shared with other
760 # extensions, it is a reference to the original list 747 # extensions, it is a reference to the original list
761 return ext.libraries + [pythonlib] 748 return ext.libraries + [pythonlib]
762 else: 749 else:
763 return ext.libraries 750 return ext.libraries
764 elif sys.platform == "os2emx": 751 elif sys.platform == "os2emx":
765 # EMX/GCC requires the python library explicitly, and I 752 # EMX/GCC requires the python library explicitly, and I
766 # believe VACPP does as well (though not confirmed) - AIM Apr01 753 # believe VACPP does as well (though not confirmed) - AIM Apr01
767 template = "python%d%d" 754 template = "python%d%d"
768 # debug versions of the main DLL aren't supported, at least 755 # debug versions of the main DLL aren't supported, at least
769 # not at this time - AIM Apr01 756 # not at this time - AIM Apr01
770 #if self.debug: 757 #if self.debug:
771 # template = template + '_d' 758 # template = template + '_d'
772 pythonlib = (template % 759 pythonlib = (template %
773 (sys.hexversion >> 24, (sys.hexversion >> 16) & 0xff)) 760 (sys.hexversion >> 24, (sys.hexversion >> 16) & 0xff))
774 # don't extend ext.libraries, it may be shared with other 761 # don't extend ext.libraries, it may be shared with other
775 # extensions, it is a reference to the original list 762 # extensions, it is a reference to the original list
776 return ext.libraries + [pythonlib] 763 return ext.libraries + [pythonlib]
777 elif sys.platform[:6] == "cygwin": 764 # NOTE : cygwin use posix build rules ;)
765 elif sys.platform[:6] == "cygwin" and False:
778 template = "python%d.%d" 766 template = "python%d.%d"
779 pythonlib = (template % 767 pythonlib = (template %
780 (sys.hexversion >> 24, (sys.hexversion >> 16) & 0xff)) 768 (sys.hexversion >> 24, (sys.hexversion >> 16) & 0xff))
781 # don't extend ext.libraries, it may be shared with other 769 # don't extend ext.libraries, it may be shared with other
782 # extensions, it is a reference to the original list 770 # extensions, it is a reference to the original list
783 return ext.libraries + [pythonlib] 771 return ext.libraries + [pythonlib]
784 elif sys.platform[:6] == "atheos": 772 elif sys.platform[:6] == "atheos":
785 from distutils import sysconfig 773 from distutils import sysconfig
786 774
787 template = "python%d.%d" 775 template = "python%d.%d"
788 pythonlib = (template % 776 pythonlib = (template %
789 (sys.hexversion >> 24, (sys.hexversion >> 16) & 0xff)) 777 (sys.hexversion >> 24, (sys.hexversion >> 16) & 0xff))
790 # Get SHLIBS from Makefile 778 # Get SHLIBS from Makefile
791 extra = [] 779 extra = []
792 for lib in sysconfig.get_config_var('SHLIBS').split(): 780 for lib in sysconfig.get_config_var('SHLIBS').split():
793 if lib.startswith('-l'): 781 if lib.startswith('-l'):
794 extra.append(lib[2:]) 782 extra.append(lib[2:])
795 else: 783 else:
796 extra.append(lib) 784 extra.append(lib)
797 # don't extend ext.libraries, it may be shared with other 785 # don't extend ext.libraries, it may be shared with other
798 # extensions, it is a reference to the original list 786 # extensions, it is a reference to the original list
799 return ext.libraries + [pythonlib, "m"] + extra 787 return ext.libraries + [pythonlib, "m"] + extra
800 elif sys.platform == 'darwin': 788 elif sys.platform == 'darwin':
801 # Don't use the default code below 789 # Don't use the default code below
802 return ext.libraries 790 return ext.libraries
791 elif sys.platform[:3] == 'aix':
792 # Don't use the default code below
793 return ext.libraries
803 else: 794 else:
804 from distutils import sysconfig 795 from distutils import sysconfig
805 if sysconfig.get_config_var('Py_ENABLE_SHARED'): 796 if sysconfig.get_config_var('Py_ENABLE_SHARED'):
806 template = "python%d.%d" 797 pythonlib = 'python{}.{}{}'.format(
807 pythonlib = (template % 798 sys.hexversion >> 24, (sys.hexversion >> 16) & 0xff,
808 (sys.hexversion >> 24, (sys.hexversion >> 16) & 0xf f)) 799 sys.abiflags)
809 return ext.libraries + [pythonlib] 800 return ext.libraries + [pythonlib]
810 else: 801 else:
811 return ext.libraries 802 return ext.libraries
LEFTRIGHT

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