home *** CD-ROM | disk | FTP | other *** search
/ Komputer for Alle 2004 #2 / K-CD-2-2004.ISO / OpenOffice Sv / f_0397 / python-core-2.2.2 / lib / distutils / mwerkscompiler.py < prev    next >
Encoding:
Python Source  |  2003-07-18  |  8.9 KB  |  218 lines

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