10c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi"""distutils.command.build
20c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
30c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiImplements the Distutils 'build' command."""
40c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
50c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi__revision__ = "$Id$"
60c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
70c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiimport sys, os
80c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
90c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yifrom distutils.util import get_platform
100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yifrom distutils.core import Command
110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yifrom distutils.errors import DistutilsOptionError
120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef show_compilers():
140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    from distutils.ccompiler import show_compilers
150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    show_compilers()
160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass build(Command):
180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    description = "build everything needed to install"
200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    user_options = [
220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        ('build-base=', 'b',
230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi         "base directory for build library"),
240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        ('build-purelib=', None,
250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi         "build directory for platform-neutral distributions"),
260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        ('build-platlib=', None,
270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi         "build directory for platform-specific distributions"),
280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        ('build-lib=', None,
290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi         "build directory for all distribution (defaults to either " +
300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi         "build-purelib or build-platlib"),
310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        ('build-scripts=', None,
320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi         "build directory for scripts"),
330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        ('build-temp=', 't',
340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi         "temporary build directory"),
350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        ('plat-name=', 'p',
360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi         "platform name to build for, if supported "
370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi         "(default: %s)" % get_platform()),
380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        ('compiler=', 'c',
390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi         "specify the compiler type"),
400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        ('debug', 'g',
410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi         "compile extensions and libraries with debugging information"),
420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        ('force', 'f',
430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi         "forcibly build everything (ignore file timestamps)"),
440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        ('executable=', 'e',
450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi         "specify final destination interpreter path (build.py)"),
460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        ]
470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    boolean_options = ['debug', 'force']
490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    help_options = [
510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        ('help-compiler', None,
520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi         "list available compilers", show_compilers),
530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        ]
540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def initialize_options(self):
560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.build_base = 'build'
570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # these are decided only after 'build_base' has its final value
580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # (unless overridden by the user or client)
590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.build_purelib = None
600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.build_platlib = None
610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.build_lib = None
620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.build_temp = None
630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.build_scripts = None
640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.compiler = None
650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.plat_name = None
660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.debug = None
670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.force = 0
680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.executable = None
690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def finalize_options(self):
710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if self.plat_name is None:
720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.plat_name = get_platform()
730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        else:
740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            # plat-name only supported for windows (other platforms are
750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            # supported via ./configure flags, if at all).  Avoid misleading
760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            # other platforms.
770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            if os.name != 'nt':
780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                raise DistutilsOptionError(
790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                            "--plat-name only supported on Windows (try "
800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                            "using './configure --help' on your platform)")
810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        plat_specifier = ".%s-%s" % (self.plat_name, sys.version[0:3])
830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # Make it so Python 2.x and Python 2.x with --with-pydebug don't
850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # share the same build directories. Doing so confuses the build
860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # process for C modules
870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if hasattr(sys, 'gettotalrefcount'):
880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            plat_specifier += '-pydebug'
890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # 'build_purelib' and 'build_platlib' just default to 'lib' and
910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # 'lib.<plat>' under the base build directory.  We only use one of
920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # them for a given distribution, though --
930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if self.build_purelib is None:
940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.build_purelib = os.path.join(self.build_base, 'lib')
950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if self.build_platlib is None:
960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.build_platlib = os.path.join(self.build_base,
970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                                              'lib' + plat_specifier)
980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # 'build_lib' is the actual directory that we will use for this
1000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # particular module distribution -- if user didn't supply it, pick
1010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # one of 'build_purelib' or 'build_platlib'.
1020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if self.build_lib is None:
1030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            if self.distribution.ext_modules:
1040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                self.build_lib = self.build_platlib
1050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            else:
1060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                self.build_lib = self.build_purelib
1070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # 'build_temp' -- temporary directory for compiler turds,
1090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # "build/temp.<plat>"
1100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if self.build_temp is None:
1110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.build_temp = os.path.join(self.build_base,
1120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                                           'temp' + plat_specifier)
1130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if self.build_scripts is None:
1140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.build_scripts = os.path.join(self.build_base,
1150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                                              'scripts-' + sys.version[0:3])
1160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if self.executable is None:
1180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.executable = os.path.normpath(sys.executable)
1190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def run(self):
1210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # Run all relevant sub-commands.  This will be some subset of:
1220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #  - build_py      - pure Python modules
1230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #  - build_clib    - standalone C libraries
1240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #  - build_ext     - Python extensions
1250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #  - build_scripts - (Python) scripts
1260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        for cmd_name in self.get_sub_commands():
1270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.run_command(cmd_name)
1280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    # -- Predicates for the sub-command list ---------------------------
1300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def has_pure_modules (self):
1320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return self.distribution.has_pure_modules()
1330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def has_c_libraries (self):
1350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return self.distribution.has_c_libraries()
1360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def has_ext_modules (self):
1380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return self.distribution.has_ext_modules()
1390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def has_scripts (self):
1410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return self.distribution.has_scripts()
1420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    sub_commands = [('build_py',      has_pure_modules),
1440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    ('build_clib',    has_c_libraries),
1450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    ('build_ext',     has_ext_modules),
1460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    ('build_scripts', has_scripts),
1470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                   ]
148