]>
git.saurik.com Git - wxWidgets.git/blob - wxPython/distutils/mwerkscompiler.py
   1 """distutils.mwerkscompiler 
   3 Contains MWerksCompiler, an implementation of the abstract CCompiler class 
   4 for MetroWerks CodeWarrior on the Macintosh. Needs work to support CW on 
   7 # This module should be kept compatible with Python 1.5.2. 
  11 import sys
, os
, string
 
  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
 
  19 import distutils
.dir_util
 
  20 from distutils 
import log
 
  23 class MWerksCompiler (CCompiler
) : 
  24     """Concrete class that implements an interface to MetroWerks CodeWarrior, 
  25        as defined by the CCompiler abstract class.""" 
  27     compiler_type 
= 'mwerks' 
  29     # Just set this so CCompiler's constructor doesn't barf.  We currently 
  30     # don't use the 'set_executables()' bureaucracy provided by CCompiler, 
  31     # as it really isn't necessary for this sort of single-compiler class. 
  32     # Would be nice to have a consistent interface with UnixCCompiler, 
  33     # though, so it's worth thinking about. 
  36     # Private class data (need to distinguish C from C++ source for compiler) 
  37     _c_extensions 
= ['.c'] 
  38     _cpp_extensions 
= ['.cc', '.cpp', '.cxx'] 
  39     _rc_extensions 
= ['.r'] 
  40     _exp_extension 
= '.exp' 
  42     # Needed for the filename generation methods provided by the 
  43     # base class, CCompiler. 
  44     src_extensions 
= (_c_extensions 
+ _cpp_extensions 
+ 
  46     res_extension 
= '.rsrc' 
  47     obj_extension 
= '.obj' # Not used, really 
  48     static_lib_extension 
= '.lib' 
  49     shared_lib_extension 
= '.slb' 
  50     static_lib_format 
= shared_lib_format 
= '%s%s' 
  59         CCompiler
.__init
__ (self
, verbose
, dry_run
, force
) 
  71         (output_dir
, macros
, include_dirs
) = \
 
  72            self
._fix
_compile
_args 
(output_dir
, macros
, include_dirs
) 
  73         self
.__sources 
= sources
 
  74         self
.__macros 
= macros
 
  75         self
.__include
_dirs 
= include_dirs
 
  76         # Don't need extra_preargs and extra_postargs for CW 
  86               runtime_library_dirs
=None, 
  94         (objects
, output_dir
) = self
._fix
_object
_args 
(objects
, output_dir
) 
  95         (libraries
, library_dirs
, runtime_library_dirs
) = \
 
  96             self
._fix
_lib
_args 
(libraries
, library_dirs
, runtime_library_dirs
) 
  98         # First examine a couple of options for things that aren't implemented yet 
  99         if not target_desc 
in (self
.SHARED_LIBRARY
, self
.SHARED_OBJECT
): 
 100             raise DistutilsPlatformError
, 'Can only make SHARED_LIBRARY or SHARED_OBJECT targets on the Mac' 
 101         if runtime_library_dirs
: 
 102             raise DistutilsPlatformError
, 'Runtime library dirs not implemented yet' 
 103         if extra_preargs 
or extra_postargs
: 
 104             raise DistutilsPlatformError
, 'Runtime library dirs not implemented yet' 
 105         if len(export_symbols
) != 1: 
 106             raise DistutilsPlatformError
, 'Need exactly one export symbol' 
 107         # Next there are various things for which we need absolute pathnames. 
 108         # This is because we (usually) create the project in a subdirectory of 
 109         # where we are now, and keeping the paths relative is too much work right 
 111         sources 
= map(self
._filename
_to
_abs
, self
.__sources
) 
 112         include_dirs 
= map(self
._filename
_to
_abs
, self
.__include
_dirs
) 
 114             objects 
= map(self
._filename
_to
_abs
, objects
) 
 118             build_temp 
= self
._filename
_to
_abs
(build_temp
) 
 120             build_temp 
= os
.curdir() 
 122             output_filename 
= os
.path
.join(output_dir
, output_filename
) 
 123         # The output filename needs special handling: splitting it into dir and 
 124         # filename part. Actually I'm not sure this is really needed, but it 
 126         output_filename 
= self
._filename
_to
_abs
(output_filename
) 
 127         output_dir
, output_filename 
= os
.path
.split(output_filename
) 
 128         # Now we need the short names of a couple of things for putting them 
 130         if output_filename
[-8:] == '.ppc.slb': 
 131             basename 
= output_filename
[:-8] 
 132         elif output_filename
[-11:] == '.carbon.slb': 
 133             basename 
= output_filename
[:-11] 
 135             basename 
= os
.path
.strip(output_filename
)[0] 
 136         projectname 
= basename 
+ '.mcp' 
 137         targetname 
= basename
 
 138         xmlname 
= basename 
+ '.xml' 
 139         exportname 
= basename 
+ '.mcp.exp' 
 140         prefixname 
= 'mwerks_%s_config.h'%basename
 
 141         # Create the directories we need 
 142         distutils
.dir_util
.mkpath(build_temp
, dry_run
=self
.dry_run
) 
 143         distutils
.dir_util
.mkpath(output_dir
, dry_run
=self
.dry_run
) 
 144         # And on to filling in the parameters for the project builder 
 146         settings
['mac_exportname'] = exportname
 
 147         settings
['mac_outputdir'] = output_dir
 
 148         settings
['mac_dllname'] = output_filename
 
 149         settings
['mac_targetname'] = targetname
 
 150         settings
['sysprefix'] = sys
.prefix
 
 151         settings
['mac_sysprefixtype'] = 'Absolute' 
 154         for filename 
in sources 
+ objects
: 
 155             dirname
, filename 
= os
.path
.split(filename
) 
 156             sourcefilenames
.append(filename
) 
 157             if not dirname 
in sourcefiledirs
: 
 158                 sourcefiledirs
.append(dirname
) 
 159         settings
['sources'] = sourcefilenames
 
 160         settings
['libraries'] = libraries
 
 161         settings
['extrasearchdirs'] = sourcefiledirs 
+ include_dirs 
+ library_dirs
 
 163             print 'CALLING LINKER IN', os
.getcwd() 
 164             for key
, value 
in settings
.items(): 
 165                 print '%20.20s %s'%(key
, value
) 
 167         # Build the export file 
 168         exportfilename 
= os
.path
.join(build_temp
, exportname
) 
 169         log
.debug("\tCreate export file %s", exportfilename
) 
 170         fp 
= open(exportfilename
, 'w') 
 171         fp
.write('%s\n'%export
_symbols
[0]) 
 173         # Generate the prefix file, if needed, and put it in the settings 
 175             prefixfilename 
= os
.path
.join(os
.getcwd(), os
.path
.join(build_temp
, prefixname
)) 
 176             fp 
= open(prefixfilename
, 'w') 
 177             fp
.write('#include "mwerks_shcarbon_config.h"\n') 
 178             for name
, value 
in self
.__macros
: 
 180                     fp
.write('#define %s\n'%name
) 
 182                     fp
.write('#define %s %s\n'%(name
, value
)) 
 184             settings
['prefixname'] = prefixname
 
 186         # Build the XML file. We need the full pathname (only lateron, really) 
 187         # because we pass this pathname to CodeWarrior in an AppleEvent, and CW 
 188         # doesn't have a clue about our working directory. 
 189         xmlfilename 
= os
.path
.join(os
.getcwd(), os
.path
.join(build_temp
, xmlname
)) 
 190         log
.debug("\tCreate XML file %s", xmlfilename
) 
 191         xmlbuilder 
= mkcwproject
.cwxmlgen
.ProjectBuilder(settings
) 
 192         xmlbuilder
.generate() 
 193         xmldata 
= settings
['tmp_projectxmldata'] 
 194         fp 
= open(xmlfilename
, 'w') 
 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
) 
 202         log
.debug('\tBuild project') 
 203         mkcwproject
.buildproject(projectfilename
) 
 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
): 
 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
] == '..': 
 220         return string
.join(components
, ':') 
 222     def library_dir_option (self
, dir): 
 223         """Return the compiler option to add 'dir' to the list of 
 224         directories searched for libraries. 
 226         return # XXXX Not correct... 
 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. 
 232         # Nothing needed or Mwerks/Mac. 
 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. 
 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.