U
    ºÛui|  ã                   @   sÊ   d 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	m
Z
 ddlmZ ddlmZmZmZmZmZmZ dd	lmZ dd
lmZmZmZ ddlmZmZ e d¡Zdd„ ZG dd„ deƒZ dS )z¶distutils.command.build_ext

Implements the Distutils 'build_ext' command, for building extension
modules (currently limited to C extensions, should accommodate C++
extensions ASAP).é    N)Úlog)Ú	USER_BASEé   )Únewer_group)ÚCommand)ÚCCompilerErrorÚCompileErrorÚDistutilsErrorÚDistutilsOptionErrorÚDistutilsPlatformErrorÚDistutilsSetupError)Ú	Extension)Úcustomize_compilerÚget_config_h_filenameÚget_python_version)Úget_platformÚis_mingwz3^[a-zA-Z_][a-zA-Z_0-9]*(\.[a-zA-Z_][a-zA-Z_0-9]*)*$c                  C   s   ddl m}  | ƒ  d S )Nr   ©Úshow_compilers)Ú	ccompilerr   r   © r   úK/tmp/pip-unpacked-wheel-9osl9suo/setuptools/_distutils/command/build_ext.pyr   !   s    r   c                   @   s*  e Zd ZdZdej› dZdddddeƒ › d	fd
ddde fdddddde fddddddddddgZddd d!d"gZ	d#d$d%e
fgZd&d'„ Zed(d)„ ƒZd*d+„ Zd,d-„ Zd.d/„ Zd0d1„ Zd2d3„ Zd4d5„ Zd6d7„ Zd8d9„ Zejd:d;„ ƒZd<d=„ Zd>d?„ Zd@dA„ ZdBdC„ ZdDdE„ ZdFdG„ ZdHdI„ Z dJdK„ Z!d$S )LÚ	build_extz8build C/C++ extensions (compile/link to build directory)z (separated by 'z'))z
build-lib=Úbz(directory for compiled extension modules)zbuild-temp=Útz1directory for temporary files (build by-products)z
plat-name=Úpz;platform name to cross-compile for, if supported [default: ú])ÚinplaceÚiziignore build-lib and put compiled extensions into the source directory alongside your pure Python moduleszinclude-dirs=ÚIz.list of directories to search for header files)zdefine=ÚDzC preprocessor macros to define)zundef=ÚUz!C preprocessor macros to undefine)z
libraries=Úlz!external C libraries to link withzlibrary-dirs=ÚLz.directories to search for external C libraries)zrpath=ÚRz7directories to search for shared C libraries at runtime)zlink-objects=ÚOz2extra explicit link objects to include in the link)ÚdebugÚgz'compile/link with debugging information)ÚforceÚfz2forcibly build everything (ignore file timestamps))z	compiler=Úczspecify the compiler type)z	parallel=Újznumber of parallel build jobs)úswig-cppNz)make SWIG create C++ files (default is C))z
swig-opts=Nz!list of SWIG command line options)zswig=Nzpath to the SWIG executable)ÚuserNz#add user include, library and rpathr   r&   r(   r,   r-   zhelp-compilerNzlist available compilersc                 C   s‚   d | _ d | _d | _d | _d| _d | _d | _d | _d | _d | _	d | _
d | _d | _d | _d | _d | _d | _d | _d | _d | _d | _d S )NF)Ú
extensionsÚ	build_libÚ	plat_nameÚ
build_tempr   ÚpackageÚinclude_dirsÚdefineÚundefÚ	librariesÚlibrary_dirsÚrpathÚlink_objectsr&   r(   ÚcompilerÚswigÚswig_cppÚ	swig_optsr-   Úparallel©Úselfr   r   r   Úinitialize_optionsk   s*    zbuild_ext.initialize_optionsc                 c   s^   |   d¡sdS | jrdV  dS tjdkrN|   d¡}|   d¡}tj ||¡V  n|   d¡V  dS )zµ
        Resolve Python's library directory for building extensions
        that rely on a shared Python library.

        See python/cpython#44264 and python/cpython#48686
        ÚPy_ENABLE_SHAREDNÚ.ZzosÚbaseZ
platlibdirÚLIBDIR)Úget_config_varÚpython_buildÚsysÚplatformÚosÚpathÚjoin)Ú	sysconfigZinstalled_dirÚlib_dirr   r   r   Ú_python_lib_dirƒ   s    



zbuild_ext._python_lib_dirc           	   
   C   sÀ  ddl m} |  ddddddd	d
¡ | jd kr8| jj| _| jj| _| ¡ }|jdd}| j	d krn| jj	pjg | _	t
| j	tƒrŠ| j	 tj¡| _	tjtjkr®| j	 tj tjd¡¡ | j	 | tjj¡¡ ||krâ| j	 | tjj¡¡ |  d¡ |  d¡ | jd krg | _| jd krg | _nt
| jtƒr:| j tj¡| _| jd krNg | _nt
| jtƒrl| j tj¡| _tjdkr`tƒ s`| j tj tjd¡¡ tjtjkr¾| j tj tjd¡¡ | jrÚtj | jd¡| _ntj | jd¡| _| j	 tj t ƒ ¡¡ | j tj¡ | j!dkr"d}n| j!dd … }tj tjd¡}|rTtj ||¡}| j |¡ tj"d d… dkr¬|j#s | j tj tjddt$ƒ  d¡¡ n| j d¡ | j |  %|¡¡ | j&râ| j& d¡}dd„ |D ƒ| _&| j'rø| j' d¡| _'| j(d krg | _(n| j( d ¡| _(| j)r~tj t*d¡}tj t*d¡}tj +|¡rX| j	 |¡ tj +|¡r~| j |¡ | j |¡ t
| j,tƒr¼zt-| j,ƒ| _,W n t.k
rº   t/d!ƒ‚Y nX d S )"Nr   )rM   Úbuild)r/   r/   )r1   r1   )r:   r:   )r&   r&   )r(   r(   )r>   r>   )r0   r0   T)Úplat_specificÚincluder6   r9   ÚntZlibsZDebugZReleaseÚwin32é   ZPCbuildé   ÚcygwinÚlibÚpythonÚconfigrC   ú,c                 S   s   g | ]}|d f‘qS )Ú1r   )Ú.0Úsymbolr   r   r   Ú
<listcomp>
  s     z.build_ext.finalize_options.<locals>.<listcomp>ú zparallel should be an integer)0Ú	distutilsrM   Úset_undefined_optionsr2   ÚdistributionÚext_packageÚext_modulesr.   Úget_python_incr3   Ú
isinstanceÚstrÚsplitrJ   ÚpathseprH   Úexec_prefixÚbase_exec_prefixÚappendrK   rL   ÚextendÚensure_string_listr6   r7   r8   Únamer   Úprefixr&   r1   Údirnamer   r0   rI   rG   r   rO   r4   r5   r=   r-   r   Úisdirr>   ÚintÚ
ValueErrorr
   )	r@   rM   Z
py_includeZplat_py_includeÚsuffixZnew_libZdefinesZuser_includeZuser_libr   r   r   Úfinalize_optionsœ   s¬    ø





   ÿÿzbuild_ext.finalize_optionsc                 C   sj  ddl m} | jsd S | j ¡ rL|  d¡}| j | ¡ p:g ¡ | j	 
|j¡ || j| j| j| jd| _t| jƒ tjdkr”| jtƒ kr”| j | j¡ | jd k	r¬| j | j¡ | jd k	rÔ| jD ]\}}| j ||¡ q¼| jd k	rö| jD ]}| j |¡ qä| jd k	r| j | j¡ | j	d k	r*| j | j	¡ | jd k	rD| j | j¡ | j d k	r^| j !| j ¡ |  "¡  d S )Nr   )Únew_compilerÚ
build_clib)r:   ÚverboseÚdry_runr(   rS   )#r   rx   r.   rc   Úhas_c_librariesÚget_finalized_commandr6   rn   Zget_library_namesr7   rm   ry   r:   rz   r{   r(   r   rJ   rp   r0   r   Z
initializer3   Zset_include_dirsr4   Zdefine_macror5   Zundefine_macroZset_librariesZset_library_dirsr8   Zset_runtime_library_dirsr9   Zset_link_objectsÚbuild_extensions)r@   rx   ry   rp   ÚvalueÚmacror   r   r   Úrun'  sB    

ü




zbuild_ext.runc           
      C   sv  t |tƒstdƒ‚t|ƒD ]T\}}t |tƒr0qt |tƒrFt|ƒdkrNtdƒ‚|\}}t d|¡ t |t	ƒrvt
 |¡s~tdƒ‚t |tƒstdƒ‚t||d ƒ}dD ]"}| |¡}|d	k	r¢t|||ƒ q¢| d
¡|_d|krät d¡ | d¡}|rhg |_g |_|D ]b}	t |	tƒr"t|	ƒdks*tdƒ‚t|	ƒdkrJ|j |	d ¡ nt|	ƒdkr|j |	¡ q|||< qd	S )a¬  Ensure that the list of extensions (presumably provided as a
        command option 'extensions') is valid, i.e. it is a list of
        Extension objects.  We also support the old-style list of 2-tuples,
        where the tuples are (ext_name, build_info), which are converted to
        Extension instances here.

        Raise DistutilsSetupError if the structure is invalid anywhere;
        just returns otherwise.
        z:'ext_modules' option must be a list of Extension instancesr   zMeach element of 'ext_modules' option must be an Extension instance or 2-tuplezvold-style (ext_name, build_info) tuple found in ext_modules for extension '%s' -- please convert to Extension instancezRfirst element of each tuple in 'ext_modules' must be the extension name (a string)zOsecond element of each tuple in 'ext_modules' must be a dictionary (build info)Úsources)r3   r7   r6   Úextra_objectsÚextra_compile_argsÚextra_link_argsNr8   Zdef_filez9'def_file' element of build info dict no longer supportedÚmacros)é   r   z9'macros' element of build info dict must be 1- or 2-tupler‡   r   )rg   Úlistr   Ú	enumerater   ÚtupleÚlenr   Úwarningrh   Úextension_name_reÚmatchÚdictÚgetÚsetattrÚruntime_library_dirsÚdefine_macrosÚundef_macrosrm   )
r@   r.   r   ÚextÚext_nameZ
build_infoÚkeyÚvalr†   r€   r   r   r   Úcheck_extensions_listi  s\    

ÿ
ÿüÿ
ÿ


ÿzbuild_ext.check_extensions_listc                 C   s,   |   | j¡ g }| jD ]}| |j¡ q|S ©N)r™   r.   rn   r‚   )r@   Ú	filenamesr•   r   r   r   Úget_source_filesÂ  s
    
zbuild_ext.get_source_filesc                    s    ˆ   ˆ j¡ ‡ fdd„ˆ jD ƒS )Nc                    s   g | ]}ˆ   |j¡‘qS r   )Úget_ext_fullpathrp   ©r]   r•   r?   r   r   r_   Ô  s     z)build_ext.get_outputs.<locals>.<listcomp>)r™   r.   r?   r   r?   r   Úget_outputsË  s    zbuild_ext.get_outputsc                 C   s(   |   | j¡ | jr|  ¡  n|  ¡  d S rš   )r™   r.   r>   Ú_build_extensions_parallelÚ_build_extensions_serialr?   r   r   r   r~   Ö  s    
zbuild_ext.build_extensionsc                    sº   ˆj }ˆj dkrt ¡ }zddlm} W n tk
r@   d }Y nX |d krVˆ ¡  d S ||dP‰ ‡ ‡fdd„ˆjD ƒ}tˆj|ƒD ]&\}}ˆ 	|¡ | 
¡  W 5 Q R X q„W 5 Q R X d S )NTr   )ÚThreadPoolExecutor)Úmax_workersc                    s   g | ]}ˆ   ˆj|¡‘qS r   )ZsubmitÚbuild_extensionrž   ©Úexecutorr@   r   r   r_   ì  s    z8build_ext._build_extensions_parallel.<locals>.<listcomp>)r>   rJ   Ú	cpu_countÚconcurrent.futuresr¢   ÚImportErrorr¡   r.   ÚzipÚ_filter_build_errorsÚresult)r@   Úworkersr¢   Zfuturesr•   Zfutr   r¥   r   r    Þ  s"    

ÿz$build_ext._build_extensions_parallelc              
   C   s0   | j D ]$}|  |¡ |  |¡ W 5 Q R X qd S rš   )r.   r«   r¤   )r@   r•   r   r   r   r¡   ó  s    
z"build_ext._build_extensions_serialc              
   c   sX   z
d V  W nH t ttfk
rR } z$|js*‚ |  d|j› d|› ¡ W 5 d }~X Y nX d S )Nzbuilding extension "z
" failed: )r   r	   r   ÚoptionalÚwarnrp   )r@   r•   Úer   r   r   r«   ø  s    
zbuild_ext._filter_build_errorsc           
      C   sT  |j }|d kst|ttfƒs.td|j› dƒ‚t|ƒ}|  |j¡}||j }| j	spt
||dƒspt d|j¡ d S t d|j¡ |  ||¡}|jp’g }|jd d … }|jD ]}| |f¡ q¨| jj|| j||j| j||jd}|d d … | _|jrü| |j¡ |jpg }|jp| j |¡}	| jj|||  |¡|j|j ||  !|¡| j| j|	d
 d S )Nz$in 'ext_modules' option (extension 'zD'), 'sources' must be present and must be a list of source filenamesÚnewerz$skipping '%s' extension (up-to-date)zbuilding '%s' extension)Ú
output_dirr†   r3   r&   Úextra_postargsÚdepends)r6   r7   r’   r³   Úexport_symbolsr&   r1   Ztarget_lang)"r‚   rg   rˆ   rŠ   r   rp   Úsortedr   r´   r(   r   r   r&   ÚinfoÚswig_sourcesr„   r“   r”   rm   r:   Úcompiler1   r3   Z_built_objectsrƒ   rn   r…   ÚlanguageZdetect_languageZlink_shared_objectÚget_librariesr7   r’   Úget_export_symbols)
r@   r•   r‚   Úext_pathr´   Ú
extra_argsr†   r5   Zobjectsrº   r   r   r   r¤     sV    ÿ


ùözbuild_ext.build_extensionc                 C   s  g }g }i }| j rt d¡ | j s6d| jks6d|jkr<d}nd}|D ]P}tj |¡\}}	|	dkrŠ| |d | ¡ | |¡ |d ||< qD| |¡ qD|sž|S | jpª|  	¡ }
|
dg}| 
| j¡ | j rÐ| d¡ | jsâ| 
|j¡ |D ].}|| }t d	||¡ |  |d
||g ¡ qæ|S )züWalk the list of source files in 'sources', looking for SWIG
        interface (.i) files.  Run SWIG on all that are found, and
        return a modified 'sources' list with SWIG source files replaced
        by the generated C (or C++) files.
        z/--swig-cpp is deprecated - use --swig-opts=-c++z-c++z.cppz.cz.iÚ_wrapéÿÿÿÿz-pythonzswigging %s to %sz-o)r<   r   rŒ   r=   rJ   rK   Úsplitextrm   r;   Ú	find_swigrn   r·   Úspawn)r@   r‚   Ú	extensionZnew_sourcesr¸   Zswig_targetsZ
target_extÚsourcerD   r•   r;   Zswig_cmdÚtargetr   r   r   r¸   R  sD    
ÿþý

zbuild_ext.swig_sourcesc                 C   sd   t jdkrdS t jdkrNdD ],}t j d|› d¡}t j |¡r|  S qdS tdt j› dƒ‚d	S )
z›Return the name of the SWIG executable.  On Unix, this is
        just "swig" -- it should be in the PATH.  Tries a bit harder on
        Windows.
        Úposixr;   rS   )z1.3z1.2z1.1zc:\swigzswig.exez;I don't know how to find (much less run) SWIG on platform 'ú'N)rJ   rp   rK   rL   Úisfiler   )r@   ÚversÚfnr   r   r   rÂ   Š  s    


ÿzbuild_ext.find_swigc                 C   sŽ   |   |¡}| d¡}|  |d ¡}| jsRtjj|dd… |g Ž }tj | j|¡S d |dd… ¡}|  d¡}tj 	| 
|¡¡}tj ||¡S )z¡Returns the path of the filename for a given extension.

        The file is located in `build_lib` or directly in the package
        (inplace option).
        rC   rÀ   Nr   Úbuild_py)Úget_ext_fullnameri   Úget_ext_filenamer   rJ   rK   rL   r/   r}   ÚabspathZget_package_dir)r@   r–   ÚfullnameÚmodpathÚfilenamer2   rÌ   Úpackage_dirr   r   r   r   £  s    


zbuild_ext.get_ext_fullpathc                 C   s    | j dkr|S | j d | S dS )zSReturns the fullname of a given extension name.

        Adds the `package.` prefixNrC   )r2   )r@   r–   r   r   r   rÍ   ¾  s    
zbuild_ext.get_ext_fullnamec                 C   s.   ddl m} | d¡}|dƒ}tjj|Ž | S )z¦Convert the name of an extension (eg. "foo.bar") into the name
        of the file from which it will be loaded (eg. "foo/bar.so", or
        "foo\bar.pyd").
        r   ©rF   rC   Ú
EXT_SUFFIX)rM   rF   ri   rJ   rK   rL   )r@   r–   rF   r½   Ú
ext_suffixr   r   r   rÎ   Ç  s    
zbuild_ext.get_ext_filenamec                 C   s|   |j  d¡d }z| d¡ W n0 tk
rN   d| d¡ dd¡ d¡ }Y n
X d| }d	| }||jkrv|j |¡ |jS )
a  Return the list of symbols that a shared extension has to
        export.  This either uses 'ext.export_symbols' or, if it's not
        provided, "PyInit_" + module_name.  Only relevant on Windows, where
        the .pyd file (DLL) must export the module "PyInit_" function.
        rC   rÀ   ÚasciiZU_Úpunycodeó   -ó   _Ú_ZPyInit)rp   ri   ÚencodeÚUnicodeEncodeErrorÚreplaceÚdecoderµ   rm   )r@   r•   rp   rv   Zinitfunc_namer   r   r   r¼   Ò  s    "
zbuild_ext.get_export_symbolsc                 C   sð   t jdkrdtƒ sdddlm} t| j|ƒsêd}| jr:|d }|t jd? t jd? d@ f }|j	|g S n†dd	l
m} d
}|dƒrÎtt dƒrŒd}nBt jdksœtƒ r¢d}n,dtjkrÎ|dƒdkr¾d}n|dƒdkrÎd}|rê|dƒ}|j	d| g S |j	S )zÓReturn the list of libraries to link against when building a
        shared extension.  On most platforms, this is just 'ext.libraries';
        on Windows, we add the Python library (eg. python20.dll).
        rT   r   )ÚMSVCCompilerz
python%d%dZ_dé   é   éÿ   rÔ   FrB   ÚgetandroidapilevelTrW   Ú_PYTHON_HOST_PLATFORMÚANDROID_API_LEVELr   ÚMACHDEPÚ	LDVERSIONrY   )rH   rI   r   Z_msvccompilerrà   rg   r:   r&   Ú
hexversionr6   rM   rF   ÚhasattrrJ   Úenviron)r@   r•   rà   ÚtemplateZ	pythonlibrF   Zlink_libpythonZ	ldversionr   r   r   r»   ç  s6    
þ


zbuild_ext.get_libraries)"Ú__name__Ú
__module__Ú__qualname__ÚdescriptionrJ   rj   Zsep_byr   Úuser_optionsÚboolean_optionsr   Úhelp_optionsrA   ÚstaticmethodrO   rw   r   r™   rœ   rŸ   r~   r    r¡   Ú
contextlibÚcontextmanagerr«   r¤   r¸   rÂ   r   rÍ   rÎ   r¼   r»   r   r   r   r   r   '   sp   ýýýÛ(
ÿ
 BY	
Q8	r   )!Ú__doc__rõ   rJ   ÚrerH   Zdistutils._logr   Úsiter   Z	_modifiedr   Úcorer   Úerrorsr   r   r	   r
   r   r   rÄ   r   rM   r   r   r   Úutilr   r   r¹   r   r   r   r   r   r   r   Ú<module>   s    
