symbian-qemu-0.9.1-12/python-2.6.1/Lib/distutils/cygwinccompiler.py
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     1 """distutils.cygwinccompiler
       
     2 
       
     3 Provides the CygwinCCompiler class, a subclass of UnixCCompiler that
       
     4 handles the Cygwin port of the GNU C compiler to Windows.  It also contains
       
     5 the Mingw32CCompiler class which handles the mingw32 port of GCC (same as
       
     6 cygwin in no-cygwin mode).
       
     7 """
       
     8 
       
     9 # problems:
       
    10 #
       
    11 # * if you use a msvc compiled python version (1.5.2)
       
    12 #   1. you have to insert a __GNUC__ section in its config.h
       
    13 #   2. you have to generate a import library for its dll
       
    14 #      - create a def-file for python??.dll
       
    15 #      - create a import library using
       
    16 #             dlltool --dllname python15.dll --def python15.def \
       
    17 #                       --output-lib libpython15.a
       
    18 #
       
    19 #   see also http://starship.python.net/crew/kernr/mingw32/Notes.html
       
    20 #
       
    21 # * We put export_symbols in a def-file, and don't use
       
    22 #   --export-all-symbols because it doesn't worked reliable in some
       
    23 #   tested configurations. And because other windows compilers also
       
    24 #   need their symbols specified this no serious problem.
       
    25 #
       
    26 # tested configurations:
       
    27 #
       
    28 # * cygwin gcc 2.91.57/ld 2.9.4/dllwrap 0.2.4 works
       
    29 #   (after patching python's config.h and for C++ some other include files)
       
    30 #   see also http://starship.python.net/crew/kernr/mingw32/Notes.html
       
    31 # * mingw32 gcc 2.95.2/ld 2.9.4/dllwrap 0.2.4 works
       
    32 #   (ld doesn't support -shared, so we use dllwrap)
       
    33 # * cygwin gcc 2.95.2/ld 2.10.90/dllwrap 2.10.90 works now
       
    34 #   - its dllwrap doesn't work, there is a bug in binutils 2.10.90
       
    35 #     see also http://sources.redhat.com/ml/cygwin/2000-06/msg01274.html
       
    36 #   - using gcc -mdll instead dllwrap doesn't work without -static because
       
    37 #     it tries to link against dlls instead their import libraries. (If
       
    38 #     it finds the dll first.)
       
    39 #     By specifying -static we force ld to link against the import libraries,
       
    40 #     this is windows standard and there are normally not the necessary symbols
       
    41 #     in the dlls.
       
    42 #   *** only the version of June 2000 shows these problems
       
    43 # * cygwin gcc 3.2/ld 2.13.90 works
       
    44 #   (ld supports -shared)
       
    45 # * mingw gcc 3.2/ld 2.13 works
       
    46 #   (ld supports -shared)
       
    47 
       
    48 # This module should be kept compatible with Python 2.1.
       
    49 
       
    50 __revision__ = "$Id: cygwinccompiler.py 65834 2008-08-18 19:23:47Z amaury.forgeotdarc $"
       
    51 
       
    52 import os,sys,copy
       
    53 from distutils.ccompiler import gen_preprocess_options, gen_lib_options
       
    54 from distutils.unixccompiler import UnixCCompiler
       
    55 from distutils.file_util import write_file
       
    56 from distutils.errors import DistutilsExecError, CompileError, UnknownFileError
       
    57 from distutils import log
       
    58 
       
    59 def get_msvcr():
       
    60     """Include the appropriate MSVC runtime library if Python was built
       
    61     with MSVC 7.0 or later.
       
    62     """
       
    63     msc_pos = sys.version.find('MSC v.')
       
    64     if msc_pos != -1:
       
    65         msc_ver = sys.version[msc_pos+6:msc_pos+10]
       
    66         if msc_ver == '1300':
       
    67             # MSVC 7.0
       
    68             return ['msvcr70']
       
    69         elif msc_ver == '1310':
       
    70             # MSVC 7.1
       
    71             return ['msvcr71']
       
    72         elif msc_ver == '1400':
       
    73             # VS2005 / MSVC 8.0
       
    74             return ['msvcr80']
       
    75         elif msc_ver == '1500':
       
    76             # VS2008 / MSVC 9.0
       
    77             return ['msvcr90']
       
    78         else:
       
    79             raise ValueError("Unknown MS Compiler version %i " % msc_Ver)
       
    80 
       
    81 
       
    82 class CygwinCCompiler (UnixCCompiler):
       
    83 
       
    84     compiler_type = 'cygwin'
       
    85     obj_extension = ".o"
       
    86     static_lib_extension = ".a"
       
    87     shared_lib_extension = ".dll"
       
    88     static_lib_format = "lib%s%s"
       
    89     shared_lib_format = "%s%s"
       
    90     exe_extension = ".exe"
       
    91 
       
    92     def __init__ (self, verbose=0, dry_run=0, force=0):
       
    93 
       
    94         UnixCCompiler.__init__ (self, verbose, dry_run, force)
       
    95 
       
    96         (status, details) = check_config_h()
       
    97         self.debug_print("Python's GCC status: %s (details: %s)" %
       
    98                          (status, details))
       
    99         if status is not CONFIG_H_OK:
       
   100             self.warn(
       
   101                 "Python's pyconfig.h doesn't seem to support your compiler. "
       
   102                 "Reason: %s. "
       
   103                 "Compiling may fail because of undefined preprocessor macros."
       
   104                 % details)
       
   105 
       
   106         self.gcc_version, self.ld_version, self.dllwrap_version = \
       
   107             get_versions()
       
   108         self.debug_print(self.compiler_type + ": gcc %s, ld %s, dllwrap %s\n" %
       
   109                          (self.gcc_version,
       
   110                           self.ld_version,
       
   111                           self.dllwrap_version) )
       
   112 
       
   113         # ld_version >= "2.10.90" and < "2.13" should also be able to use
       
   114         # gcc -mdll instead of dllwrap
       
   115         # Older dllwraps had own version numbers, newer ones use the
       
   116         # same as the rest of binutils ( also ld )
       
   117         # dllwrap 2.10.90 is buggy
       
   118         if self.ld_version >= "2.10.90":
       
   119             self.linker_dll = "gcc"
       
   120         else:
       
   121             self.linker_dll = "dllwrap"
       
   122 
       
   123         # ld_version >= "2.13" support -shared so use it instead of
       
   124         # -mdll -static
       
   125         if self.ld_version >= "2.13":
       
   126             shared_option = "-shared"
       
   127         else:
       
   128             shared_option = "-mdll -static"
       
   129 
       
   130         # Hard-code GCC because that's what this is all about.
       
   131         # XXX optimization, warnings etc. should be customizable.
       
   132         self.set_executables(compiler='gcc -mcygwin -O -Wall',
       
   133                              compiler_so='gcc -mcygwin -mdll -O -Wall',
       
   134                              compiler_cxx='g++ -mcygwin -O -Wall',
       
   135                              linker_exe='gcc -mcygwin',
       
   136                              linker_so=('%s -mcygwin %s' %
       
   137                                         (self.linker_dll, shared_option)))
       
   138 
       
   139         # cygwin and mingw32 need different sets of libraries
       
   140         if self.gcc_version == "2.91.57":
       
   141             # cygwin shouldn't need msvcrt, but without the dlls will crash
       
   142             # (gcc version 2.91.57) -- perhaps something about initialization
       
   143             self.dll_libraries=["msvcrt"]
       
   144             self.warn(
       
   145                 "Consider upgrading to a newer version of gcc")
       
   146         else:
       
   147             # Include the appropriate MSVC runtime library if Python was built
       
   148             # with MSVC 7.0 or later.
       
   149             self.dll_libraries = get_msvcr()
       
   150 
       
   151     # __init__ ()
       
   152 
       
   153 
       
   154     def _compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts):
       
   155         if ext == '.rc' or ext == '.res':
       
   156             # gcc needs '.res' and '.rc' compiled to object files !!!
       
   157             try:
       
   158                 self.spawn(["windres", "-i", src, "-o", obj])
       
   159             except DistutilsExecError, msg:
       
   160                 raise CompileError, msg
       
   161         else: # for other files use the C-compiler
       
   162             try:
       
   163                 self.spawn(self.compiler_so + cc_args + [src, '-o', obj] +
       
   164                            extra_postargs)
       
   165             except DistutilsExecError, msg:
       
   166                 raise CompileError, msg
       
   167 
       
   168     def link (self,
       
   169               target_desc,
       
   170               objects,
       
   171               output_filename,
       
   172               output_dir=None,
       
   173               libraries=None,
       
   174               library_dirs=None,
       
   175               runtime_library_dirs=None,
       
   176               export_symbols=None,
       
   177               debug=0,
       
   178               extra_preargs=None,
       
   179               extra_postargs=None,
       
   180               build_temp=None,
       
   181               target_lang=None):
       
   182 
       
   183         # use separate copies, so we can modify the lists
       
   184         extra_preargs = copy.copy(extra_preargs or [])
       
   185         libraries = copy.copy(libraries or [])
       
   186         objects = copy.copy(objects or [])
       
   187 
       
   188         # Additional libraries
       
   189         libraries.extend(self.dll_libraries)
       
   190 
       
   191         # handle export symbols by creating a def-file
       
   192         # with executables this only works with gcc/ld as linker
       
   193         if ((export_symbols is not None) and
       
   194             (target_desc != self.EXECUTABLE or self.linker_dll == "gcc")):
       
   195             # (The linker doesn't do anything if output is up-to-date.
       
   196             # So it would probably better to check if we really need this,
       
   197             # but for this we had to insert some unchanged parts of
       
   198             # UnixCCompiler, and this is not what we want.)
       
   199 
       
   200             # we want to put some files in the same directory as the
       
   201             # object files are, build_temp doesn't help much
       
   202             # where are the object files
       
   203             temp_dir = os.path.dirname(objects[0])
       
   204             # name of dll to give the helper files the same base name
       
   205             (dll_name, dll_extension) = os.path.splitext(
       
   206                 os.path.basename(output_filename))
       
   207 
       
   208             # generate the filenames for these files
       
   209             def_file = os.path.join(temp_dir, dll_name + ".def")
       
   210             lib_file = os.path.join(temp_dir, 'lib' + dll_name + ".a")
       
   211 
       
   212             # Generate .def file
       
   213             contents = [
       
   214                 "LIBRARY %s" % os.path.basename(output_filename),
       
   215                 "EXPORTS"]
       
   216             for sym in export_symbols:
       
   217                 contents.append(sym)
       
   218             self.execute(write_file, (def_file, contents),
       
   219                          "writing %s" % def_file)
       
   220 
       
   221             # next add options for def-file and to creating import libraries
       
   222 
       
   223             # dllwrap uses different options than gcc/ld
       
   224             if self.linker_dll == "dllwrap":
       
   225                 extra_preargs.extend(["--output-lib", lib_file])
       
   226                 # for dllwrap we have to use a special option
       
   227                 extra_preargs.extend(["--def", def_file])
       
   228             # we use gcc/ld here and can be sure ld is >= 2.9.10
       
   229             else:
       
   230                 # doesn't work: bfd_close build\...\libfoo.a: Invalid operation
       
   231                 #extra_preargs.extend(["-Wl,--out-implib,%s" % lib_file])
       
   232                 # for gcc/ld the def-file is specified as any object files
       
   233                 objects.append(def_file)
       
   234 
       
   235         #end: if ((export_symbols is not None) and
       
   236         #        (target_desc != self.EXECUTABLE or self.linker_dll == "gcc")):
       
   237 
       
   238         # who wants symbols and a many times larger output file
       
   239         # should explicitly switch the debug mode on
       
   240         # otherwise we let dllwrap/ld strip the output file
       
   241         # (On my machine: 10KB < stripped_file < ??100KB
       
   242         #   unstripped_file = stripped_file + XXX KB
       
   243         #  ( XXX=254 for a typical python extension))
       
   244         if not debug:
       
   245             extra_preargs.append("-s")
       
   246 
       
   247         UnixCCompiler.link(self,
       
   248                            target_desc,
       
   249                            objects,
       
   250                            output_filename,
       
   251                            output_dir,
       
   252                            libraries,
       
   253                            library_dirs,
       
   254                            runtime_library_dirs,
       
   255                            None, # export_symbols, we do this in our def-file
       
   256                            debug,
       
   257                            extra_preargs,
       
   258                            extra_postargs,
       
   259                            build_temp,
       
   260                            target_lang)
       
   261 
       
   262     # link ()
       
   263 
       
   264     # -- Miscellaneous methods -----------------------------------------
       
   265 
       
   266     # overwrite the one from CCompiler to support rc and res-files
       
   267     def object_filenames (self,
       
   268                           source_filenames,
       
   269                           strip_dir=0,
       
   270                           output_dir=''):
       
   271         if output_dir is None: output_dir = ''
       
   272         obj_names = []
       
   273         for src_name in source_filenames:
       
   274             # use normcase to make sure '.rc' is really '.rc' and not '.RC'
       
   275             (base, ext) = os.path.splitext (os.path.normcase(src_name))
       
   276             if ext not in (self.src_extensions + ['.rc','.res']):
       
   277                 raise UnknownFileError, \
       
   278                       "unknown file type '%s' (from '%s')" % \
       
   279                       (ext, src_name)
       
   280             if strip_dir:
       
   281                 base = os.path.basename (base)
       
   282             if ext == '.res' or ext == '.rc':
       
   283                 # these need to be compiled to object files
       
   284                 obj_names.append (os.path.join (output_dir,
       
   285                                             base + ext + self.obj_extension))
       
   286             else:
       
   287                 obj_names.append (os.path.join (output_dir,
       
   288                                             base + self.obj_extension))
       
   289         return obj_names
       
   290 
       
   291     # object_filenames ()
       
   292 
       
   293 # class CygwinCCompiler
       
   294 
       
   295 
       
   296 # the same as cygwin plus some additional parameters
       
   297 class Mingw32CCompiler (CygwinCCompiler):
       
   298 
       
   299     compiler_type = 'mingw32'
       
   300 
       
   301     def __init__ (self,
       
   302                   verbose=0,
       
   303                   dry_run=0,
       
   304                   force=0):
       
   305 
       
   306         CygwinCCompiler.__init__ (self, verbose, dry_run, force)
       
   307 
       
   308         # ld_version >= "2.13" support -shared so use it instead of
       
   309         # -mdll -static
       
   310         if self.ld_version >= "2.13":
       
   311             shared_option = "-shared"
       
   312         else:
       
   313             shared_option = "-mdll -static"
       
   314 
       
   315         # A real mingw32 doesn't need to specify a different entry point,
       
   316         # but cygwin 2.91.57 in no-cygwin-mode needs it.
       
   317         if self.gcc_version <= "2.91.57":
       
   318             entry_point = '--entry _DllMain@12'
       
   319         else:
       
   320             entry_point = ''
       
   321 
       
   322         self.set_executables(compiler='gcc -mno-cygwin -O -Wall',
       
   323                              compiler_so='gcc -mno-cygwin -mdll -O -Wall',
       
   324                              compiler_cxx='g++ -mno-cygwin -O -Wall',
       
   325                              linker_exe='gcc -mno-cygwin',
       
   326                              linker_so='%s -mno-cygwin %s %s'
       
   327                                         % (self.linker_dll, shared_option,
       
   328                                            entry_point))
       
   329         # Maybe we should also append -mthreads, but then the finished
       
   330         # dlls need another dll (mingwm10.dll see Mingw32 docs)
       
   331         # (-mthreads: Support thread-safe exception handling on `Mingw32')
       
   332 
       
   333         # no additional libraries needed
       
   334         self.dll_libraries=[]
       
   335 
       
   336         # Include the appropriate MSVC runtime library if Python was built
       
   337         # with MSVC 7.0 or later.
       
   338         self.dll_libraries = get_msvcr()
       
   339 
       
   340     # __init__ ()
       
   341 
       
   342 # class Mingw32CCompiler
       
   343 
       
   344 # Because these compilers aren't configured in Python's pyconfig.h file by
       
   345 # default, we should at least warn the user if he is using a unmodified
       
   346 # version.
       
   347 
       
   348 CONFIG_H_OK = "ok"
       
   349 CONFIG_H_NOTOK = "not ok"
       
   350 CONFIG_H_UNCERTAIN = "uncertain"
       
   351 
       
   352 def check_config_h():
       
   353 
       
   354     """Check if the current Python installation (specifically, pyconfig.h)
       
   355     appears amenable to building extensions with GCC.  Returns a tuple
       
   356     (status, details), where 'status' is one of the following constants:
       
   357       CONFIG_H_OK
       
   358         all is well, go ahead and compile
       
   359       CONFIG_H_NOTOK
       
   360         doesn't look good
       
   361       CONFIG_H_UNCERTAIN
       
   362         not sure -- unable to read pyconfig.h
       
   363     'details' is a human-readable string explaining the situation.
       
   364 
       
   365     Note there are two ways to conclude "OK": either 'sys.version' contains
       
   366     the string "GCC" (implying that this Python was built with GCC), or the
       
   367     installed "pyconfig.h" contains the string "__GNUC__".
       
   368     """
       
   369 
       
   370     # XXX since this function also checks sys.version, it's not strictly a
       
   371     # "pyconfig.h" check -- should probably be renamed...
       
   372 
       
   373     from distutils import sysconfig
       
   374     import string
       
   375     # if sys.version contains GCC then python was compiled with
       
   376     # GCC, and the pyconfig.h file should be OK
       
   377     if string.find(sys.version,"GCC") >= 0:
       
   378         return (CONFIG_H_OK, "sys.version mentions 'GCC'")
       
   379 
       
   380     fn = sysconfig.get_config_h_filename()
       
   381     try:
       
   382         # It would probably better to read single lines to search.
       
   383         # But we do this only once, and it is fast enough
       
   384         f = open(fn)
       
   385         s = f.read()
       
   386         f.close()
       
   387 
       
   388     except IOError, exc:
       
   389         # if we can't read this file, we cannot say it is wrong
       
   390         # the compiler will complain later about this file as missing
       
   391         return (CONFIG_H_UNCERTAIN,
       
   392                 "couldn't read '%s': %s" % (fn, exc.strerror))
       
   393 
       
   394     else:
       
   395         # "pyconfig.h" contains an "#ifdef __GNUC__" or something similar
       
   396         if string.find(s,"__GNUC__") >= 0:
       
   397             return (CONFIG_H_OK, "'%s' mentions '__GNUC__'" % fn)
       
   398         else:
       
   399             return (CONFIG_H_NOTOK, "'%s' does not mention '__GNUC__'" % fn)
       
   400 
       
   401 
       
   402 
       
   403 def get_versions():
       
   404     """ Try to find out the versions of gcc, ld and dllwrap.
       
   405         If not possible it returns None for it.
       
   406     """
       
   407     from distutils.version import LooseVersion
       
   408     from distutils.spawn import find_executable
       
   409     import re
       
   410 
       
   411     gcc_exe = find_executable('gcc')
       
   412     if gcc_exe:
       
   413         out = os.popen(gcc_exe + ' -dumpversion','r')
       
   414         out_string = out.read()
       
   415         out.close()
       
   416         result = re.search('(\d+\.\d+(\.\d+)*)',out_string)
       
   417         if result:
       
   418             gcc_version = LooseVersion(result.group(1))
       
   419         else:
       
   420             gcc_version = None
       
   421     else:
       
   422         gcc_version = None
       
   423     ld_exe = find_executable('ld')
       
   424     if ld_exe:
       
   425         out = os.popen(ld_exe + ' -v','r')
       
   426         out_string = out.read()
       
   427         out.close()
       
   428         result = re.search('(\d+\.\d+(\.\d+)*)',out_string)
       
   429         if result:
       
   430             ld_version = LooseVersion(result.group(1))
       
   431         else:
       
   432             ld_version = None
       
   433     else:
       
   434         ld_version = None
       
   435     dllwrap_exe = find_executable('dllwrap')
       
   436     if dllwrap_exe:
       
   437         out = os.popen(dllwrap_exe + ' --version','r')
       
   438         out_string = out.read()
       
   439         out.close()
       
   440         result = re.search(' (\d+\.\d+(\.\d+)*)',out_string)
       
   441         if result:
       
   442             dllwrap_version = LooseVersion(result.group(1))
       
   443         else:
       
   444             dllwrap_version = None
       
   445     else:
       
   446         dllwrap_version = None
       
   447     return (gcc_version, ld_version, dllwrap_version)