1"""distutils.command.build 2 3Implements the Distutils 'build' command.""" 4 5import sys, os 6from distutils.core import Command 7from distutils.errors import DistutilsOptionError 8from distutils.util import get_platform 9 10 11def show_compilers(): 12 from distutils.ccompiler import show_compilers 13 show_compilers() 14 15 16class 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