]>
git.saurik.com Git - wxWidgets.git/blob - wxPython/distutils/command/build_clib.py
   1 """distutils.command.build_clib 
   3 Implements the Distutils 'build_clib' command, to build a C/C++ library 
   4 that is included in the module distribution and needed by an extension 
   7 # This module should be kept compatible with Python 1.5.2. 
  12 # XXX this module has *lots* of code ripped-off quite transparently from 
  13 # build_ext.py -- not surprisingly really, as the work required to build 
  14 # a static library from a collection of C source files is not really all 
  15 # that different from what's required to build a shared object file from 
  16 # a collection of C source files.  Nevertheless, I haven't done the 
  17 # necessary refactoring to account for the overlap in code between the 
  18 # two modules, mainly because a number of subtle details changed in the 
  23 from distutils
.core 
import Command
 
  24 from distutils
.errors 
import * 
  25 from distutils
.sysconfig 
import customize_compiler
 
  26 from distutils 
import log
 
  28 def show_compilers (): 
  29     from distutils
.ccompiler 
import show_compilers
 
  33 class build_clib (Command
): 
  35     description 
= "build C/C++ libraries used by Python extensions" 
  39          "directory to build C/C++ libraries to"), 
  41          "directory to put temporary build by-products"), 
  43          "compile with debugging information"), 
  45          "forcibly build everything (ignore file timestamps)"), 
  47          "specify the compiler type"), 
  50     boolean_options 
= ['debug', 'force'] 
  53         ('help-compiler', None, 
  54          "list available compilers", show_compilers
), 
  57     def initialize_options (self
): 
  58         self
.build_clib 
= None 
  59         self
.build_temp 
= None 
  61         # List of libraries to build 
  64         # Compilation options for all libraries 
  65         self
.include_dirs 
= None 
  72     # initialize_options() 
  75     def finalize_options (self
): 
  77         # This might be confusing: both build-clib and build-temp default 
  78         # to build-temp as defined by the "build" command.  This is because 
  79         # I think that C libraries are really just temporary build 
  80         # by-products, at least from the point of view of building Python 
  81         # extensions -- but I want to keep my options open. 
  82         self
.set_undefined_options('build', 
  83                                    ('build_temp', 'build_clib'), 
  84                                    ('build_temp', 'build_temp'), 
  85                                    ('compiler', 'compiler'), 
  89         self
.libraries 
= self
.distribution
.libraries
 
  91             self
.check_library_list(self
.libraries
) 
  93         if self
.include_dirs 
is None: 
  94             self
.include_dirs 
= self
.distribution
.include_dirs 
or [] 
  95         if type(self
.include_dirs
) is StringType
: 
  96             self
.include_dirs 
= string
.split(self
.include_dirs
, 
  99         # XXX same as for build_ext -- what about 'self.define' and 
 107         if not self
.libraries
: 
 110         # Yech -- this is cut 'n pasted from build_ext.py! 
 111         from distutils
.ccompiler 
import new_compiler
 
 112         self
.compiler 
= new_compiler(compiler
=self
.compiler
, 
 113                                      dry_run
=self
.dry_run
, 
 115         customize_compiler(self
.compiler
) 
 117         if self
.include_dirs 
is not None: 
 118             self
.compiler
.set_include_dirs(self
.include_dirs
) 
 119         if self
.define 
is not None: 
 120             # 'define' option is a list of (name,value) tuples 
 121             for (name
,value
) in self
.define
: 
 122                 self
.compiler
.define_macro(name
, value
) 
 123         if self
.undef 
is not None: 
 124             for macro 
in self
.undef
: 
 125                 self
.compiler
.undefine_macro(macro
) 
 127         self
.build_libraries(self
.libraries
) 
 132     def check_library_list (self
, libraries
): 
 133         """Ensure that the list of libraries (presumably provided as a 
 134            command option 'libraries') is valid, i.e. it is a list of 
 135            2-tuples, where the tuples are (library_name, build_info_dict). 
 136            Raise DistutilsSetupError if the structure is invalid anywhere; 
 137            just returns otherwise.""" 
 139         # Yechh, blecch, ackk: this is ripped straight out of build_ext.py, 
 140         # with only names changed to protect the innocent! 
 142         if type(libraries
) is not ListType
: 
 143             raise DistutilsSetupError
, \
 
 144                   "'libraries' option must be a list of tuples" 
 146         for lib 
in libraries
: 
 147             if type(lib
) is not TupleType 
and len(lib
) != 2: 
 148                 raise DistutilsSetupError
, \
 
 149                       "each element of 'libraries' must a 2-tuple" 
 151             if type(lib
[0]) is not StringType
: 
 152                 raise DistutilsSetupError
, \
 
 153                       "first element of each tuple in 'libraries' " + \
 
 154                       "must be a string (the library name)" 
 155             if '/' in lib
[0] or (os
.sep 
!= '/' and os
.sep 
in lib
[0]): 
 156                 raise DistutilsSetupError
, \
 
 157                       ("bad library name '%s': " + 
 158                        "may not contain directory separators") % \
 
 161             if type(lib
[1]) is not DictionaryType
: 
 162                 raise DistutilsSetupError
, \
 
 163                       "second element of each tuple in 'libraries' " + \
 
 164                       "must be a dictionary (build info)" 
 167     # check_library_list () 
 170     def get_library_names (self
): 
 171         # Assume the library list is valid -- 'check_library_list()' is 
 172         # called from 'finalize_options()', so it should be! 
 174         if not self
.libraries
: 
 178         for (lib_name
, build_info
) in self
.libraries
: 
 179             lib_names
.append(lib_name
) 
 182     # get_library_names () 
 185     def get_source_files (self
): 
 186         self
.check_library_list(self
.libraries
) 
 188         for (lib_name
, build_info
) in self
.libraries
: 
 189             sources 
= build_info
.get('sources') 
 190             if (sources 
is None or 
 191                 type(sources
) not in (ListType
, TupleType
) ): 
 192                 raise DistutilsSetupError
, \
 
 193                       ("in 'libraries' option (library '%s'), " 
 194                        "'sources' must be present and must be " 
 195                        "a list of source filenames") % lib_name
 
 197             filenames
.extend(sources
) 
 200     # get_source_files () 
 203     def build_libraries (self
, libraries
): 
 205         for (lib_name
, build_info
) in libraries
: 
 206             sources 
= build_info
.get('sources') 
 207             if sources 
is None or type(sources
) not in (ListType
, TupleType
): 
 208                 raise DistutilsSetupError
, \
 
 209                       ("in 'libraries' option (library '%s'), " + 
 210                        "'sources' must be present and must be " + 
 211                        "a list of source filenames") % lib_name
 
 212             sources 
= list(sources
) 
 214             log
.info("building '%s' library", lib_name
) 
 216             # First, compile the source code to object files in the library 
 217             # directory.  (This should probably change to putting object 
 218             # files in a temporary build directory.) 
 219             macros 
= build_info
.get('macros') 
 220             include_dirs 
= build_info
.get('include_dirs') 
 221             objects 
= self
.compiler
.compile(sources
, 
 222                                             output_dir
=self
.build_temp
, 
 224                                             include_dirs
=include_dirs
, 
 227             # Now "link" the object files together into a static library. 
 228             # (On Unix at least, this isn't really linking -- it just 
 229             # builds an archive.  Whatever.) 
 230             self
.compiler
.create_static_lib(objects
, lib_name
, 
 231                                             output_dir
=self
.build_clib
,