142 lines
		
	
	
		
			5.3 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			142 lines
		
	
	
		
			5.3 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
"""
 | 
						|
unixccompiler - can handle very long argument lists for ar.
 | 
						|
 | 
						|
"""
 | 
						|
import os
 | 
						|
import sys
 | 
						|
import subprocess
 | 
						|
import shlex
 | 
						|
 | 
						|
from distutils.errors import CompileError, DistutilsExecError, LibError
 | 
						|
from distutils.unixccompiler import UnixCCompiler
 | 
						|
from numpy.distutils.ccompiler import replace_method
 | 
						|
from numpy.distutils.misc_util import _commandline_dep_string
 | 
						|
from numpy.distutils import log
 | 
						|
 | 
						|
# Note that UnixCCompiler._compile appeared in Python 2.3
 | 
						|
def UnixCCompiler__compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts):
 | 
						|
    """Compile a single source files with a Unix-style compiler."""
 | 
						|
    # HP ad-hoc fix, see ticket 1383
 | 
						|
    ccomp = self.compiler_so
 | 
						|
    if ccomp[0] == 'aCC':
 | 
						|
        # remove flags that will trigger ANSI-C mode for aCC
 | 
						|
        if '-Ae' in ccomp:
 | 
						|
            ccomp.remove('-Ae')
 | 
						|
        if '-Aa' in ccomp:
 | 
						|
            ccomp.remove('-Aa')
 | 
						|
        # add flags for (almost) sane C++ handling
 | 
						|
        ccomp += ['-AA']
 | 
						|
        self.compiler_so = ccomp
 | 
						|
    # ensure OPT environment variable is read
 | 
						|
    if 'OPT' in os.environ:
 | 
						|
        # XXX who uses this?
 | 
						|
        from sysconfig import get_config_vars
 | 
						|
        opt = shlex.join(shlex.split(os.environ['OPT']))
 | 
						|
        gcv_opt = shlex.join(shlex.split(get_config_vars('OPT')[0]))
 | 
						|
        ccomp_s = shlex.join(self.compiler_so)
 | 
						|
        if opt not in ccomp_s:
 | 
						|
            ccomp_s = ccomp_s.replace(gcv_opt, opt)
 | 
						|
            self.compiler_so = shlex.split(ccomp_s)
 | 
						|
        llink_s = shlex.join(self.linker_so)
 | 
						|
        if opt not in llink_s:
 | 
						|
            self.linker_so = self.linker_so + shlex.split(opt)
 | 
						|
 | 
						|
    display = '%s: %s' % (os.path.basename(self.compiler_so[0]), src)
 | 
						|
 | 
						|
    # gcc style automatic dependencies, outputs a makefile (-MF) that lists
 | 
						|
    # all headers needed by a c file as a side effect of compilation (-MMD)
 | 
						|
    if getattr(self, '_auto_depends', False):
 | 
						|
        deps = ['-MMD', '-MF', obj + '.d']
 | 
						|
    else:
 | 
						|
        deps = []
 | 
						|
 | 
						|
    try:
 | 
						|
        self.spawn(self.compiler_so + cc_args + [src, '-o', obj] + deps +
 | 
						|
                   extra_postargs, display = display)
 | 
						|
    except DistutilsExecError as e:
 | 
						|
        msg = str(e)
 | 
						|
        raise CompileError(msg) from None
 | 
						|
 | 
						|
    # add commandline flags to dependency file
 | 
						|
    if deps:
 | 
						|
        # After running the compiler, the file created will be in EBCDIC
 | 
						|
        # but will not be tagged as such. This tags it so the file does not
 | 
						|
        # have multiple different encodings being written to it
 | 
						|
        if sys.platform == 'zos':
 | 
						|
            subprocess.check_output(['chtag', '-tc', 'IBM1047', obj + '.d'])
 | 
						|
        with open(obj + '.d', 'a') as f:
 | 
						|
            f.write(_commandline_dep_string(cc_args, extra_postargs, pp_opts))
 | 
						|
 | 
						|
replace_method(UnixCCompiler, '_compile', UnixCCompiler__compile)
 | 
						|
 | 
						|
 | 
						|
def UnixCCompiler_create_static_lib(self, objects, output_libname,
 | 
						|
                                    output_dir=None, debug=0, target_lang=None):
 | 
						|
    """
 | 
						|
    Build a static library in a separate sub-process.
 | 
						|
 | 
						|
    Parameters
 | 
						|
    ----------
 | 
						|
    objects : list or tuple of str
 | 
						|
        List of paths to object files used to build the static library.
 | 
						|
    output_libname : str
 | 
						|
        The library name as an absolute or relative (if `output_dir` is used)
 | 
						|
        path.
 | 
						|
    output_dir : str, optional
 | 
						|
        The path to the output directory. Default is None, in which case
 | 
						|
        the ``output_dir`` attribute of the UnixCCompiler instance.
 | 
						|
    debug : bool, optional
 | 
						|
        This parameter is not used.
 | 
						|
    target_lang : str, optional
 | 
						|
        This parameter is not used.
 | 
						|
 | 
						|
    Returns
 | 
						|
    -------
 | 
						|
    None
 | 
						|
 | 
						|
    """
 | 
						|
    objects, output_dir = self._fix_object_args(objects, output_dir)
 | 
						|
 | 
						|
    output_filename = \
 | 
						|
                    self.library_filename(output_libname, output_dir=output_dir)
 | 
						|
 | 
						|
    if self._need_link(objects, output_filename):
 | 
						|
        try:
 | 
						|
            # previous .a may be screwed up; best to remove it first
 | 
						|
            # and recreate.
 | 
						|
            # Also, ar on OS X doesn't handle updating universal archives
 | 
						|
            os.unlink(output_filename)
 | 
						|
        except OSError:
 | 
						|
            pass
 | 
						|
        self.mkpath(os.path.dirname(output_filename))
 | 
						|
        tmp_objects = objects + self.objects
 | 
						|
        while tmp_objects:
 | 
						|
            objects = tmp_objects[:50]
 | 
						|
            tmp_objects = tmp_objects[50:]
 | 
						|
            display = '%s: adding %d object files to %s' % (
 | 
						|
                           os.path.basename(self.archiver[0]),
 | 
						|
                           len(objects), output_filename)
 | 
						|
            self.spawn(self.archiver + [output_filename] + objects,
 | 
						|
                       display = display)
 | 
						|
 | 
						|
        # Not many Unices required ranlib anymore -- SunOS 4.x is, I
 | 
						|
        # think the only major Unix that does.  Maybe we need some
 | 
						|
        # platform intelligence here to skip ranlib if it's not
 | 
						|
        # needed -- or maybe Python's configure script took care of
 | 
						|
        # it for us, hence the check for leading colon.
 | 
						|
        if self.ranlib:
 | 
						|
            display = '%s:@ %s' % (os.path.basename(self.ranlib[0]),
 | 
						|
                                   output_filename)
 | 
						|
            try:
 | 
						|
                self.spawn(self.ranlib + [output_filename],
 | 
						|
                           display = display)
 | 
						|
            except DistutilsExecError as e:
 | 
						|
                msg = str(e)
 | 
						|
                raise LibError(msg) from None
 | 
						|
    else:
 | 
						|
        log.debug("skipping %s (up-to-date)", output_filename)
 | 
						|
    return
 | 
						|
 | 
						|
replace_method(UnixCCompiler, 'create_static_lib',
 | 
						|
               UnixCCompiler_create_static_lib)
 |