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 ESC[4;38;5;81mbuild(ESC[4;38;5;149mCommand):
      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 and sys.executable:
     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                     ]