10a8c90248264a8b26970b4473770bcc3df8515fJosh Gao"""distutils.cygwinccompiler
20a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
30a8c90248264a8b26970b4473770bcc3df8515fJosh GaoProvides the CygwinCCompiler class, a subclass of UnixCCompiler that
40a8c90248264a8b26970b4473770bcc3df8515fJosh Gaohandles the Cygwin port of the GNU C compiler to Windows.  It also contains
50a8c90248264a8b26970b4473770bcc3df8515fJosh Gaothe Mingw32CCompiler class which handles the mingw32 port of GCC (same as
60a8c90248264a8b26970b4473770bcc3df8515fJosh Gaocygwin in no-cygwin mode).
70a8c90248264a8b26970b4473770bcc3df8515fJosh Gao"""
80a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
90a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# problems:
100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#
110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# * if you use a msvc compiled python version (1.5.2)
120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#   1. you have to insert a __GNUC__ section in its config.h
130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#   2. you have to generate a import library for its dll
140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#      - create a def-file for python??.dll
150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#      - create a import library using
160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#             dlltool --dllname python15.dll --def python15.def \
170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#                       --output-lib libpython15.a
180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#
190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#   see also http://starship.python.net/crew/kernr/mingw32/Notes.html
200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#
210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# * We put export_symbols in a def-file, and don't use
220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#   --export-all-symbols because it doesn't worked reliable in some
230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#   tested configurations. And because other windows compilers also
240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#   need their symbols specified this no serious problem.
250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#
260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# tested configurations:
270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#
280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# * cygwin gcc 2.91.57/ld 2.9.4/dllwrap 0.2.4 works
290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#   (after patching python's config.h and for C++ some other include files)
300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#   see also http://starship.python.net/crew/kernr/mingw32/Notes.html
310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# * mingw32 gcc 2.95.2/ld 2.9.4/dllwrap 0.2.4 works
320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#   (ld doesn't support -shared, so we use dllwrap)
330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# * cygwin gcc 2.95.2/ld 2.10.90/dllwrap 2.10.90 works now
340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#   - its dllwrap doesn't work, there is a bug in binutils 2.10.90
350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#     see also http://sources.redhat.com/ml/cygwin/2000-06/msg01274.html
360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#   - using gcc -mdll instead dllwrap doesn't work without -static because
370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#     it tries to link against dlls instead their import libraries. (If
380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#     it finds the dll first.)
390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#     By specifying -static we force ld to link against the import libraries,
400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#     this is windows standard and there are normally not the necessary symbols
410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#     in the dlls.
420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#   *** only the version of June 2000 shows these problems
430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# * cygwin gcc 3.2/ld 2.13.90 works
440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#   (ld supports -shared)
450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# * mingw gcc 3.2/ld 2.13 works
460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#   (ld supports -shared)
470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# This module should be kept compatible with Python 2.1.
490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao__revision__ = "$Id$"
510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
520a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport os,sys,copy
530a8c90248264a8b26970b4473770bcc3df8515fJosh Gaofrom distutils.ccompiler import gen_preprocess_options, gen_lib_options
540a8c90248264a8b26970b4473770bcc3df8515fJosh Gaofrom distutils.unixccompiler import UnixCCompiler
550a8c90248264a8b26970b4473770bcc3df8515fJosh Gaofrom distutils.file_util import write_file
560a8c90248264a8b26970b4473770bcc3df8515fJosh Gaofrom distutils.errors import DistutilsExecError, CompileError, UnknownFileError
570a8c90248264a8b26970b4473770bcc3df8515fJosh Gaofrom distutils import log
580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
590a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef get_msvcr():
600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """Include the appropriate MSVC runtime library if Python was built
610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    with MSVC 7.0 or later.
620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """
630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # FIXME: next code is from issue870382
640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # MS C-runtime libraries never support backward compatibility.
650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # Linking to a different library without to specify correct runtime
660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # version for the headers will link renamed functions to msvcrt.
670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # See issue3308: this piece of code is python problem even
680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # with correct w32api headers.
690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # Issue: for MSVC compiler we can get the version and from version
700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # to determine mcvcrt as code below. But what about if python is
710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # build with GCC compiler?
720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # Output of sys.version is information for python build on first
730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # line, on the next line is information for the compiler and the
740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # output lack information for the C-runtime.
750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    msc_pos = sys.version.find('MSC v.')
760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    if msc_pos != -1:
770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        msc_ver = sys.version[msc_pos+6:msc_pos+10]
780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if msc_ver == '1300':
790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # MSVC 7.0
800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            return ['msvcr70']
810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        elif msc_ver == '1310':
820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # MSVC 7.1
830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            return ['msvcr71']
840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        elif msc_ver == '1400':
850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # VS2005 / MSVC 8.0
860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            return ['msvcr80']
870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        elif msc_ver == '1500':
880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # VS2008 / MSVC 9.0
890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            return ['msvcr90']
900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        else:
910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            raise ValueError("Unknown MS Compiler version %s " % msc_ver)
920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    else:
930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return []
940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
960a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass CygwinCCompiler (UnixCCompiler):
970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    compiler_type = 'cygwin'
990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    obj_extension = ".o"
1000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    static_lib_extension = ".a"
1010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    shared_lib_extension = ".dll"
1020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # FIXME: dylib_... = ".dll.a" is not enought for binutils
1030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # loader on win32 platform !!!
1040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    dylib_lib_extension = ".dll.a"
1050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    static_lib_format = "lib%s%s"
1060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    shared_lib_format = "%s%s"
1070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    exe_extension = ".exe"
1080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def __init__ (self, verbose=0, dry_run=0, force=0):
1100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        UnixCCompiler.__init__ (self, verbose, dry_run, force)
1120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        (status, details) = check_config_h()
1140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.debug_print("Python's GCC status: %s (details: %s)" %
1150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                         (status, details))
1160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if status is not CONFIG_H_OK:
1170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.warn(
1180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                "Python's pyconfig.h doesn't seem to support your compiler. "
1190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                "Reason: %s. "
1200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                "Compiling may fail because of undefined preprocessor macros."
1210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                % details)
1220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Next line of code is problem for cross-compiled enviroment:
1240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # NOTE: GCC cross-compiler is prefixed by the <hostarch>-<hostos>-
1250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # and by default binaries are installed in same directory
1260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # as native compiler.
1270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.gcc_version, self.ld_version, self.dllwrap_version = \
1280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            get_versions()
1290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.debug_print(self.compiler_type + ": gcc %s, ld %s, dllwrap %s\n" %
1300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                         (self.gcc_version,
1310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                          self.ld_version,
1320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                          self.dllwrap_version) )
1330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # ld_version >= "2.10.90" and < "2.13" should also be able to use
1350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # gcc -mdll instead of dllwrap
1360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Older dllwraps had own version numbers, newer ones use the
1370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # same as the rest of binutils ( also ld )
1380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # dllwrap 2.10.90 is buggy
1390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if self.ld_version >= "2.10.90":
1400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.linker_dll = "gcc"
1410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        else:
1420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.linker_dll = "dllwrap"
1430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # ld_version >= "2.13" support -shared so use it instead of
1450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # -mdll -static
1460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if self.ld_version >= "2.13":
1470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            shared_option = "-shared"
1480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        else:
1490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            shared_option = "-mdll -static"
1500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # FIXME:
1520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Hard-code may override unix-compiler settings and isn't
1530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # possible to use Makefile variables to pass correct flags !
1540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Hard-code GCC because that's what this is all about.
1550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # XXX optimization, warnings etc. should be customizable.
1560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.set_executables(compiler='gcc -mcygwin -O -Wall',
1570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                             compiler_so='gcc -mcygwin -mdll -O -Wall',
1580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                             compiler_cxx='g++ -mcygwin -O -Wall',
1590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                             linker_exe='gcc -mcygwin',
1600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                             linker_so=('%s -mcygwin %s' %
1610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                                        (self.linker_dll, shared_option)))
1620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # cygwin and mingw32 need different sets of libraries
1640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if self.gcc_version == "2.91.57":
1650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # cygwin shouldn't need msvcrt, but without the dlls will crash
1660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # (gcc version 2.91.57) -- perhaps something about initialization
1670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.dll_libraries=["msvcrt"]
1680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.warn(
1690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                "Consider upgrading to a newer version of gcc")
1700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        else:
1710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # Include the appropriate MSVC runtime library if Python was built
1720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # with MSVC 7.0 or later.
1730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.dll_libraries = get_msvcr()
1740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # __init__ ()
1760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def _compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts):
1790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if ext == '.rc' or ext == '.res':
1800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # gcc needs '.res' and '.rc' compiled to object files !!!
1810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            try:
1820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.spawn(["windres", "-i", src, "-o", obj])
1830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            except DistutilsExecError, msg:
1840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                raise CompileError, msg
1850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        else: # for other files use the C-compiler
1860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            try:
1870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.spawn(self.compiler_so + cc_args + [src, '-o', obj] +
1880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                           extra_postargs)
1890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            except DistutilsExecError, msg:
1900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                raise CompileError, msg
1910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def link (self,
1930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao              target_desc,
1940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao              objects,
1950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao              output_filename,
1960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao              output_dir=None,
1970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao              libraries=None,
1980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao              library_dirs=None,
1990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao              runtime_library_dirs=None,
2000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao              export_symbols=None,
2010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao              debug=0,
2020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao              extra_preargs=None,
2030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao              extra_postargs=None,
2040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao              build_temp=None,
2050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao              target_lang=None):
2060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # use separate copies, so we can modify the lists
2080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        extra_preargs = copy.copy(extra_preargs or [])
2090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        libraries = copy.copy(libraries or [])
2100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        objects = copy.copy(objects or [])
2110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Additional libraries
2130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        libraries.extend(self.dll_libraries)
2140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # handle export symbols by creating a def-file
2160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # with executables this only works with gcc/ld as linker
2170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if ((export_symbols is not None) and
2180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            (target_desc != self.EXECUTABLE or self.linker_dll == "gcc")):
2190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # (The linker doesn't do anything if output is up-to-date.
2200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # So it would probably better to check if we really need this,
2210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # but for this we had to insert some unchanged parts of
2220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # UnixCCompiler, and this is not what we want.)
2230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # we want to put some files in the same directory as the
2250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # object files are, build_temp doesn't help much
2260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # where are the object files
2270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            temp_dir = os.path.dirname(objects[0])
2280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # name of dll to give the helper files the same base name
2290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            (dll_name, dll_extension) = os.path.splitext(
2300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                os.path.basename(output_filename))
2310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # generate the filenames for these files
2330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def_file = os.path.join(temp_dir, dll_name + ".def")
2340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            lib_file = os.path.join(temp_dir, 'lib' + dll_name + ".a")
2350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # Generate .def file
2370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            contents = [
2380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                "LIBRARY %s" % os.path.basename(output_filename),
2390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                "EXPORTS"]
2400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            for sym in export_symbols:
2410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                contents.append(sym)
2420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.execute(write_file, (def_file, contents),
2430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                         "writing %s" % def_file)
2440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # next add options for def-file and to creating import libraries
2460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # dllwrap uses different options than gcc/ld
2480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if self.linker_dll == "dllwrap":
2490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                extra_preargs.extend(["--output-lib", lib_file])
2500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                # for dllwrap we have to use a special option
2510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                extra_preargs.extend(["--def", def_file])
2520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # we use gcc/ld here and can be sure ld is >= 2.9.10
2530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            else:
2540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                # doesn't work: bfd_close build\...\libfoo.a: Invalid operation
2550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                #extra_preargs.extend(["-Wl,--out-implib,%s" % lib_file])
2560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                # for gcc/ld the def-file is specified as any object files
2570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                objects.append(def_file)
2580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        #end: if ((export_symbols is not None) and
2600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        #        (target_desc != self.EXECUTABLE or self.linker_dll == "gcc")):
2610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # who wants symbols and a many times larger output file
2630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # should explicitly switch the debug mode on
2640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # otherwise we let dllwrap/ld strip the output file
2650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # (On my machine: 10KB < stripped_file < ??100KB
2660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        #   unstripped_file = stripped_file + XXX KB
2670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        #  ( XXX=254 for a typical python extension))
2680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if not debug:
2690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            extra_preargs.append("-s")
2700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        UnixCCompiler.link(self,
2720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                           target_desc,
2730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                           objects,
2740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                           output_filename,
2750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                           output_dir,
2760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                           libraries,
2770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                           library_dirs,
2780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                           runtime_library_dirs,
2790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                           None, # export_symbols, we do this in our def-file
2800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                           debug,
2810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                           extra_preargs,
2820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                           extra_postargs,
2830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                           build_temp,
2840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                           target_lang)
2850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # link ()
2870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # -- Miscellaneous methods -----------------------------------------
2890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # overwrite the one from CCompiler to support rc and res-files
2910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def object_filenames (self,
2920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                          source_filenames,
2930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                          strip_dir=0,
2940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                          output_dir=''):
2950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if output_dir is None: output_dir = ''
2960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        obj_names = []
2970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for src_name in source_filenames:
2980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # FIXME: "bogus checks for suffix" - as example the commented
2990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # by #BOGUS# code break valid assembler suffix ".S" !
3000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            #BOGUS## use normcase to make sure '.rc' is really '.rc' and not '.RC'
3010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            #BOGUS#base, ext = os.path.splitext(os.path.normcase(src_name))
3020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            base, ext = os.path.splitext (src_name)
3030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            ext_normcase = os.path.normcase(ext)
3040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if ext_normcase in ['.rc','.res']:
3050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                ext = ext_normcase
3060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if ext not in (self.src_extensions + ['.rc','.res']):
3070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                raise UnknownFileError, \
3080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                      "unknown file type '%s' (from '%s')" % \
3090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                      (ext, src_name)
3100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            base = os.path.splitdrive(base)[1] # Chop off the drive
3110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            base = base[os.path.isabs(base):]  # If abs, chop off leading /
3120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if strip_dir:
3130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                base = os.path.basename (base)
3140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if ext == '.res' or ext == '.rc':
3150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                # these need to be compiled to object files
3160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                obj_names.append (os.path.join (output_dir,
3170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                                            base + ext + self.obj_extension))
3180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            else:
3190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                obj_names.append (os.path.join (output_dir,
3200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                                            base + self.obj_extension))
3210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return obj_names
3220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # object_filenames ()
3240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# class CygwinCCompiler
3260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# the same as cygwin plus some additional parameters
3290a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass Mingw32CCompiler (CygwinCCompiler):
3300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    compiler_type = 'mingw32'
3320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def __init__ (self,
3340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                  verbose=0,
3350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                  dry_run=0,
3360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                  force=0):
3370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        CygwinCCompiler.__init__ (self, verbose, dry_run, force)
3390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # ld_version >= "2.13" support -shared so use it instead of
3410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # -mdll -static
3420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if self.ld_version >= "2.13":
3430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            shared_option = "-shared"
3440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        else:
3450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            shared_option = "-mdll -static"
3460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # A real mingw32 doesn't need to specify a different entry point,
3480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # but cygwin 2.91.57 in no-cygwin-mode needs it.
3490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if self.gcc_version <= "2.91.57":
3500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            entry_point = '--entry _DllMain@12'
3510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        else:
3520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            entry_point = ''
3530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.set_executables(compiler='gcc -mno-cygwin -O -Wall',
3550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                             compiler_so='gcc -mno-cygwin -mdll -O -Wall',
3560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                             compiler_cxx='g++ -mno-cygwin -O -Wall',
3570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                             linker_exe='gcc -mno-cygwin',
3580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                             linker_so='%s -mno-cygwin %s %s'
3590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                                        % (self.linker_dll, shared_option,
3600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                                           entry_point))
3610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Maybe we should also append -mthreads, but then the finished
3620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # dlls need another dll (mingwm10.dll see Mingw32 docs)
3630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # (-mthreads: Support thread-safe exception handling on `Mingw32')
3640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # no additional libraries needed
3660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.dll_libraries=[]
3670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Include the appropriate MSVC runtime library if Python was built
3690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # with MSVC 7.0 or later.
3700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.dll_libraries = get_msvcr()
3710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # __init__ ()
3730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# class Mingw32CCompiler
3750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# Because these compilers aren't configured in Python's pyconfig.h file by
3770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# default, we should at least warn the user if he is using a unmodified
3780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# version.
3790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3800a8c90248264a8b26970b4473770bcc3df8515fJosh GaoCONFIG_H_OK = "ok"
3810a8c90248264a8b26970b4473770bcc3df8515fJosh GaoCONFIG_H_NOTOK = "not ok"
3820a8c90248264a8b26970b4473770bcc3df8515fJosh GaoCONFIG_H_UNCERTAIN = "uncertain"
3830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3840a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef check_config_h():
3850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """Check if the current Python installation (specifically, pyconfig.h)
3870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    appears amenable to building extensions with GCC.  Returns a tuple
3880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    (status, details), where 'status' is one of the following constants:
3890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao      CONFIG_H_OK
3900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        all is well, go ahead and compile
3910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao      CONFIG_H_NOTOK
3920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        doesn't look good
3930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao      CONFIG_H_UNCERTAIN
3940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        not sure -- unable to read pyconfig.h
3950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    'details' is a human-readable string explaining the situation.
3960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    Note there are two ways to conclude "OK": either 'sys.version' contains
3980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    the string "GCC" (implying that this Python was built with GCC), or the
3990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    installed "pyconfig.h" contains the string "__GNUC__".
4000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """
4010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # XXX since this function also checks sys.version, it's not strictly a
4030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # "pyconfig.h" check -- should probably be renamed...
4040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    from distutils import sysconfig
4060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    import string
4070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # if sys.version contains GCC then python was compiled with
4080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # GCC, and the pyconfig.h file should be OK
4090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    if string.find(sys.version,"GCC") >= 0:
4100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return (CONFIG_H_OK, "sys.version mentions 'GCC'")
4110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    fn = sysconfig.get_config_h_filename()
4130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    try:
4140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # It would probably better to read single lines to search.
4150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # But we do this only once, and it is fast enough
4160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        f = open(fn)
4170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        try:
4180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            s = f.read()
4190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        finally:
4200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            f.close()
4210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    except IOError, exc:
4230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # if we can't read this file, we cannot say it is wrong
4240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # the compiler will complain later about this file as missing
4250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return (CONFIG_H_UNCERTAIN,
4260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                "couldn't read '%s': %s" % (fn, exc.strerror))
4270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    else:
4290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # "pyconfig.h" contains an "#ifdef __GNUC__" or something similar
4300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if string.find(s,"__GNUC__") >= 0:
4310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            return (CONFIG_H_OK, "'%s' mentions '__GNUC__'" % fn)
4320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        else:
4330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            return (CONFIG_H_NOTOK, "'%s' does not mention '__GNUC__'" % fn)
4340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4370a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef get_versions():
4380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """ Try to find out the versions of gcc, ld and dllwrap.
4390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        If not possible it returns None for it.
4400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """
4410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    from distutils.version import LooseVersion
4420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    from distutils.spawn import find_executable
4430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    import re
4440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    gcc_exe = os.environ.get('CC') or find_executable('gcc')
4460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    ld_exe = os.environ.get('LD') or find_executable('ld')
4470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    if gcc_exe:
4480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        out = os.popen(gcc_exe + ' -dumpversion','r')
4490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        out_string = out.read()
4500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        out.close()
4510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        result = re.search('(\d+\.\d+(\.\d+)*)',out_string)
4520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if result:
4530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            gcc_version = LooseVersion(result.group(1))
4540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        else:
4550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            gcc_version = None
4560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        out = os.popen(gcc_exe + ' --print-prog-name ld','r')
4570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        ld_exe = out.read().decode('ascii').split()[0]
4580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        out.close()
4590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    else:
4600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        gcc_version = None
4610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    if ld_exe:
4620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        out = os.popen(ld_exe + ' -v','r')
4630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        out_string = out.read()
4640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        out.close()
4650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        result = re.search('(\d+\.\d+(\.\d+)*)',out_string)
4660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if result:
4670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            ld_version = LooseVersion(result.group(1))
4680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        else:
4690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            ld_version = None
4700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    else:
4710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        ld_version = None
4720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    dllwrap_exe = os.environ.get('DLLWRAP') or find_executable('dllwrap')
4730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    if dllwrap_exe:
4740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        out = os.popen(dllwrap_exe + ' --version','r')
4750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        out_string = out.read()
4760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        out.close()
4770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        result = re.search(' (\d+\.\d+(\.\d+)*)',out_string)
4780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if result:
4790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            dllwrap_version = LooseVersion(result.group(1))
4800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        else:
4810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            dllwrap_version = None
4820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    else:
4830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        dllwrap_version = None
4840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    return (gcc_version, ld_version, dllwrap_version)
485