"""distutils.command.build
Implements the Distutils 'build' command."""
from __future__ import annotations
import os
import sys
import sysconfig
from collections.abc import Callable
from typing import ClassVar
from ..ccompiler import show_compilers
from ..core import Command
from ..errors import DistutilsOptionError
from ..util import get_platform
class build(Command):
description = "build everything needed to install"
user_options = [
('build-base=', 'b', "base directory for build library"),
('build-purelib=', None, "build directory for platform-neutral distributions"),
('build-platlib=', None, "build directory for platform-specific distributions"),
(
'build-lib=',
None,
"build directory for all distribution (defaults to either build-purelib or build-platlib",
),
('build-scripts=', None, "build directory for scripts"),
('build-temp=', 't', "temporary build directory"),
(
'plat-name=',
'p',
f"platform name to build for, if supported [default: {get_platform()}]",
),
('compiler=', 'c', "specify the compiler type"),
('parallel=', 'j', "number of parallel build jobs"),
('debug', 'g', "compile extensions and libraries with debugging information"),
('force', 'f', "forcibly build everything (ignore file timestamps)"),
('executable=', 'e', "specify final destination interpreter path (build.py)"),
]
boolean_options: ClassVar[list[str]] = ['debug', 'force']
help_options: ClassVar[list[tuple[str, str | None, str, Callable[[], object]]]] = [
('help-compiler', None, "list available compilers", show_compilers),
]
def initialize_options(self):
self.build_base = 'build'
# these are decided only after 'build_base' has its final value
# (unless overridden by the user or client)
self.build_purelib = None
self.build_platlib = None
self.build_lib = None
self.build_temp = None
self.build_scripts = None
self.compiler = None
self.plat_name = None
self.debug = None
self.force = False
self.executable = None
self.parallel = None
def finalize_options(self) -> None: # noqa: C901
if self.plat_name is None:
self.plat_name = get_platform()
else:
# plat-name only supported for windows (other platforms are
# supported via ./configure flags, if at all). Avoid misleading
# other platforms.
if os.name != 'nt':
raise DistutilsOptionError(
"--plat-name only supported on Windows (try "
"using './configure --help' on your platform)"
)
plat_specifier = f".{self.plat_name}-{sys.implementation.cache_tag}"
# Python 3.13+ with --disable-gil shouldn't share build directories
if sysconfig.get_config_var('Py_GIL_DISABLED'):
plat_specifier += 't'
# Make it so Python 2.x and Python 2.x with --with-pydebug don't
# share the same build directories. Doing so confuses the build
# process for C modules
if hasattr(sys, 'gettotalrefcount'):
plat_specifier += '-pydebug'
# 'build_purelib' and 'build_platlib' just default to 'lib' and
# 'lib.