symbian-qemu-0.9.1-12/python-win32-2.6.1/lib/distutils/mwerkscompiler.py
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     1 """distutils.mwerkscompiler
       
     2 
       
     3 Contains MWerksCompiler, an implementation of the abstract CCompiler class
       
     4 for MetroWerks CodeWarrior on the Macintosh. Needs work to support CW on
       
     5 Windows."""
       
     6 
       
     7 # This module should be kept compatible with Python 2.1.
       
     8 
       
     9 __revision__ = "$Id: mwerkscompiler.py 55881 2007-06-11 05:28:45Z neal.norwitz $"
       
    10 
       
    11 import sys, os, string
       
    12 from types import *
       
    13 from distutils.errors import \
       
    14      DistutilsExecError, DistutilsPlatformError, \
       
    15      CompileError, LibError, LinkError
       
    16 from distutils.ccompiler import \
       
    17      CCompiler, gen_preprocess_options, gen_lib_options
       
    18 import distutils.util
       
    19 import distutils.dir_util
       
    20 from distutils import log
       
    21 
       
    22 class MWerksCompiler (CCompiler) :
       
    23     """Concrete class that implements an interface to MetroWerks CodeWarrior,
       
    24        as defined by the CCompiler abstract class."""
       
    25 
       
    26     compiler_type = 'mwerks'
       
    27 
       
    28     # Just set this so CCompiler's constructor doesn't barf.  We currently
       
    29     # don't use the 'set_executables()' bureaucracy provided by CCompiler,
       
    30     # as it really isn't necessary for this sort of single-compiler class.
       
    31     # Would be nice to have a consistent interface with UnixCCompiler,
       
    32     # though, so it's worth thinking about.
       
    33     executables = {}
       
    34 
       
    35     # Private class data (need to distinguish C from C++ source for compiler)
       
    36     _c_extensions = ['.c']
       
    37     _cpp_extensions = ['.cc', '.cpp', '.cxx']
       
    38     _rc_extensions = ['.r']
       
    39     _exp_extension = '.exp'
       
    40 
       
    41     # Needed for the filename generation methods provided by the
       
    42     # base class, CCompiler.
       
    43     src_extensions = (_c_extensions + _cpp_extensions +
       
    44                       _rc_extensions)
       
    45     res_extension = '.rsrc'
       
    46     obj_extension = '.obj' # Not used, really
       
    47     static_lib_extension = '.lib'
       
    48     shared_lib_extension = '.slb'
       
    49     static_lib_format = shared_lib_format = '%s%s'
       
    50     exe_extension = ''
       
    51 
       
    52 
       
    53     def __init__ (self,
       
    54                   verbose=0,
       
    55                   dry_run=0,
       
    56                   force=0):
       
    57 
       
    58         CCompiler.__init__ (self, verbose, dry_run, force)
       
    59 
       
    60 
       
    61     def compile (self,
       
    62                  sources,
       
    63                  output_dir=None,
       
    64                  macros=None,
       
    65                  include_dirs=None,
       
    66                  debug=0,
       
    67                  extra_preargs=None,
       
    68                  extra_postargs=None,
       
    69                  depends=None):
       
    70         (output_dir, macros, include_dirs) = \
       
    71            self._fix_compile_args (output_dir, macros, include_dirs)
       
    72         self.__sources = sources
       
    73         self.__macros = macros
       
    74         self.__include_dirs = include_dirs
       
    75         # Don't need extra_preargs and extra_postargs for CW
       
    76         return []
       
    77 
       
    78     def link (self,
       
    79               target_desc,
       
    80               objects,
       
    81               output_filename,
       
    82               output_dir=None,
       
    83               libraries=None,
       
    84               library_dirs=None,
       
    85               runtime_library_dirs=None,
       
    86               export_symbols=None,
       
    87               debug=0,
       
    88               extra_preargs=None,
       
    89               extra_postargs=None,
       
    90               build_temp=None,
       
    91               target_lang=None):
       
    92         # First fixup.
       
    93         (objects, output_dir) = self._fix_object_args (objects, output_dir)
       
    94         (libraries, library_dirs, runtime_library_dirs) = \
       
    95             self._fix_lib_args (libraries, library_dirs, runtime_library_dirs)
       
    96 
       
    97         # First examine a couple of options for things that aren't implemented yet
       
    98         if not target_desc in (self.SHARED_LIBRARY, self.SHARED_OBJECT):
       
    99             raise DistutilsPlatformError, 'Can only make SHARED_LIBRARY or SHARED_OBJECT targets on the Mac'
       
   100         if runtime_library_dirs:
       
   101             raise DistutilsPlatformError, 'Runtime library dirs not implemented yet'
       
   102         if extra_preargs or extra_postargs:
       
   103             raise DistutilsPlatformError, 'Runtime library dirs not implemented yet'
       
   104         if len(export_symbols) != 1:
       
   105             raise DistutilsPlatformError, 'Need exactly one export symbol'
       
   106         # Next there are various things for which we need absolute pathnames.
       
   107         # This is because we (usually) create the project in a subdirectory of
       
   108         # where we are now, and keeping the paths relative is too much work right
       
   109         # now.
       
   110         sources = map(self._filename_to_abs, self.__sources)
       
   111         include_dirs = map(self._filename_to_abs, self.__include_dirs)
       
   112         if objects:
       
   113             objects = map(self._filename_to_abs, objects)
       
   114         else:
       
   115             objects = []
       
   116         if build_temp:
       
   117             build_temp = self._filename_to_abs(build_temp)
       
   118         else:
       
   119             build_temp = os.curdir()
       
   120         if output_dir:
       
   121             output_filename = os.path.join(output_dir, output_filename)
       
   122         # The output filename needs special handling: splitting it into dir and
       
   123         # filename part. Actually I'm not sure this is really needed, but it
       
   124         # can't hurt.
       
   125         output_filename = self._filename_to_abs(output_filename)
       
   126         output_dir, output_filename = os.path.split(output_filename)
       
   127         # Now we need the short names of a couple of things for putting them
       
   128         # into the project.
       
   129         if output_filename[-8:] == '.ppc.slb':
       
   130             basename = output_filename[:-8]
       
   131         elif output_filename[-11:] == '.carbon.slb':
       
   132             basename = output_filename[:-11]
       
   133         else:
       
   134             basename = os.path.strip(output_filename)[0]
       
   135         projectname = basename + '.mcp'
       
   136         targetname = basename
       
   137         xmlname = basename + '.xml'
       
   138         exportname = basename + '.mcp.exp'
       
   139         prefixname = 'mwerks_%s_config.h'%basename
       
   140         # Create the directories we need
       
   141         distutils.dir_util.mkpath(build_temp, dry_run=self.dry_run)
       
   142         distutils.dir_util.mkpath(output_dir, dry_run=self.dry_run)
       
   143         # And on to filling in the parameters for the project builder
       
   144         settings = {}
       
   145         settings['mac_exportname'] = exportname
       
   146         settings['mac_outputdir'] = output_dir
       
   147         settings['mac_dllname'] = output_filename
       
   148         settings['mac_targetname'] = targetname
       
   149         settings['sysprefix'] = sys.prefix
       
   150         settings['mac_sysprefixtype'] = 'Absolute'
       
   151         sourcefilenames = []
       
   152         sourcefiledirs = []
       
   153         for filename in sources + objects:
       
   154             dirname, filename = os.path.split(filename)
       
   155             sourcefilenames.append(filename)
       
   156             if not dirname in sourcefiledirs:
       
   157                 sourcefiledirs.append(dirname)
       
   158         settings['sources'] = sourcefilenames
       
   159         settings['libraries'] = libraries
       
   160         settings['extrasearchdirs'] = sourcefiledirs + include_dirs + library_dirs
       
   161         if self.dry_run:
       
   162             print 'CALLING LINKER IN', os.getcwd()
       
   163             for key, value in settings.items():
       
   164                 print '%20.20s %s'%(key, value)
       
   165             return
       
   166         # Build the export file
       
   167         exportfilename = os.path.join(build_temp, exportname)
       
   168         log.debug("\tCreate export file %s", exportfilename)
       
   169         fp = open(exportfilename, 'w')
       
   170         fp.write('%s\n'%export_symbols[0])
       
   171         fp.close()
       
   172         # Generate the prefix file, if needed, and put it in the settings
       
   173         if self.__macros:
       
   174             prefixfilename = os.path.join(os.getcwd(), os.path.join(build_temp, prefixname))
       
   175             fp = open(prefixfilename, 'w')
       
   176             fp.write('#include "mwerks_shcarbon_config.h"\n')
       
   177             for name, value in self.__macros:
       
   178                 if value is None:
       
   179                     fp.write('#define %s\n'%name)
       
   180                 else:
       
   181                     fp.write('#define %s %s\n'%(name, value))
       
   182             fp.close()
       
   183             settings['prefixname'] = prefixname
       
   184 
       
   185         # Build the XML file. We need the full pathname (only lateron, really)
       
   186         # because we pass this pathname to CodeWarrior in an AppleEvent, and CW
       
   187         # doesn't have a clue about our working directory.
       
   188         xmlfilename = os.path.join(os.getcwd(), os.path.join(build_temp, xmlname))
       
   189         log.debug("\tCreate XML file %s", xmlfilename)
       
   190         import mkcwproject
       
   191         xmlbuilder = mkcwproject.cwxmlgen.ProjectBuilder(settings)
       
   192         xmlbuilder.generate()
       
   193         xmldata = settings['tmp_projectxmldata']
       
   194         fp = open(xmlfilename, 'w')
       
   195         fp.write(xmldata)
       
   196         fp.close()
       
   197         # Generate the project. Again a full pathname.
       
   198         projectfilename = os.path.join(os.getcwd(), os.path.join(build_temp, projectname))
       
   199         log.debug('\tCreate project file %s', projectfilename)
       
   200         mkcwproject.makeproject(xmlfilename, projectfilename)
       
   201         # And build it
       
   202         log.debug('\tBuild project')
       
   203         mkcwproject.buildproject(projectfilename)
       
   204 
       
   205     def _filename_to_abs(self, filename):
       
   206         # Some filenames seem to be unix-like. Convert to Mac names.
       
   207 ##        if '/' in filename and ':' in filename:
       
   208 ##           raise DistutilsPlatformError, 'Filename may be Unix or Mac style: %s'%filename
       
   209 ##        if '/' in filename:
       
   210 ##           filename = macurl2path(filename)
       
   211         filename = distutils.util.convert_path(filename)
       
   212         if not os.path.isabs(filename):
       
   213             curdir = os.getcwd()
       
   214             filename = os.path.join(curdir, filename)
       
   215         # Finally remove .. components
       
   216         components = string.split(filename, ':')
       
   217         for i in range(1, len(components)):
       
   218             if components[i] == '..':
       
   219                 components[i] = ''
       
   220         return string.join(components, ':')
       
   221 
       
   222     def library_dir_option (self, dir):
       
   223         """Return the compiler option to add 'dir' to the list of
       
   224         directories searched for libraries.
       
   225         """
       
   226         return # XXXX Not correct...
       
   227 
       
   228     def runtime_library_dir_option (self, dir):
       
   229         """Return the compiler option to add 'dir' to the list of
       
   230         directories searched for runtime libraries.
       
   231         """
       
   232         # Nothing needed or Mwerks/Mac.
       
   233         return
       
   234 
       
   235     def library_option (self, lib):
       
   236         """Return the compiler option to add 'dir' to the list of libraries
       
   237         linked into the shared library or executable.
       
   238         """
       
   239         return
       
   240 
       
   241     def find_library_file (self, dirs, lib, debug=0):
       
   242         """Search the specified list of directories for a static or shared
       
   243         library file 'lib' and return the full path to that file.  If
       
   244         'debug' true, look for a debugging version (if that makes sense on
       
   245         the current platform).  Return None if 'lib' wasn't found in any of
       
   246         the specified directories.
       
   247         """
       
   248         return 0