symbian-qemu-0.9.1-12/python-2.6.1/Lib/distutils/extension.py
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     1 """distutils.extension
       
     2 
       
     3 Provides the Extension class, used to describe C/C++ extension
       
     4 modules in setup scripts."""
       
     5 
       
     6 __revision__ = "$Id: extension.py 37623 2004-10-14 10:02:08Z anthonybaxter $"
       
     7 
       
     8 import os, string, sys
       
     9 from types import *
       
    10 
       
    11 try:
       
    12     import warnings
       
    13 except ImportError:
       
    14     warnings = None
       
    15 
       
    16 # This class is really only used by the "build_ext" command, so it might
       
    17 # make sense to put it in distutils.command.build_ext.  However, that
       
    18 # module is already big enough, and I want to make this class a bit more
       
    19 # complex to simplify some common cases ("foo" module in "foo.c") and do
       
    20 # better error-checking ("foo.c" actually exists).
       
    21 #
       
    22 # Also, putting this in build_ext.py means every setup script would have to
       
    23 # import that large-ish module (indirectly, through distutils.core) in
       
    24 # order to do anything.
       
    25 
       
    26 class Extension:
       
    27     """Just a collection of attributes that describes an extension
       
    28     module and everything needed to build it (hopefully in a portable
       
    29     way, but there are hooks that let you be as unportable as you need).
       
    30 
       
    31     Instance attributes:
       
    32       name : string
       
    33         the full name of the extension, including any packages -- ie.
       
    34         *not* a filename or pathname, but Python dotted name
       
    35       sources : [string]
       
    36         list of source filenames, relative to the distribution root
       
    37         (where the setup script lives), in Unix form (slash-separated)
       
    38         for portability.  Source files may be C, C++, SWIG (.i),
       
    39         platform-specific resource files, or whatever else is recognized
       
    40         by the "build_ext" command as source for a Python extension.
       
    41       include_dirs : [string]
       
    42         list of directories to search for C/C++ header files (in Unix
       
    43         form for portability)
       
    44       define_macros : [(name : string, value : string|None)]
       
    45         list of macros to define; each macro is defined using a 2-tuple,
       
    46         where 'value' is either the string to define it to or None to
       
    47         define it without a particular value (equivalent of "#define
       
    48         FOO" in source or -DFOO on Unix C compiler command line)
       
    49       undef_macros : [string]
       
    50         list of macros to undefine explicitly
       
    51       library_dirs : [string]
       
    52         list of directories to search for C/C++ libraries at link time
       
    53       libraries : [string]
       
    54         list of library names (not filenames or paths) to link against
       
    55       runtime_library_dirs : [string]
       
    56         list of directories to search for C/C++ libraries at run time
       
    57         (for shared extensions, this is when the extension is loaded)
       
    58       extra_objects : [string]
       
    59         list of extra files to link with (eg. object files not implied
       
    60         by 'sources', static library that must be explicitly specified,
       
    61         binary resource files, etc.)
       
    62       extra_compile_args : [string]
       
    63         any extra platform- and compiler-specific information to use
       
    64         when compiling the source files in 'sources'.  For platforms and
       
    65         compilers where "command line" makes sense, this is typically a
       
    66         list of command-line arguments, but for other platforms it could
       
    67         be anything.
       
    68       extra_link_args : [string]
       
    69         any extra platform- and compiler-specific information to use
       
    70         when linking object files together to create the extension (or
       
    71         to create a new static Python interpreter).  Similar
       
    72         interpretation as for 'extra_compile_args'.
       
    73       export_symbols : [string]
       
    74         list of symbols to be exported from a shared extension.  Not
       
    75         used on all platforms, and not generally necessary for Python
       
    76         extensions, which typically export exactly one symbol: "init" +
       
    77         extension_name.
       
    78       swig_opts : [string]
       
    79         any extra options to pass to SWIG if a source file has the .i
       
    80         extension.
       
    81       depends : [string]
       
    82         list of files that the extension depends on
       
    83       language : string
       
    84         extension language (i.e. "c", "c++", "objc"). Will be detected
       
    85         from the source extensions if not provided.
       
    86     """
       
    87 
       
    88     # When adding arguments to this constructor, be sure to update
       
    89     # setup_keywords in core.py.
       
    90     def __init__ (self, name, sources,
       
    91                   include_dirs=None,
       
    92                   define_macros=None,
       
    93                   undef_macros=None,
       
    94                   library_dirs=None,
       
    95                   libraries=None,
       
    96                   runtime_library_dirs=None,
       
    97                   extra_objects=None,
       
    98                   extra_compile_args=None,
       
    99                   extra_link_args=None,
       
   100                   export_symbols=None,
       
   101                   swig_opts = None,
       
   102                   depends=None,
       
   103                   language=None,
       
   104                   **kw                      # To catch unknown keywords
       
   105                  ):
       
   106         assert type(name) is StringType, "'name' must be a string"
       
   107         assert (type(sources) is ListType and
       
   108                 map(type, sources) == [StringType]*len(sources)), \
       
   109                 "'sources' must be a list of strings"
       
   110 
       
   111         self.name = name
       
   112         self.sources = sources
       
   113         self.include_dirs = include_dirs or []
       
   114         self.define_macros = define_macros or []
       
   115         self.undef_macros = undef_macros or []
       
   116         self.library_dirs = library_dirs or []
       
   117         self.libraries = libraries or []
       
   118         self.runtime_library_dirs = runtime_library_dirs or []
       
   119         self.extra_objects = extra_objects or []
       
   120         self.extra_compile_args = extra_compile_args or []
       
   121         self.extra_link_args = extra_link_args or []
       
   122         self.export_symbols = export_symbols or []
       
   123         self.swig_opts = swig_opts or []
       
   124         self.depends = depends or []
       
   125         self.language = language
       
   126 
       
   127         # If there are unknown keyword options, warn about them
       
   128         if len(kw):
       
   129             L = kw.keys() ; L.sort()
       
   130             L = map(repr, L)
       
   131             msg = "Unknown Extension options: " + string.join(L, ', ')
       
   132             if warnings is not None:
       
   133                 warnings.warn(msg)
       
   134             else:
       
   135                 sys.stderr.write(msg + '\n')
       
   136 # class Extension
       
   137 
       
   138 
       
   139 def read_setup_file (filename):
       
   140     from distutils.sysconfig import \
       
   141          parse_makefile, expand_makefile_vars, _variable_rx
       
   142     from distutils.text_file import TextFile
       
   143     from distutils.util import split_quoted
       
   144 
       
   145     # First pass over the file to gather "VAR = VALUE" assignments.
       
   146     vars = parse_makefile(filename)
       
   147 
       
   148     # Second pass to gobble up the real content: lines of the form
       
   149     #   <module> ... [<sourcefile> ...] [<cpparg> ...] [<library> ...]
       
   150     file = TextFile(filename,
       
   151                     strip_comments=1, skip_blanks=1, join_lines=1,
       
   152                     lstrip_ws=1, rstrip_ws=1)
       
   153     extensions = []
       
   154 
       
   155     while 1:
       
   156         line = file.readline()
       
   157         if line is None:                # eof
       
   158             break
       
   159         if _variable_rx.match(line):    # VAR=VALUE, handled in first pass
       
   160             continue
       
   161 
       
   162         if line[0] == line[-1] == "*":
       
   163             file.warn("'%s' lines not handled yet" % line)
       
   164             continue
       
   165 
       
   166         #print "original line: " + line
       
   167         line = expand_makefile_vars(line, vars)
       
   168         words = split_quoted(line)
       
   169         #print "expanded line: " + line
       
   170 
       
   171         # NB. this parses a slightly different syntax than the old
       
   172         # makesetup script: here, there must be exactly one extension per
       
   173         # line, and it must be the first word of the line.  I have no idea
       
   174         # why the old syntax supported multiple extensions per line, as
       
   175         # they all wind up being the same.
       
   176 
       
   177         module = words[0]
       
   178         ext = Extension(module, [])
       
   179         append_next_word = None
       
   180 
       
   181         for word in words[1:]:
       
   182             if append_next_word is not None:
       
   183                 append_next_word.append(word)
       
   184                 append_next_word = None
       
   185                 continue
       
   186 
       
   187             suffix = os.path.splitext(word)[1]
       
   188             switch = word[0:2] ; value = word[2:]
       
   189 
       
   190             if suffix in (".c", ".cc", ".cpp", ".cxx", ".c++", ".m", ".mm"):
       
   191                 # hmm, should we do something about C vs. C++ sources?
       
   192                 # or leave it up to the CCompiler implementation to
       
   193                 # worry about?
       
   194                 ext.sources.append(word)
       
   195             elif switch == "-I":
       
   196                 ext.include_dirs.append(value)
       
   197             elif switch == "-D":
       
   198                 equals = string.find(value, "=")
       
   199                 if equals == -1:        # bare "-DFOO" -- no value
       
   200                     ext.define_macros.append((value, None))
       
   201                 else:                   # "-DFOO=blah"
       
   202                     ext.define_macros.append((value[0:equals],
       
   203                                               value[equals+2:]))
       
   204             elif switch == "-U":
       
   205                 ext.undef_macros.append(value)
       
   206             elif switch == "-C":        # only here 'cause makesetup has it!
       
   207                 ext.extra_compile_args.append(word)
       
   208             elif switch == "-l":
       
   209                 ext.libraries.append(value)
       
   210             elif switch == "-L":
       
   211                 ext.library_dirs.append(value)
       
   212             elif switch == "-R":
       
   213                 ext.runtime_library_dirs.append(value)
       
   214             elif word == "-rpath":
       
   215                 append_next_word = ext.runtime_library_dirs
       
   216             elif word == "-Xlinker":
       
   217                 append_next_word = ext.extra_link_args
       
   218             elif word == "-Xcompiler":
       
   219                 append_next_word = ext.extra_compile_args
       
   220             elif switch == "-u":
       
   221                 ext.extra_link_args.append(word)
       
   222                 if not value:
       
   223                     append_next_word = ext.extra_link_args
       
   224             elif suffix in (".a", ".so", ".sl", ".o", ".dylib"):
       
   225                 # NB. a really faithful emulation of makesetup would
       
   226                 # append a .o file to extra_objects only if it
       
   227                 # had a slash in it; otherwise, it would s/.o/.c/
       
   228                 # and append it to sources.  Hmmmm.
       
   229                 ext.extra_objects.append(word)
       
   230             else:
       
   231                 file.warn("unrecognized argument '%s'" % word)
       
   232 
       
   233         extensions.append(ext)
       
   234 
       
   235         #print "module:", module
       
   236         #print "source files:", source_files
       
   237         #print "cpp args:", cpp_args
       
   238         #print "lib args:", library_args
       
   239 
       
   240         #extensions[module] = { 'sources': source_files,
       
   241         #                       'cpp_args': cpp_args,
       
   242         #                       'lib_args': library_args }
       
   243 
       
   244     return extensions
       
   245 
       
   246 # read_setup_file ()