o
    ǉf/|                     @   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T ddl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 ddlmZ edZd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).    N)Command)*)customize_compilerget_python_version)get_config_h_filename)newer_group)	Extension)get_platform)log)	USER_BASEz3^[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)distutils.ccompilerr   r    r   w/home/ych/rk3568/buildroot/output/rockchip_rk3568_recovery/build/host-python3-3.10.5/Lib/distutils/command/build_ext.pyr      s   
r   c                   @   s  e Zd ZdZdej Zddddde  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dde
fgZd d! Zd"d# Zd$d% Zd&d' Zd(d) Zd*d+ Zd,d- Zd.d/ Zd0d1 Zejd2d3 Zd4d5 Zd6d7 Zd8d9 Zd:d; Zd<d= Zd>d? Zd@dA ZdBdC ZdS )D	build_extz8build C/C++ extensions (compile/link to build directory)z (separated by '%s'))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: %s))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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 )Nr   )
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_optionsj   s*   
zbuild_ext.initialize_optionsc              
   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-| 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  t tdd }|r| 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r\tj#$tjtjdrV| jtjtjddt%  d n| jd |&dr|j's|&d }d!tj(v rytj()d!| }| j| n| jd | j*r| j*d"}d#d$ |D | _*| j+r| j+d"| _+| j,d u rg | _,n| j,d%| _,| j-rtjt.d}	tjt.d}
tj/|	r| j	|	 tj/|
r| j|
 | j|
 t
| j0trz	t1| j0| _0W d S  t2y   t3d&w d S )'Nr   )	sysconfigbuild)r'   r'   )r)   r)   )r2   r2   )r   r   )r    r    )r6   r6   )r(   r(      )Zplat_specificincluder.   r1   ntlibsZDebugZRelease_homewin32   ZPCbuild   cygwinbinlibpythonconfig.Py_ENABLE_SHAREDLIBDIRZ_python_sysroot,c                 S   s   g | ]}|d fqS )1r   ).0Zsymbolr   r   r   
<listcomp>   s    z.build_ext.finalize_options.<locals>.<listcomp> zparallel should be an integer)4	distutilsr:   Zset_undefined_optionsr*   distributionZext_packageext_modulesr&   Zget_python_incr+   
isinstancestrsplitospathsepsysexec_prefixbase_exec_prefixappendpathjoinextendZensure_string_listr.   r/   r0   nameprefixr   r)   dirnamer   getattrr(   platform
executable
startswithr   get_config_varZpython_buildenvirongetr,   r-   r5   r%   r   isdirr6   int
ValueErrorZDistutilsOptionError)r8   r:   Z
py_includeZplat_py_include	_sys_homesuffixZnew_liblibdirZdefinesZuser_includeZuser_libr   r   r   finalize_options   s   










zbuild_ext.finalize_optionsc                 C   sb  ddl m} | jsd S | j r&| d}| j| pg  | j	
|j || j| j| j| jd| _t| j tjdkrJ| jt krJ| j| j | jd urV| j| j | jd urj| jD ]\}}| j|| q^| jd ur{| jD ]}| j| qr| 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 )Nr   )new_compiler
build_clib)r2   verbosedry_runr    r>   )#r   rq   r&   rR   Zhas_c_librariesget_finalized_commandr.   r_   Zget_library_namesr/   r\   rr   r2   rs   rt   r    r   rW   r`   r(   r	   Z
initializer+   Zset_include_dirsr,   Zdefine_macror-   Zundefine_macroZset_librariesZset_library_dirsr0   Zset_runtime_library_dirsr1   Zset_link_objectsbuild_extensions)r8   rq   rr   r`   valuemacror   r   r   run  s@   










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 instances   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)r+   r/   r.   extra_objectsextra_compile_argsextra_link_argsNr0   Zdef_filez9'def_file' element of build info dict no longer supportedmacros)r<   rz   z9'macros' element of build info dict must be 1- or 2-tupler<   r   )rT   listDistutilsSetupError	enumerater   tuplelenr
   warnrU   extension_name_rematchdictri   setattrruntime_library_dirsdefine_macrosundef_macrosr\   )
r8   r&   r   extext_nameZ
build_infokeyvalr   rx   r   r   r   check_extensions_listY  sd   








zbuild_ext.check_extensions_listc                 C   s,   |  | j g }| jD ]}||j q|S N)r   r&   r_   r{   )r8   	filenamesr   r   r   r   get_source_files  s
   
zbuild_ext.get_source_filesc                 C   s2   |  | j g }| jD ]}|| |j q|S r   )r   r&   r\   get_ext_fullpathr`   )r8   Zoutputsr   r   r   r   get_outputs  s
   
zbuild_ext.get_outputsc                 C   s*   |  | j | jr|   d S |   d S r   )r   r&   r6   _build_extensions_parallel_build_extensions_serialr7   r   r   r   rv     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)Zmax_workersc                    s   g | ]	}  j|qS r   )Zsubmitbuild_extension)rN   r   Zexecutorr8   r   r   rO     s    z8build_ext._build_extensions_parallel.<locals>.<listcomp>)r6   rW   	cpu_countZconcurrent.futuresr   ImportErrorr   r&   zip_filter_build_errorsresult)r8   Zworkersr   Zfuturesr   Zfutr   r   r   r     s,   

"z$build_ext._build_extensions_parallelc              	   C   sD   | j D ]}| | | | W d    n1 sw   Y  qd S r   )r&   r   r   )r8   r   r   r   r   r     s   
z"build_ext._build_extensions_serialc              
   c   sX    zd V  W d S  t ttfy+ } z|js | d|j|f  W Y d }~d S d }~ww )Nz"building extension "%s" failed: %s)CCompilerErrorDistutilsErrorZCompileErrorZoptionalr   r`   )r8   r   er   r   r   r     s   zbuild_ext._filter_build_errorsc           
      C   sL  |j }|d u st|ttfstd|j t|}| |j}||j }| j	s6t
||ds6td|j d S td|j | ||}|jpGg }|jd d  }|jD ]}||f qR| 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 )Nzjin 'ext_modules' option (extension '%s'), 'sources' must be present and must be a list of source filenamesZnewerz$skipping '%s' extension (up-to-date)zbuilding '%s' extension)Z
output_dirr   r+   r   extra_postargsdepends)r.   r/   r   r   export_symbolsr   r)   Ztarget_lang)"r{   rT   r   r   r   r`   sortedr   r   r    r   r
   r   infoswig_sourcesr}   r   r   r\   r2   compiler)   r+   Z_built_objectsr|   r_   r~   languageZdetect_languageZlink_shared_objectget_librariesr/   r   get_export_symbols)
r8   r   r{   ext_pathr   Z
extra_argsr   r-   Zobjectsr   r   r   r   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sv|jD ]}|| qn|D ]}|| }td	|| | |d
||g  qx|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)r4   r
   r   r5   rW   r]   splitextr\   r3   	find_swigr_   r   spawn)r8   r{   	extensionZnew_sourcesr   Zswig_targetsZ
target_extsourcebaser   r3   Zswig_cmdotargetr   r   r   r   5  s@   



zbuild_ext.swig_sourcesc                 C   sZ   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 )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.
        posixr3   r>   )z1.3z1.2z1.1z	c:\swig%szswig.exez>I don't know how to find (much less run) SWIG on platform '%s')rW   r`   r]   r^   isfileZDistutilsPlatformError)r8   Zversfnr   r   r   r   k  s   

zbuild_ext.find_swigc                 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).
        rI   r   Nr   build_py)get_ext_fullnamerV   get_ext_filenamer   rW   r]   r^   r'   ru   abspathZget_package_dir)r8   r   fullnamemodpathfilenamer*   r   Zpackage_dirr   r   r   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.` prefixNrI   )r*   )r8   r   r   r   r   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   rg   rI   
EXT_SUFFIX)distutils.sysconfigrg   rV   rW   r]   r^   )r8   r   rg   r   Z
ext_suffixr   r   r   r     s   
zbuild_ext.get_ext_filenamec                 C   sv   d|j dd  }z|d W n ty(   d|dddd }Y nw d	| }||jvr8|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.
        _rI   r   asciir   Zpunycode   -   _ZPyInit)r`   rV   encodeUnicodeEncodeErrorreplacedecoder   r\   )r8   r   rn   Zinitfunc_namer   r   r   r     s    
zbuild_ext.get_export_symbolsc                 C   s   t jdkr1ddlm} t| j|s.d}| jr|d }|t jd? t jd? d@ f }|j|g S |jS dd	l	m
} d
}|drctt drEd}nt jdkrMd}ndtjv rc|ddkr[d}n|ddkrcd}|rq|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%dZ_d         r   FrJ   ZgetandroidapilevelTrD   _PYTHON_HOST_PLATFORMZANDROID_API_LEVELZMACHDEPZ	LDVERSIONrG   )rY   rd   Zdistutils._msvccompilerr   rT   r2   r   
hexversionr.   r   rg   hasattrrW   rh   )r8   r   r   templateZ	pythonlibrg   Zlink_libpythonZ	ldversionr   r   r   r     s6   




zbuild_ext.get_libraries) __name__
__module____qualname__descriptionrW   rX   Zsep_byr	   Zuser_optionsZboolean_optionsr   Zhelp_optionsr9   rp   ry   r   r   r   rv   r   r   
contextlibcontextmanagerr   r   r   r   r   r   r   r   r   r   r   r   r   r   !   sp    
+ @N	
	L6	
r   )__doc__r   rW   rerY   distutils.corer   distutils.errorsr   r   r   r   Zdistutils.dep_utilr   Zdistutils.extensionr   Zdistutils.utilr	   rQ   r
   Zsiter   r   r   r   r   r   r   r   r   <module>   s&    