B
    V&t\as                 @   s  d dl mZmZmZ d dlZd dlZd dlZd dlZd dlZd dl	Z	d dl
Z
d dlmZ d dlmZ d dlT d dlmZmZmZmZ d dlmZ d dlmZ d d	lmZ d d
lmZ d dlmZmZ d dlm Z m!Z!m"Z"m#Z#m$Z$ yd dl%Z%W n e&k
r
   d dl'Z%Y nX da(e%) Z*e+ Z,dd Z-dd Z.dd Z/e.e0de/ dSddZ1e.e0de1 dTddZ2e.e0de2 dUddZ3e.e0de3 dVdd Z4e.e0d!e4 d"d# Z5d$d% Z6e.e0d&e6 dWd'd(Z7e.e0d)e7 dXd+d,Z8d-d gfd.d/Z9e.e0d0e9 d1d2 Z:e.e0d3e: d4e;d5< d6e;d7< d8e;d9< d:e;d;< d<e;d=< d>e;d?< e j<d@7  _<ej=dAkrvdBe;dC< e" rve>dD dEej< e_<e?Z@dYdFdGZ?e?e_?eAZBdHdI ZAeAe_Ax8dJD ]0ZCejDEdKeC dL ZFeFdk	reGeFdIeA qW d dlHZHeIdMeHjJ ZKeIdNZLeIdOZMeIdPZNdQdR ZOeOe_OdS )Z    )divisionabsolute_importprint_functionN)copy)	ccompiler)*)DistutilsExecErrorDistutilsModuleErrorDistutilsPlatformErrorCompileError)customize_compiler)LooseVersion)log)get_exception)filepath_from_subprocess_outputforward_bytes_to_stdout)	cyg2win32is_sequencemingw32get_num_build_jobs_commandline_dep_stringc          	   C   s   | d }t j|sdS t|d}| }W dQ R X t|||}|d }||krVdS d|dd }	dd tj|	dd	D }
y2t 	| j
}x |
D ]}t 	|j
|krdS qW W n tk
r   dS X d
S )z
    Check if an objects needs to be rebuild based on its dependencies

    Parameters
    ----------
    obj : str
        object file

    Returns
    -------
    bool
    z.dTrN c             S   s"   g | ]}|d kr| ds|qS )
:)endswith).0x r   8lib/python3.7/site-packages/numpy/distutils/ccompiler.py
<listcomp>E   s    z _needs_build.<locals>.<listcomp>)posixF)ospathexistsopen	readlinesr   joinshlexsplitstatst_mtimeOSError)objcc_argsextra_postargspp_optsZdep_fileflinesZcmdlineZlast_cmdlinecontentsZdepsZt_objr   r   r    _needs_build%   s&    
r5   c                s:   t jd dk rt d | }n fdd}t| || d S )Nr      c                s    | f||S )Nr   )selfargskw)funcr   r    <lambda>\   s    z replace_method.<locals>.<lambda>)sysversion_infotypes
MethodTypesetattr)klassZmethod_namer:   mr   )r:   r    replace_methodW   s    rC   c             C   s   dS )z
    Does nothing here, but is called by the get_version method and can be
    overridden by subclasses. In particular it is redefined in the `FCompiler`
    class where more documentation can be found.

    Nr   )r7   r   r   r    CCompiler_find_executablese   s    rD   find_executablesc          
   C   s   |dkr"|}t |r"dt|}t| yt| W nJ tjk
rj } z|j}|j	}W dd}~X Y n  t
k
r   d}d}Y nX dS t |rdt|}t| td|rd}nd}td|||f dS )	a  
    Execute a command in a sub-process.

    Parameters
    ----------
    cmd : str
        The command to execute.
    display : str or sequence of str, optional
        The text to add to the log file kept by `numpy.distutils`.
        If not given, `display` is equal to `cmd`.

    Returns
    -------
    None

    Raises
    ------
    DistutilsExecError
        If the command failed, i.e. the exit status was not 0.

    N        s   Too many open filesz2
Try rerunning setup command until build succeeds.r   z)Command "%s" failed with exit status %d%s)r   r(   listr   info
subprocesscheck_outputCalledProcessErroroutput
returncoder-   r   researchr   )r7   cmddisplayexcosmsgr   r   r    CCompiler_spawns   s,    

rX   Zspawnr   c             C   s   |dkrd}g }x|D ]}t jt j|\}}t j|d }|t j|d }|dr|dd }|d| }	t jt j	|	}	|	||d  }|| j
krtd||f |rt j|}t j||| j }
||
 qW |S )a  
    Return the name of the object files for the given source files.

    Parameters
    ----------
    source_filenames : list of str
        The list of paths to source files. Paths can be either relative or
        absolute, this is handled transparently.
    strip_dir : bool, optional
        Whether to strip the directory from the returned paths. If True,
        the file name prepended by `output_dir` is returned. Default is False.
    output_dir : str, optional
        If given, this path is prepended to the returned paths to the
        object files.

    Returns
    -------
    obj_names : list of str
        The list of paths to the object files corresponding to the source
        files in `source_filenames`.

    Nr      z..   z"unknown file type '%s' (from '%s'))r#   r$   splitextnormpath
splitdriveisabs
startswithrfindbasenameabspathZsrc_extensionsZUnknownFileErrorr(   Zobj_extensionappend)r7   Zsource_filenamesZ	strip_dir
output_dirZ	obj_namesZsrc_namebaseextidZobj_namer   r   r    CCompiler_object_filenames   s&    


ri   Zobject_filenamesc	          	      sp  t  }	t tdkrt|	aW dQ R X |s0g S tjd dk rTddlm}
m	}m
} nddlm}
m	}m
} t|
rg }x<dD ]4}td| }|dkrq||d|d	|f  q|W d
|}nj}dd	|f }t| |||||\}}}|| dd	  }r2|dd	 7 }t|  fdd}t|
r
t| }g g  }}xz|D ]r}||krv|| \}}jdkrt|}t|}||r||s||||ff n||||ff qvW |}x |D ]}|| qW n| }t|dkrT|	dkrTddl}|j|	}||| |  nx|D ]}|| qZW |S )a  
    Compile one or more source files.

    Please refer to the Python distutils API reference for more details.

    Parameters
    ----------
    sources : list of str
        A list of filenames
    output_dir : str, optional
        Path to the output directory.
    macros : list of tuples
        A list of macro definitions.
    include_dirs : list of str, optional
        The directories to add to the default include file search path for
        this compilation only.
    debug : bool, optional
        Whether or not to output debug symbols in or alongside the object
        file(s).
    extra_preargs, extra_postargs : ?
        Extra pre- and post-arguments.
    depends : list of str, optional
        A list of file names that all targets depend on.

    Returns
    -------
    objects : list of str
        A list of object file names, one per source file `sources`.

    Raises
    ------
    CompileError
        If compilation fails.

    Nr   r6   rY   )	FCompiler	is_f_filehas_f90_header)Zf77Zf90ZfixZ	compiler_zFortran %s compiler: %srF   r   zC compiler: %s
zcompile options: '%s'z
extra options: '%s'c                s   | \}\}}t | sd S x2t |tkr:t| P W d Q R X td q W z(t |||  W d Q R X W d t t| W d Q R X X d S )Ng?)	r5   _global_lock_processing_filesaddtimeZsleep_job_semaphore_compileremove)r8   r.   srcrf   )r/   r0   r1   r7   r   r    single_compile/  s    
"z)CCompiler_compile.<locals>.single_compileZabsoft) r   rm   rq   	threadingZ	Semaphorer<   r=   Z	fcompilerrj   rk   rl   Znumpy.distutils.fcompiler
isinstancegetattrrc   r(   compiler_sor   rJ   Z_setup_compileZ_get_cc_argsrI   keyscompiler_typer   itemslenZmultiprocessing.poolpoolZ
ThreadPoolmapclose)r7   Zsourcesrd   Zmacrosinclude_dirsdebugextra_preargsr0   ZdependsZjobsrj   rk   rl   rS   ZfcZfcompZccompZobjectsZbuildru   Zobjects_to_buildZf77_objectsZother_objectsr.   rt   rf   Zbuild_itemsrU   Zmultiprocessingr~   r   )r/   r0   r1   r7   r    CCompiler_compile   sh    +









r   compiler   c                s   t d| jj jjf   fdd}|dr<|  j |drdx jD ]\}}| || qLW |drx jD ]}| 	| qtW |dr| 
| j j  |dr| | j j  |d	r|  j |d
r|  j dS )a  
    Customize compiler using distutils command.

    Parameters
    ----------
    cmd : class instance
        An instance inheriting from `distutils.cmd.Command`.
    ignore : sequence of str, optional
        List of `CCompiler` commands (without ``'set_'``) that should not be
        altered. Strings that are checked for are:
        ``('include_dirs', 'define', 'undef', 'libraries', 'library_dirs',
        'rpath', 'link_objects')``.

    Returns
    -------
    None

    zcustomize %s using %sc                s   t  | d d k	o| kS )N)rx   )attr)rR   ignorer   r    allow  s    z&CCompiler_customize_cmd.<locals>.allowr   defineundef	librarieslibrary_dirsrpathlink_objectsN)r   rJ   	__class____name__Zset_include_dirsr   r   Zdefine_macror   Zundefine_macroZset_librariesr   Zset_library_dirsr   Zset_runtime_library_dirsr   Zset_link_objectsr   )r7   rR   r   r   namevalueZmacror   )rR   r   r    CCompiler_customize_cmdr  s&    r   Zcustomize_cmdc                s   g }d}t | j }xdD ]}||kr|| qW x@|D ]8}t| |r<t| |}t|t|}||t|f q<W dt|d  d   fdd|D }d	|S )	Nr   )
versionr   r   Zobject_switchZcompile_switchr   r   r   r   r   z%-rY   zs = %sc                s   g | ]} | qS r   r   )r   Zprop)fmtr   r    r!     s    z'_compiler_to_string.<locals>.<listcomp>r   )
rI   Zexecutablesrz   rc   hasattrrx   maxr}   reprr(   )compilerZpropsZmxrz   keyvr3   r   )r   r    _compiler_to_string  s    



r   c             C   sX   y|    W n tk
r    Y nX tjjdk rTtd t| j tt|  td dS )z
    Print the compiler customizations to stdout.

    Parameters
    ----------
    None

    Returns
    -------
    None

    Notes
    -----
    Printing is only done if the distutils log threshold is < 2.

    rZ   zP********************************************************************************N)get_version	Exceptionr   Z_global_logZ	thresholdprintr   r   )r7   r   r   r    CCompiler_show_customization  s    
r   Zshow_customizationc       
   	   C   s  t d| jj  t|  |ry| jd W n ttfk
rF   Y nX t	| drd| j
d kr| js| j
d drd\}}nd\}}| j
d ||g| j
d	d
  | _n8t	| drt d| j
f  t	| dst d| jj  t	| dr*d| j
d ks"d| j
d ks"d| j
d kr*d| _ntjdkrdd
l}dd
l}| }zvyTtj|d}t|d}	|	d W d
Q R X | j|g|dd|d gd d| _W n tk
r   d| _Y nX W d
|| X d
S )am  
    Do any platform-specific customization of a compiler instance.

    This method calls `distutils.sysconfig.customize_compiler` for
    platform-specific customization, as well as optionally remove a flag
    to suppress spurious warnings in case C++ code is being compiled.

    Parameters
    ----------
    dist : object
        This parameter is not used for anything.
    need_cxx : bool, optional
        Whether or not C++ has to be compiled. If so (True), the
        ``"-Wstrict-prototypes"`` option is removed to prevent spurious
        warnings. Default is False.

    Returns
    -------
    None

    Notes
    -----
    All the default options used by distutils can be extracted with::

      from distutils import sysconfig
      sysconfig.get_config_vars('CC', 'CXX', 'OPT', 'BASECFLAGS',
                                'CCSHARED', 'LDSHARED', 'SO')

    zcustomize %sz-Wstrict-prototypesr   ccr   gcc)r   zg++)r   zc++rY   Nz#### %s #######compiler_cxxzMissing compiler_cxx fix for zg++ZclangTr"   zfile.cwzint a;
z-MMDz-MFz.d)rd   r   F)r   rJ   r   r   r   ry   rs   AttributeError
ValueErrorr   r   r   r_   replacewarnZ_auto_dependsr#   r   tempfileshutilZmkdtempr$   r(   r&   writer   r   Zrmtree)
r7   ZdistZneed_cxxabr   r   Ztmpdirfnr2   r   r   r    CCompiler_customize  sJ    




r   Z	customize[-.\d]+c                s    fdd}|S )aU  
    Simple matching of version numbers, for use in CCompiler and FCompiler.

    Parameters
    ----------
    pat : str, optional
        A regular expression matching version numbers.
        Default is ``r'[-.\d]+'``.
    ignore : str, optional
        A regular expression matching patterns to skip.
        Default is ``''``, in which case nothing is skipped.
    start : str, optional
        A regular expression matching the start of where to start looking
        for version numbers.
        Default is ``''``, in which case searching is started at the
        beginning of the version string given to `matcher`.

    Returns
    -------
    matcher : callable
        A function that is appropriate to use as the ``.version_match``
        attribute of a `CCompiler` class. `matcher` takes a single parameter,
        a version string.

    c                s~   | dd}d}r0t|}|s(d S | }xBt||d  }|sNd S  rnt |drn| }q2P q2W |dS )Nr   rF   r   )r   rP   matchendrQ   group)r7   version_stringposrB   )r   patstartr   r    matcherA  s     z%simple_version_match.<locals>.matcherr   )r   r   r   r   r   )r   r   r   r    simple_version_match'  s    r   Fc       	         s,  |st | dr| jS |   y
| j}W n tk
r:   dS X |rH|d sLdS y
| j}W n@ tk
r   y
| j W n tk
r   dS X  fdd}Y nX yt|}W nJ tj	k
r } z|j
}|j}W dd}~X Y n( tk
r   d}d}Y nX t|}d}d}||kr"||}|r"t|}|| _|S )a  
    Return compiler version, or None if compiler is not available.

    Parameters
    ----------
    force : bool, optional
        If True, force a new determination of the version, even if the
        compiler already has a version attribute. Default is False.
    ok_status : list of int, optional
        The list of status values returned by the version look-up process
        for which a version string is returned. If the status value is not
        in `ok_status`, None is returned. Default is ``[0]``.

    Returns
    -------
    version : str or None
        Version string, in the format of `distutils.version.LooseVersion`.

    r   Nr   c                s"   t  | }|sd S |d}|S )Nr   )rP   r   r   )r   rB   r   )r   r   r    r   z  s
    
z&CCompiler_get_version.<locals>.matcherrH   rG   )r   r   rE   version_cmdr   Zversion_matchZversion_patternrK   rL   rM   rN   rO   r-   r   r   )	r7   forceZ	ok_statusr   r   rN   rT   Zstatusr   r   )r   r    CCompiler_get_versionV  sD    




r   r   c             C   s   | j dkr| S t| }|jd g|jdd  |_tjdrrd|jd krr|jd |jd g|jdd  |_n|jd g|jdd  |_|S )z
    Return the C++ compiler.

    Parameters
    ----------
    None

    Returns
    -------
    cxx : class instance
        The C++ compiler, as a `CCompiler` instance.

    )msvcintelwintelemwr   rY   NZaixZ	ld_so_aixrZ   )r{   r   r   ry   r<   platformr_   Z	linker_so)r7   Zcxxr   r   r    CCompiler_cxx_compiler  s    
r   Zcxx_compiler)intelccompilerZIntelCCompilerz(Intel C Compiler for 32-bit applicationsintel)r   ZIntelItaniumCCompilerz7Intel C Itanium Compiler for Itanium-based applicationsintele)r   ZIntelEM64TCCompilerz(Intel C Compiler for 64-bit applicationsintelem)r   ZIntelCCompilerWz3Intel C Compiler for 32-bit applications on Windowsr   )r   ZIntelEM64TCCompilerWz3Intel C Compiler for 64-bit applications on Windowsr   )ZpathccompilerZPathScaleCCompilerz2PathScale Compiler for SiCortex-based applicationspathcc))zlinux.*r   )zlinux.*r   )zlinux.*r   )zlinux.*r   )ntr   )r   r   Zwin32)Zmingw32ccompilerZMingw32CCompilerz>Mingw32 port of GNU C Compiler for Win32(for MSC built Python)r   z+Setting mingw32 as default compiler for nt.))r   r   c             C   sR  | d krt j} y"|d kr t| }t| \}}}W n8 tk
rh   d|  }|d k	r\|d|  }t|Y nX d| }yt| W nr tk
r   tt	 }t
dt| |dd  }yt| W n* tk
r   tt	 }td| Y nX Y nX ytj| }	t|	| }
W n& tk
r2   td||f Y nX |
d ||}t
d|
  |S )	Nz5don't know how to compile C/C++ code on platform '%s'z with '%s' compilerznumpy.distutils.z,%s in numpy.distutils; trying from distutils   z4can't compile C/C++ code: unable to load module '%s'zBcan't compile C/C++ code: unable to find class '%s' in module '%s'znew_compiler returns %s)r#   r   Zget_default_compilercompiler_classKeyErrorr
   
__import__ImportErrorstrr   r   rJ   r	   r<   modulesvarsr   )Zplatr   verboseZdry_runr   Zmodule_name
class_nameZlong_descriptionrW   modulerA   r   r   r    new_compiler  sD    



r   c             C   sF   t | |||}g }x.|D ]&}t|r4|t| q|| qW |S )N)_distutils_gen_lib_optionsr   extendrI   rc   )r   r   Zruntime_library_dirsr   r   Zlib_optsrg   r   r   r    gen_lib_options  s    
r   )Zmsvc9r   Z_msvcZbcppZcygwincZemxcZunixcz
distutils.r   z[^\\\'\"%s ]*z'(?:[^'\\]|\\.)*'z"(?:[^"\\]|\\.)*"z\sc             C   s  |   } g }d}x| rt| |}| }|t| krN|| d |  P | | tjkr|| d |  | |d   } d}n| | dkr| d | | |d d   } |d }n| | dkrt	| |}n*| | dkrt
| |}ntd| |  |d krtd| |  | \}}t| |d |d  rv| d | | |d |d   | |d   } | d }n| }|t| kr||  P qW |S )	Nr   \rY   '"z!this can't happen (bad char '%c')z"bad string (mismatched %s quotes?)rZ   )strip_wordchars_rer   r   r}   rc   string
whitespacelstrip
_squote_re
_dquote_reRuntimeErrorr   span_has_white_rerQ   )rV   Zwordsr   rB   r   Zbegr   r   r    split_quoted*  s@    


,
r   )N)r   r   )NNNr   NNN)r   )r   )r   r   r   )NNr   r   r   )PZ
__future__r   r   r   r#   rP   r<   r>   r)   rp   rK   r   Z	distutilsr   Zdistutils.ccompilerZdistutils.errorsr   r	   r
   r   Zdistutils.sysconfigr   Zdistutils.versionr   Znumpy.distutilsr   Znumpy.distutils.compatr   Znumpy.distutils.exec_commandr   r   Znumpy.distutils.misc_utilr   r   r   r   r   rv   r   Zdummy_threadingrq   ZLockrm   setrn   r5   rC   rD   Z	CCompilerrX   ri   r   r   r   r   r   r   r   r   r   Z_default_compilersr   rJ   r   Z_distutils_new_compilerr   r   Z_ccr   get_mr@   r   r   r   r   r   r   r   r   r   r   r   r    <module>   s   2

;
-  
 
)#
Q
/C

    
%




/