mirror of
				https://github.com/python/cpython.git
				synced 2025-11-04 03:44:55 +00:00 
			
		
		
		
	distutils was removed in November. However, the c-analyzer relies on it. To solve that here, we vendor the parts the tool needs so it can be run against 3.12+. (Also see gh-92584.) Note that we may end up removing this code later in favor of a solution in common with the peg_generator tool (which also relies on distutils). At the least, the copy here makes sure the c-analyzer tool works on 3.12+ in the meantime.
		
			
				
	
	
		
			109 lines
		
	
	
	
		
			3.7 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			109 lines
		
	
	
	
		
			3.7 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
"""distutils.bcppcompiler
 | 
						|
 | 
						|
Contains BorlandCCompiler, an implementation of the abstract CCompiler class
 | 
						|
for the Borland C++ compiler.
 | 
						|
"""
 | 
						|
 | 
						|
# This implementation by Lyle Johnson, based on the original msvccompiler.py
 | 
						|
# module and using the directions originally published by Gordon Williams.
 | 
						|
 | 
						|
# XXX looks like there's a LOT of overlap between these two classes:
 | 
						|
# someone should sit down and factor out the common code as
 | 
						|
# WindowsCCompiler!  --GPW
 | 
						|
 | 
						|
 | 
						|
import os
 | 
						|
from distutils.errors import DistutilsExecError, CompileError
 | 
						|
from distutils.ccompiler import \
 | 
						|
     CCompiler, gen_preprocess_options
 | 
						|
from distutils.dep_util import newer
 | 
						|
 | 
						|
class BCPPCompiler(CCompiler) :
 | 
						|
    """Concrete class that implements an interface to the Borland C/C++
 | 
						|
    compiler, as defined by the CCompiler abstract class.
 | 
						|
    """
 | 
						|
 | 
						|
    compiler_type = 'bcpp'
 | 
						|
 | 
						|
    # Just set this so CCompiler's constructor doesn't barf.  We currently
 | 
						|
    # don't use the 'set_executables()' bureaucracy provided by CCompiler,
 | 
						|
    # as it really isn't necessary for this sort of single-compiler class.
 | 
						|
    # Would be nice to have a consistent interface with UnixCCompiler,
 | 
						|
    # though, so it's worth thinking about.
 | 
						|
    executables = {}
 | 
						|
 | 
						|
    # Private class data (need to distinguish C from C++ source for compiler)
 | 
						|
    _c_extensions = ['.c']
 | 
						|
    _cpp_extensions = ['.cc', '.cpp', '.cxx']
 | 
						|
 | 
						|
    # Needed for the filename generation methods provided by the
 | 
						|
    # base class, CCompiler.
 | 
						|
    src_extensions = _c_extensions + _cpp_extensions
 | 
						|
    obj_extension = '.obj'
 | 
						|
    static_lib_extension = '.lib'
 | 
						|
    shared_lib_extension = '.dll'
 | 
						|
    static_lib_format = shared_lib_format = '%s%s'
 | 
						|
    exe_extension = '.exe'
 | 
						|
 | 
						|
 | 
						|
    def __init__ (self,
 | 
						|
                  verbose=0,
 | 
						|
                  dry_run=0,
 | 
						|
                  force=0):
 | 
						|
 | 
						|
        CCompiler.__init__ (self, verbose, dry_run, force)
 | 
						|
 | 
						|
        # These executables are assumed to all be in the path.
 | 
						|
        # Borland doesn't seem to use any special registry settings to
 | 
						|
        # indicate their installation locations.
 | 
						|
 | 
						|
        self.cc = "bcc32.exe"
 | 
						|
        self.linker = "ilink32.exe"
 | 
						|
        self.lib = "tlib.exe"
 | 
						|
 | 
						|
        self.preprocess_options = None
 | 
						|
        self.compile_options = ['/tWM', '/O2', '/q', '/g0']
 | 
						|
        self.compile_options_debug = ['/tWM', '/Od', '/q', '/g0']
 | 
						|
 | 
						|
        self.ldflags_shared = ['/Tpd', '/Gn', '/q', '/x']
 | 
						|
        self.ldflags_shared_debug = ['/Tpd', '/Gn', '/q', '/x']
 | 
						|
        self.ldflags_static = []
 | 
						|
        self.ldflags_exe = ['/Gn', '/q', '/x']
 | 
						|
        self.ldflags_exe_debug = ['/Gn', '/q', '/x','/r']
 | 
						|
 | 
						|
 | 
						|
    # -- Worker methods ------------------------------------------------
 | 
						|
 | 
						|
    def preprocess (self,
 | 
						|
                    source,
 | 
						|
                    output_file=None,
 | 
						|
                    macros=None,
 | 
						|
                    include_dirs=None,
 | 
						|
                    extra_preargs=None,
 | 
						|
                    extra_postargs=None):
 | 
						|
 | 
						|
        (_, macros, include_dirs) = \
 | 
						|
            self._fix_compile_args(None, macros, include_dirs)
 | 
						|
        pp_opts = gen_preprocess_options(macros, include_dirs)
 | 
						|
        pp_args = ['cpp32.exe'] + pp_opts
 | 
						|
        if output_file is not None:
 | 
						|
            pp_args.append('-o' + output_file)
 | 
						|
        if extra_preargs:
 | 
						|
            pp_args[:0] = extra_preargs
 | 
						|
        if extra_postargs:
 | 
						|
            pp_args.extend(extra_postargs)
 | 
						|
        pp_args.append(source)
 | 
						|
 | 
						|
        # We need to preprocess: either we're being forced to, or the
 | 
						|
        # source file is newer than the target (or the target doesn't
 | 
						|
        # exist).
 | 
						|
        if self.force or output_file is None or newer(source, output_file):
 | 
						|
            if output_file:
 | 
						|
                self.mkpath(os.path.dirname(output_file))
 | 
						|
            try:
 | 
						|
                self.spawn(pp_args)
 | 
						|
            except DistutilsExecError as msg:
 | 
						|
                print(msg)
 | 
						|
                raise CompileError(msg)
 | 
						|
 | 
						|
    # preprocess()
 |