o
    LK&h                     @  s   d Z ddlm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 dd
lmZ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%m&Z& e'dZ(G dd deZ)dS )zdistutils.command.build_ext

Implements the Distutils 'build_ext' command, for building extension
modules (currently limited to C extensions, should accommodate C++
extensions ASAP).    )annotationsN)Callable)log)	USER_BASE)ClassVar   )newer_group)new_compilershow_compilers)Command)CCompilerErrorCompileErrorDistutilsErrorDistutilsOptionErrorDistutilsPlatformErrorDistutilsSetupError)	Extension)customize_compilerget_config_h_filenameget_python_version)get_platformis_freethreadedis_mingwz3^[a-zA-Z_][a-zA-Z_0-9]*(\.[a-zA-Z_][a-zA-Z_0-9]*)*$c                   @  sR  e Zd ZU 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g dZ	de
d < d!d"d#efgZd$e
d%< d&d' Zed(d) ZdUd,d-ZdUd.d/ZdUd0d1Zd2d3 Zd4d5 ZdUd6d7Zd8d9 Zd:d; Zejd<d= ZdUd>d?Zd@dA ZdBdC ZdVdFdGZdVdHdIZdVdJdKZ dWdOdPZ!dQdR Z"dWdSdTZ#d"S )X	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 rpath)r   r'   r)   r-   r.   zClassVar[list[str]]boolean_optionszhelp-compilerNzlist available compilerszAClassVar[list[tuple[str, str | None, str, Callable[[], object]]]]help_optionsc                 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self rD   Z/var/www/html/venv/lib/python3.10/site-packages/setuptools/_distutils/command/build_ext.pyinitialize_optionsp   s*   
zbuild_ext.initialize_optionsc                 c  sb    |  dsdS | jrdV  dS tjdkr)|  d}|  d}tj||V  dS |  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.zosbase
platlibdirLIBDIR)get_config_varpython_buildsysplatformospathjoin)	sysconfiginstalled_dirlib_dirrD   rD   rE   _python_lib_dir   s   



zbuild_ext._python_lib_dirreturnNonec           	   
   C  s  ddl m} | ddddddd	d
 | jd u r| jj| _| jj| _| }|jdd}| j	d u r7| jj	p5g | _	t
| j	trE| j	tj| _	tjtjkrW| j	tjtjd | j	|tjj ||krq| j	|tjj | d | d | jd u rg | _| jd u rg | _nt
| jtr| jtj| _| jd u rg | _nt
| jtr| 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rt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}|r#tj||}| j| tj"d d dkrO|j#sI| jtjtjddt$  d n| jd | j| %| | j&rj| j&d}dd |D | _&| j'ru| j'd| _'| j(d u rg | _(n| j(d | _(| j)rtjt*d}tjt*d}tj+|r| j	| tj+|r| j| | j| t
| j,trz	t-| j,| _,W d S  t.y   t/d!w d S )"Nr   )rT   build)r2   r2   )r4   r4   )r=   r=   )r'   r'   )r)   r)   )rA   rA   )r3   r3   T)plat_specificincluder9   r<   ntlibsDebugReleasewin32   PCbuild   cygwinlibpythonconfigrH   ,c                 S  s   g | ]}|d fqS )1rD   ).0symbolrD   rD   rE   
<listcomp>  s    z.build_ext.finalize_options.<locals>.<listcomp> zparallel should be an integer)0	distutilsrT   set_undefined_optionsr5   distributionext_packageext_modulesr1   get_python_incr6   
isinstancestrsplitrQ   pathseprO   exec_prefixbase_exec_prefixappendrR   rS   extendensure_string_listr9   r:   r;   namer   prefixr'   r4   dirnamer   r3   rP   rN   r   rW   r7   r8   r@   r.   r   isdirrA   int
ValueErrorr   )	rC   rT   
py_includeplat_py_includesuffixnew_libdefinesuser_includeuser_librD   rD   rE   finalize_options   s   








zbuild_ext.finalize_optionsc                 C  st  | j sd S | j r | d}| j| pg  | j|j	 t
| j| j| j| jd| _t| j tjdkrD| jt krD| j| j tjdkrSt rS| jdd | jd ur_| j| j | jd urs| jD ]\}}| j|| qg| jd ur| jD ]}| j| q{| jd ur| j| j | jd ur| j| j | jd ur| j| j | j d ur| j!| j  | "  d S )N
build_clib)r=   verbosedry_runr)   r]   Py_GIL_DISABLEDrj   )#r1   rq   has_c_librariesget_finalized_commandr9   r|   get_library_namesr:   r{   r   r	   r=   r   r   r)   r   rQ   r~   r3   r   
initializer   define_macror6   set_include_dirsr7   r8   undefine_macroset_librariesset_library_dirsr;   set_runtime_library_dirsr<   set_link_objectsbuild_extensions)rC   r   r~   valuemacrorD   rD   rE   run,  sD   










zbuild_ext.runc           
      C  sh  t |ts	tdt|D ]\}}t |trqt |tr"t|dkr&td|\}}td| t |t	r:t
|s>tdt |tsGtdt||d }dD ]}||}|d	urat||| qP|d
|_d|v rqtd |d}|rg |_g |_|D ],}	t |	trt|	dv stdt|	dkr|j|	d  qt|	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)r6   r:   r9   extra_objectsextra_compile_argsextra_link_argsNr;   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   )ru   listr   	enumerater   tuplelenr   warningrv   extension_name_rematchdictgetsetattrruntime_library_dirsdefine_macrosundef_macrosr{   )
rC   r1   r   extext_name
build_infokeyvalr   r   rD   rD   rE   check_extensions_listr  sb   







zbuild_ext.check_extensions_listc                 C  s,   |  | j g }| jD ]}||j q|S N)r   r1   r|   r   )rC   	filenamesr   rD   rD   rE   get_source_files  s
   
zbuild_ext.get_source_filesc                   s       j  fdd jD S )Nc                   s   g | ]}  |jqS rD   )get_ext_fullpathr~   rk   r   rB   rD   rE   rm     s    z)build_ext.get_outputs.<locals>.<listcomp>)r   r1   rB   rD   rB   rE   get_outputs  s   zbuild_ext.get_outputsc                 C  s*   |  | j | jr|   d S |   d S r   )r   r1   rA   _build_extensions_parallel_build_extensions_serialrB   rD   rD   rE   r     s   zbuild_ext.build_extensionsc              
     s   j }j du rt }zddlm} W n ty   d }Y nw |d u r*  d S ||d8  fddjD }tj|D ]\}}	| |
  W d    n1 sYw   Y  qAW d    d S 1 sjw   Y  d S )NTr   )ThreadPoolExecutor)max_workersc                   s   g | ]	}  j|qS rD   )submitbuild_extensionr   executorrC   rD   rE   rm     s    z8build_ext._build_extensions_parallel.<locals>.<listcomp>)rA   rQ   	cpu_countconcurrent.futuresr   ImportErrorr   r1   zip_filter_build_errorsresult)rC   workersr   futuresr   futrD   r   rE   r     s,   

"z$build_ext._build_extensions_parallelc              	   C  sD   | j D ]}| | | | W d    n1 sw   Y  qd S r   )r1   r   r   )rC   r   rD   rD   rE   r     s   
z"build_ext._build_extensions_serialc              
   c  s\    zd V  W d S  t ttfy- } z|js | d|j d|  W Y d }~d S d }~ww )Nzbuilding extension "z
" failed: )r   r   r   optionalwarnr~   )rC   r   erD   rD   rE   r      s   &zbuild_ext._filter_build_errorsc           
      C  sP  |j }|d u st|ttfstd|j dt|}| |j}||j }| j	s8t
||ds8td|j d S td|j | ||}|jpIg }|jd d  }|jD ]}||f qT| jj|| j||j| j||jd}|d d  | _|jr~||j |jpg }|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   r6   r'   extra_postargsdepends)r9   r:   r   r   export_symbolsr'   r4   target_lang)"r   ru   r   r   r   r~   sortedr   r   r)   r   r   r'   infoswig_sourcesr   r   r   r{   r=   compiler4   r6   _built_objectsr   r|   r   languagedetect_languagelink_shared_objectget_librariesr:   r   get_export_symbols)
rC   r   r   ext_pathr   
extra_argsr   r8   objectsr   rD   rD   rE   r   	  sV   




zbuild_ext.build_extensionc                 C  s  g }g }i }| j rtd | j sd| jv sd|jv rd}nd}|D ](}tj|\}}	|	dkrE||d |  || |d ||< q"|| q"|sO|S | jpU| 	 }
|
dg}|
| j | j rh|d | jsq|
|j |D ]}|| }td	|| | |d
||g  qs|S )zWalk 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_wrapz-pythonzswigging %s to %sz-o)r?   r   r   r@   rQ   rR   splitextr{   r>   	find_swigr|   r   spawn)rC   r   	extensionnew_sourcesr   swig_targets
target_extsourcerJ   r   r>   swig_cmdtargetrD   rD   rE   r   Z  s@   




zbuild_ext.swig_sourcesc                 C  s`   t jdkrdS t jdkr'dD ]}t jd| d}t j|r$|  S qdS tdt j d)	zReturn 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>   r]   )z1.3z1.2z1.1zc:\swigzswig.exez;I don't know how to find (much less run) SWIG on platform '')rQ   r~   rR   rS   isfiler   )rC   versfnrD   rD   rE   r     s   

zbuild_ext.find_swigr   rv   c                 C  s   |  |}|d}| |d }| js)tjj|dd |g  }tj| j|S d|dd }| d}tj	|
|}tj||S )zReturns the path of the filename for a given extension.

        The file is located in `build_lib` or directly in the package
        (inplace option).
        rH   r   Nr   build_py)get_ext_fullnamerw   get_ext_filenamer   rQ   rR   rS   r2   r   abspathget_package_dir)rC   r   fullnamemodpathfilenamer5   r   package_dirrD   rD   rE   r     s   


zbuild_ext.get_ext_fullpathc                 C  s   | j du r|S | j d | S )zSReturns the fullname of a given extension name.

        Adds the `package.` prefixNrH   )r5   )rC   r   rD   rD   rE   r     s   
zbuild_ext.get_ext_fullnamec                 C  s.   ddl m} |d}|d}tjj| | S )zConvert 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   rM   rH   
EXT_SUFFIX)rT   rM   rw   rQ   rR   rS   )rC   r   rM   r   
ext_suffixrD   rD   rE   r     s   
zbuild_ext.get_ext_filenamer   r   	list[str]c                 C  st   |  |}z|d W n ty#   d|dddd }Y nw d| }d| }||jvr7|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.
        asciiU_punycode   -   __PyInit)_get_module_name_for_symbolencodeUnicodeEncodeErrorreplacedecoder   r{   )rC   r   r~   r   initfunc_namerD   rD   rE   r     s   
 
zbuild_ext.get_export_symbolsc                 C  s4   |j d}|d dkrt|dkr|d S |d S )NrH   r   __init__r   )r~   rw   r   )rC   r   partsrD   rD   rE   r    s   z%build_ext._get_module_name_for_symbolc                 C  s   t jdkr4t s4ddlm} t| j|s1d}| jr|d }|t jd? t jd? d@ f }|j	|g S |j	S dd	l
m} d
}|dritt drHd}n!t jdksPt rSd}ndtjv ri|ddkrad}n|ddkrid}|rw|d}|j	d| g S |j	S )zReturn 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).
        ra   r   )MSVCCompilerz
python%d%d_d         r   FrG   getandroidapilevelTre   _PYTHON_HOST_PLATFORMANDROID_API_LEVELr   MACHDEP	LDVERSIONrg   )rO   rP   r   _msvccompilerr  ru   r=   r'   
hexversionr9   rT   rM   hasattrrQ   environ)rC   r   r  template	pythonlibrM   link_libpython	ldversionrD   rD   rE   r     s8   


zbuild_ext.get_libraries)rX   rY   )r   rv   rX   rv   )r   r   rX   r  )$__name__
__module____qualname__descriptionrQ   rx   sep_byr   user_optionsr/   __annotations__r
   r0   rF   staticmethodrW   r   r   r   r   r   r   r   r   
contextlibcontextmanagerr   r   r   r   r   r   r   r   r  r   rD   rD   rD   rE   r   &   sx   
 (
	

 

FX	


Q8


	
	r   )*__doc__
__future__r   r.  rQ   rerO   collections.abcr   distutils._logr   siter   typingr   	_modifiedr   	ccompilerr	   r
   corer   errorsr   r   r   r   r   r   r   r   rT   r   r   r   utilr   r   r   r   r   r   rD   rD   rD   rE   <module>   s&     
