]>
git.saurik.com Git - wxWidgets.git/blob - wxPython/distutils/extension.py
   3 Provides the Extension class, used to describe C/C++ extension 
   4 modules in setup scripts.""" 
  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). 
  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. 
  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). 
  33         the full name of the extension, including any packages -- ie. 
  34         *not* a filename or pathname, but Python dotted name 
  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 
  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 
  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 
  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" + 
  79         list of files that the extension depends on 
  81         extension language (i.e. "c", "c++", "objc"). Will be detected 
  82         from the source extensions if not provided. 
  85     # When adding arguments to this constructor, be sure to update 
  86     # setup_keywords in core.py. 
  87     def __init__ (self
, name
, sources
, 
  93                   runtime_library_dirs
=None, 
  95                   extra_compile_args
=None, 
 100                   **kw                      
# To catch unknown keywords 
 102         assert type(name
) is StringType
, "'name' must be a string" 
 103         assert (type(sources
) is ListType 
and 
 104                 map(type, sources
) == [StringType
]*len(sources
)), \
 
 105                 "'sources' must be a list of strings" 
 108         self
.sources 
= sources
 
 109         self
.include_dirs 
= include_dirs 
or [] 
 110         self
.define_macros 
= define_macros 
or [] 
 111         self
.undef_macros 
= undef_macros 
or [] 
 112         self
.library_dirs 
= library_dirs 
or [] 
 113         self
.libraries 
= libraries 
or [] 
 114         self
.runtime_library_dirs 
= runtime_library_dirs 
or [] 
 115         self
.extra_objects 
= extra_objects 
or [] 
 116         self
.extra_compile_args 
= extra_compile_args 
or [] 
 117         self
.extra_link_args 
= extra_link_args 
or [] 
 118         self
.export_symbols 
= export_symbols 
or [] 
 119         self
.depends 
= depends 
or [] 
 120         self
.language 
= language
 
 122         # If there are unknown keyword options, warn about them 
 124             L 
= kw
.keys() ; L
.sort() 
 126             msg 
= "Unknown Extension options: " + string
.join(L
, ', ') 
 127             if warnings 
is not None: 
 130                 sys
.stderr
.write(msg 
+ '\n') 
 134 def read_setup_file (filename
): 
 135     from distutils
.sysconfig 
import \
 
 136          parse_makefile
, expand_makefile_vars
, _variable_rx
 
 137     from distutils
.text_file 
import TextFile
 
 138     from distutils
.util 
import split_quoted
 
 140     # First pass over the file to gather "VAR = VALUE" assignments. 
 141     vars = parse_makefile(filename
) 
 143     # Second pass to gobble up the real content: lines of the form 
 144     #   <module> ... [<sourcefile> ...] [<cpparg> ...] [<library> ...] 
 145     file = TextFile(filename
, 
 146                     strip_comments
=1, skip_blanks
=1, join_lines
=1, 
 147                     lstrip_ws
=1, rstrip_ws
=1) 
 151         line 
= file.readline() 
 152         if line 
is None:                # eof 
 154         if _variable_rx
.match(line
):    # VAR=VALUE, handled in first pass 
 157         if line
[0] == line
[-1] == "*": 
 158             file.warn("'%s' lines not handled yet" % line
) 
 161         #print "original line: " + line 
 162         line 
= expand_makefile_vars(line
, vars) 
 163         words 
= split_quoted(line
) 
 164         #print "expanded line: " + line 
 166         # NB. this parses a slightly different syntax than the old 
 167         # makesetup script: here, there must be exactly one extension per 
 168         # line, and it must be the first word of the line.  I have no idea 
 169         # why the old syntax supported multiple extensions per line, as 
 170         # they all wind up being the same. 
 173         ext 
= Extension(module
, []) 
 174         append_next_word 
= None 
 176         for word 
in words
[1:]: 
 177             if append_next_word 
is not None: 
 178                 append_next_word
.append(word
) 
 179                 append_next_word 
= None 
 182             suffix 
= os
.path
.splitext(word
)[1] 
 183             switch 
= word
[0:2] ; value 
= word
[2:] 
 185             if suffix 
in (".c", ".cc", ".cpp", ".cxx", ".c++", ".m", ".mm"): 
 186                 # hmm, should we do something about C vs. C++ sources? 
 187                 # or leave it up to the CCompiler implementation to 
 189                 ext
.sources
.append(word
) 
 191                 ext
.include_dirs
.append(value
) 
 193                 equals 
= string
.find(value
, "=") 
 194                 if equals 
== -1:        # bare "-DFOO" -- no value 
 195                     ext
.define_macros
.append((value
, None)) 
 197                     ext
.define_macros
.append((value
[0:equals
], 
 200                 ext
.undef_macros
.append(value
) 
 201             elif switch 
== "-C":        # only here 'cause makesetup has it! 
 202                 ext
.extra_compile_args
.append(word
) 
 204                 ext
.libraries
.append(value
) 
 206                 ext
.library_dirs
.append(value
) 
 208                 ext
.runtime_library_dirs
.append(value
) 
 209             elif word 
== "-rpath": 
 210                 append_next_word 
= ext
.runtime_library_dirs
 
 211             elif word 
== "-Xlinker": 
 212                 append_next_word 
= ext
.extra_link_args
 
 213             elif word 
== "-Xcompiler": 
 214                 append_next_word 
= ext
.extra_compile_args
 
 216                 ext
.extra_link_args
.append(word
) 
 218                     append_next_word 
= ext
.extra_link_args
 
 219             elif suffix 
in (".a", ".so", ".sl", ".o", ".dylib"): 
 220                 # NB. a really faithful emulation of makesetup would 
 221                 # append a .o file to extra_objects only if it 
 222                 # had a slash in it; otherwise, it would s/.o/.c/ 
 223                 # and append it to sources.  Hmmmm. 
 224                 ext
.extra_objects
.append(word
) 
 226                 file.warn("unrecognized argument '%s'" % word
) 
 228         extensions
.append(ext
) 
 230         #print "module:", module 
 231         #print "source files:", source_files 
 232         #print "cpp args:", cpp_args 
 233         #print "lib args:", library_args 
 235         #extensions[module] = { 'sources': source_files, 
 236         #                       'cpp_args': cpp_args, 
 237         #                       'lib_args': library_args }