Home | History | Annotate | Download | only in command
      1 """distutils.command.build
      2 
      3 Implements the Distutils 'build' command."""
      4 
      5 import sys, os
      6 from distutils.core import Command
      7 from distutils.errors import DistutilsOptionError
      8 from distutils.util import get_platform
      9 
     10 
     11 def show_compilers():
     12     from distutils.ccompiler import show_compilers
     13     show_compilers()
     14 
     15 
     16 class build(Command):
     17 
     18     description = "build everything needed to install"
     19 
     20     user_options = [
     21         ('build-base=', 'b',
     22          "base directory for build library"),
     23         ('build-purelib=', None,
     24          "build directory for platform-neutral distributions"),
     25         ('build-platlib=', None,
     26          "build directory for platform-specific distributions"),
     27         ('build-lib=', None,
     28          "build directory for all distribution (defaults to either " +
     29          "build-purelib or build-platlib"),
     30         ('build-scripts=', None,
     31          "build directory for scripts"),
     32         ('build-temp=', 't',
     33          "temporary build directory"),
     34         ('plat-name=', 'p',
     35          "platform name to build for, if supported "
     36          "(default: %s)" % get_platform()),
     37         ('compiler=', 'c',
     38          "specify the compiler type"),
     39         ('parallel=', 'j',
     40          "number of parallel build jobs"),
     41         ('debug', 'g',
     42          "compile extensions and libraries with debugging information"),
     43         ('force', 'f',
     44          "forcibly build everything (ignore file timestamps)"),
     45         ('executable=', 'e',
     46          "specify final destination interpreter path (build.py)"),
     47         ]
     48 
     49     boolean_options = ['debug', 'force']
     50 
     51     help_options = [
     52         ('help-compiler', None,
     53          "list available compilers", show_compilers),
     54         ]
     55 
     56     def initialize_options(self):
     57         self.build_base = 'build'
     58         # these are decided only after 'build_base' has its final value
     59         # (unless overridden by the user or client)
     60         self.build_purelib = None
     61         self.build_platlib = None
     62         self.build_lib = None
     63         self.build_temp = None
     64         self.build_scripts = None
     65         self.compiler = None
     66         self.plat_name = None
     67         self.debug = None
     68         self.force = 0
     69         self.executable = None
     70         self.parallel = None
     71 
     72     def finalize_options(self):
     73         if self.plat_name is None:
     74             self.plat_name = get_platform()
     75         else:
     76             # plat-name only supported for windows (other platforms are
     77             # supported via ./configure flags, if at all).  Avoid misleading
     78             # other platforms.
     79             if os.name != 'nt':
     80                 raise DistutilsOptionError(
     81                             "--plat-name only supported on Windows (try "
     82                             "using './configure --help' on your platform)")
     83 
     84         plat_specifier = ".%s-%d.%d" % (self.plat_name, *sys.version_info[:2])
     85 
     86         # Make it so Python 2.x and Python 2.x with --with-pydebug don't
     87         # share the same build directories. Doing so confuses the build
     88         # process for C modules
     89         if hasattr(sys, 'gettotalrefcount'):
     90             plat_specifier += '-pydebug'
     91 
     92         # 'build_purelib' and 'build_platlib' just default to 'lib' and
     93         # 'lib.<plat>' under the base build directory.  We only use one of
     94         # them for a given distribution, though --
     95         if self.build_purelib is None:
     96             self.build_purelib = os.path.join(self.build_base, 'lib')
     97         if self.build_platlib is None:
     98             self.build_platlib = os.path.join(self.build_base,
     99                                               'lib' + plat_specifier)
    100 
    101         # 'build_lib' is the actual directory that we will use for this
    102         # particular module distribution -- if user didn't supply it, pick
    103         # one of 'build_purelib' or 'build_platlib'.
    104         if self.build_lib is None:
    105             if self.distribution.ext_modules:
    106                 self.build_lib = self.build_platlib
    107             else:
    108                 self.build_lib = self.build_purelib
    109 
    110         # 'build_temp' -- temporary directory for compiler turds,
    111         # "build/temp.<plat>"
    112         if self.build_temp is None:
    113             self.build_temp = os.path.join(self.build_base,
    114                                            'temp' + plat_specifier)
    115         if self.build_scripts is None:
    116             self.build_scripts = os.path.join(self.build_base,
    117                                               'scripts-%d.%d' % sys.version_info[:2])
    118 
    119         if self.executable is None:
    120             self.executable = os.path.normpath(sys.executable)
    121 
    122         if isinstance(self.parallel, str):
    123             try:
    124                 self.parallel = int(self.parallel)
    125             except ValueError:
    126                 raise DistutilsOptionError("parallel should be an integer")
    127 
    128     def run(self):
    129         # Run all relevant sub-commands.  This will be some subset of:
    130         #  - build_py      - pure Python modules
    131         #  - build_clib    - standalone C libraries
    132         #  - build_ext     - Python extensions
    133         #  - build_scripts - (Python) scripts
    134         for cmd_name in self.get_sub_commands():
    135             self.run_command(cmd_name)
    136 
    137 
    138     # -- Predicates for the sub-command list ---------------------------
    139 
    140     def has_pure_modules(self):
    141         return self.distribution.has_pure_modules()
    142 
    143     def has_c_libraries(self):
    144         return self.distribution.has_c_libraries()
    145 
    146     def has_ext_modules(self):
    147         return self.distribution.has_ext_modules()
    148 
    149     def has_scripts(self):
    150         return self.distribution.has_scripts()
    151 
    152 
    153     sub_commands = [('build_py',      has_pure_modules),
    154                     ('build_clib',    has_c_libraries),
    155                     ('build_ext',     has_ext_modules),
    156                     ('build_scripts', has_scripts),
    157                    ]
    158