home *** CD-ROM | disk | FTP | other *** search
/ Chip 2004 December / CHIP_CD_2004-12.iso / bonus / oo / OOo_1.1.3_ru_RU_infra_WinIntel_install.exe / $PLUGINSDIR / f_0372 / python-core-2.2.2 / lib / distutils / unixccompiler.py < prev    next >
Text File  |  2004-10-09  |  12KB  |  306 lines

  1. """distutils.unixccompiler
  2.  
  3. Contains the UnixCCompiler class, a subclass of CCompiler that handles
  4. the "typical" Unix-style command-line C compiler:
  5.   * macros defined with -Dname[=value]
  6.   * macros undefined with -Uname
  7.   * include search directories specified with -Idir
  8.   * libraries specified with -lllib
  9.   * library search directories specified with -Ldir
  10.   * compile handled by 'cc' (or similar) executable with -c option:
  11.     compiles .c to .o
  12.   * link static library handled by 'ar' command (possibly with 'ranlib')
  13.   * link shared library handled by 'cc -shared'
  14. """
  15.  
  16. # created 1999/07/05, Greg Ward
  17.  
  18. __revision__ = "$Id: unixccompiler.py,v 1.38.6.1 2002/03/17 19:47:39 mwh Exp $"
  19.  
  20. import string, re, os, sys
  21. from types import *
  22. from copy import copy
  23. from distutils import sysconfig
  24. from distutils.dep_util import newer
  25. from distutils.ccompiler import \
  26.      CCompiler, gen_preprocess_options, gen_lib_options
  27. from distutils.errors import \
  28.      DistutilsExecError, CompileError, LibError, LinkError
  29.  
  30. # XXX Things not currently handled:
  31. #   * optimization/debug/warning flags; we just use whatever's in Python's
  32. #     Makefile and live with it.  Is this adequate?  If not, we might
  33. #     have to have a bunch of subclasses GNUCCompiler, SGICCompiler,
  34. #     SunCCompiler, and I suspect down that road lies madness.
  35. #   * even if we don't know a warning flag from an optimization flag,
  36. #     we need some way for outsiders to feed preprocessor/compiler/linker
  37. #     flags in to us -- eg. a sysadmin might want to mandate certain flags
  38. #     via a site config file, or a user might want to set something for
  39. #     compiling this module distribution only via the setup.py command
  40. #     line, whatever.  As long as these options come from something on the
  41. #     current system, they can be as system-dependent as they like, and we
  42. #     should just happily stuff them into the preprocessor/compiler/linker
  43. #     options and carry on.
  44.  
  45.  
  46. class UnixCCompiler (CCompiler):
  47.  
  48.     compiler_type = 'unix'
  49.  
  50.     # These are used by CCompiler in two places: the constructor sets
  51.     # instance attributes 'preprocessor', 'compiler', etc. from them, and
  52.     # 'set_executable()' allows any of these to be set.  The defaults here
  53.     # are pretty generic; they will probably have to be set by an outsider
  54.     # (eg. using information discovered by the sysconfig about building
  55.     # Python extensions).
  56.     executables = {'preprocessor' : None,
  57.                    'compiler'     : ["cc"],
  58.                    'compiler_so'  : ["cc"],
  59.                    'linker_so'    : ["cc", "-shared"],
  60.                    'linker_exe'   : ["cc"],
  61.                    'archiver'     : ["ar", "-cr"],
  62.                    'ranlib'       : None,
  63.                   }
  64.  
  65.     if sys.platform[:6] == "darwin":
  66.         executables['ranlib'] = ["ranlib"]
  67.  
  68.     # Needed for the filename generation methods provided by the base
  69.     # class, CCompiler.  NB. whoever instantiates/uses a particular
  70.     # UnixCCompiler instance should set 'shared_lib_ext' -- we set a
  71.     # reasonable common default here, but it's not necessarily used on all
  72.     # Unices!
  73.  
  74.     src_extensions = [".c",".C",".cc",".cxx",".cpp",".m"]
  75.     obj_extension = ".o"
  76.     static_lib_extension = ".a"
  77.     shared_lib_extension = ".so"
  78.     dylib_lib_extension = ".dylib"
  79.     static_lib_format = shared_lib_format = dylib_lib_format = "lib%s%s"
  80.  
  81.  
  82.  
  83.     def __init__ (self,
  84.                   verbose=0,
  85.                   dry_run=0,
  86.                   force=0):
  87.         CCompiler.__init__ (self, verbose, dry_run, force)
  88.  
  89.  
  90.     def preprocess (self,
  91.                     source,
  92.                     output_file=None,
  93.                     macros=None,
  94.                     include_dirs=None,
  95.                     extra_preargs=None,
  96.                     extra_postargs=None):
  97.  
  98.         (_, macros, include_dirs) = \
  99.             self._fix_compile_args(None, macros, include_dirs)
  100.         pp_opts = gen_preprocess_options(macros, include_dirs)
  101.         pp_args = self.preprocessor + pp_opts
  102.         if output_file:
  103.             pp_args.extend(['-o', output_file])
  104.         if extra_preargs:
  105.             pp_args[:0] = extra_preargs
  106.         if extra_postargs:
  107.             pp_args.extend(extra_postargs)
  108.  
  109.         # We need to preprocess: either we're being forced to, or we're
  110.         # generating output to stdout, or there's a target output file and
  111.         # the source file is newer than the target (or the target doesn't
  112.         # exist).
  113.         if self.force or output_file is None or newer(source, output_file):
  114.             if output_file:
  115.                 self.mkpath(os.path.dirname(output_file))
  116.             try:
  117.                 self.spawn(pp_args)
  118.             except DistutilsExecError, msg:
  119.                 raise CompileError, msg
  120.  
  121.  
  122.     def compile (self,
  123.                  sources,
  124.                  output_dir=None,
  125.                  macros=None,
  126.                  include_dirs=None,
  127.                  debug=0,
  128.                  extra_preargs=None,
  129.                  extra_postargs=None):
  130.  
  131.         (output_dir, macros, include_dirs) = \
  132.             self._fix_compile_args(output_dir, macros, include_dirs)
  133.         (objects, skip_sources) = self._prep_compile(sources, output_dir)
  134.  
  135.         # Figure out the options for the compiler command line.
  136.         pp_opts = gen_preprocess_options(macros, include_dirs)
  137.         cc_args = pp_opts + ['-c']
  138.         if debug:
  139.             cc_args[:0] = ['-g']
  140.         if extra_preargs:
  141.             cc_args[:0] = extra_preargs
  142.         if extra_postargs is None:
  143.             extra_postargs = []
  144.  
  145.         # Compile all source files that weren't eliminated by
  146.         # '_prep_compile()'.
  147.         for i in range(len(sources)):
  148.             src = sources[i] ; obj = objects[i]
  149.             if skip_sources[src]:
  150.                 self.announce("skipping %s (%s up-to-date)" % (src, obj))
  151.             else:
  152.                 self.mkpath(os.path.dirname(obj))
  153.                 try:
  154.                     self.spawn(self.compiler_so + cc_args +
  155.                                [src, '-o', obj] +
  156.                                extra_postargs)
  157.                 except DistutilsExecError, msg:
  158.                     raise CompileError, msg
  159.  
  160.         # Return *all* object filenames, not just the ones we just built.
  161.         return objects
  162.  
  163.     # compile ()
  164.  
  165.  
  166.     def create_static_lib (self,
  167.                            objects,
  168.                            output_libname,
  169.                            output_dir=None,
  170.                            debug=0):
  171.  
  172.         (objects, output_dir) = self._fix_object_args(objects, output_dir)
  173.  
  174.         output_filename = \
  175.             self.library_filename(output_libname, output_dir=output_dir)
  176.  
  177.         if self._need_link(objects, output_filename):
  178.             self.mkpath(os.path.dirname(output_filename))
  179.             self.spawn(self.archiver +
  180.                        [output_filename] +
  181.                        objects + self.objects)
  182.  
  183.             # Not many Unices required ranlib anymore -- SunOS 4.x is, I
  184.             # think the only major Unix that does.  Maybe we need some
  185.             # platform intelligence here to skip ranlib if it's not
  186.             # needed -- or maybe Python's configure script took care of
  187.             # it for us, hence the check for leading colon.
  188.             if self.ranlib:
  189.                 try:
  190.                     self.spawn(self.ranlib + [output_filename])
  191.                 except DistutilsExecError, msg:
  192.                     raise LibError, msg
  193.         else:
  194.             self.announce("skipping %s (up-to-date)" % output_filename)
  195.  
  196.     # create_static_lib ()
  197.  
  198.  
  199.     def link (self,
  200.               target_desc,
  201.               objects,
  202.               output_filename,
  203.               output_dir=None,
  204.               libraries=None,
  205.               library_dirs=None,
  206.               runtime_library_dirs=None,
  207.               export_symbols=None,
  208.               debug=0,
  209.               extra_preargs=None,
  210.               extra_postargs=None,
  211.               build_temp=None):
  212.  
  213.         (objects, output_dir) = self._fix_object_args(objects, output_dir)
  214.         (libraries, library_dirs, runtime_library_dirs) = \
  215.             self._fix_lib_args(libraries, library_dirs, runtime_library_dirs)
  216.  
  217.         lib_opts = gen_lib_options(self,
  218.                                    library_dirs, runtime_library_dirs,
  219.                                    libraries)
  220.         if type(output_dir) not in (StringType, NoneType):
  221.             raise TypeError, "'output_dir' must be a string or None"
  222.         if output_dir is not None:
  223.             output_filename = os.path.join(output_dir, output_filename)
  224.  
  225.         if self._need_link(objects, output_filename):
  226.             ld_args = (objects + self.objects +
  227.                        lib_opts + ['-o', output_filename])
  228.             if debug:
  229.                 ld_args[:0] = ['-g']
  230.             if extra_preargs:
  231.                 ld_args[:0] = extra_preargs
  232.             if extra_postargs:
  233.                 ld_args.extend(extra_postargs)
  234.             self.mkpath(os.path.dirname(output_filename))
  235.             try:
  236.                 if target_desc == CCompiler.EXECUTABLE:
  237.                     self.spawn(self.linker_exe + ld_args)
  238.                 else:
  239.                     self.spawn(self.linker_so + ld_args)
  240.             except DistutilsExecError, msg:
  241.                 raise LinkError, msg
  242.         else:
  243.             self.announce("skipping %s (up-to-date)" % output_filename)
  244.  
  245.     # link ()
  246.  
  247.  
  248.     # -- Miscellaneous methods -----------------------------------------
  249.     # These are all used by the 'gen_lib_options() function, in
  250.     # ccompiler.py.
  251.  
  252.     def library_dir_option (self, dir):
  253.         return "-L" + dir
  254.  
  255.     def runtime_library_dir_option (self, dir):
  256.         # XXX Hackish, at the very least.  See Python bug #445902:
  257.         # http://sourceforge.net/tracker/index.php
  258.         #   ?func=detail&aid=445902&group_id=5470&atid=105470
  259.         # Linkers on different platforms need different options to
  260.         # specify that directories need to be added to the list of
  261.         # directories searched for dependencies when a dynamic library
  262.         # is sought.  GCC has to be told to pass the -R option through
  263.         # to the linker, whereas other compilers just know this.
  264.         # Other compilers may need something slightly different.  At
  265.         # this time, there's no way to determine this information from
  266.         # the configuration data stored in the Python installation, so
  267.         # we use this hack.
  268.         compiler = os.path.basename(sysconfig.get_config_var("CC"))
  269.         if compiler == "gcc" or compiler == "g++":
  270.             return "-Wl,-R" + dir
  271.         else:
  272.             return "-R" + dir
  273.  
  274.     def library_option (self, lib):
  275.         return "-l" + lib
  276.  
  277.  
  278.     def find_library_file (self, dirs, lib, debug=0):
  279.  
  280.         for dir in dirs:
  281.             shared = os.path.join(
  282.                 dir, self.library_filename(lib, lib_type='shared'))
  283.             dylib = os.path.join(
  284.                 dir, self.library_filename(lib, lib_type='dylib'))
  285.             static = os.path.join(
  286.                 dir, self.library_filename(lib, lib_type='static'))
  287.  
  288.             # We're second-guessing the linker here, with not much hard
  289.             # data to go on: GCC seems to prefer the shared library, so I'm
  290.             # assuming that *all* Unix C compilers do.  And of course I'm
  291.             # ignoring even GCC's "-static" option.  So sue me.
  292.             if os.path.exists(dylib):
  293.                 return dylib
  294.             elif os.path.exists(shared):
  295.                 return shared
  296.             elif os.path.exists(static):
  297.                 return static
  298.  
  299.         else:
  300.             # Oops, didn't find it in *any* of 'dirs'
  301.             return None
  302.  
  303.     # find_library_file ()
  304.  
  305. # class UnixCCompiler
  306.