o bc{@sdZddlZddlZddlZddlZddlmZddlTddlm Z m Z ddlm Z ddl m Z ddlmZdd lmZdd lmZdd lmZed Zd dZGdddeZdS)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_compilerget_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]*)*$cCsddlm}|dS)Nrshow_compilers)distutils.ccompilerr r r2/usr/lib/python3.10/distutils/command/build_ext.pyr s  r c@seZdZdZdejZdddddefdd d d efd d ddddefddddddddddgZgdZ ddde fgZ d d!Z d"d#Z d$d%Zd&d'Zd(d)Zd*d+Zd,d-Zd.d/Zd0d1Zejd2d3Zd4d5Zd6d7Zd8d9Zd:d;Zdd?Zd@dAZdBdCZdS)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))inplaceiziignore 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)zdefine=DzC preprocessor macros to define)zundef=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)zrpath=Rz7directories to search for shared C libraries at runtime)z link-objects=Oz2extra explicit link objects to include in the link)debuggz'compile/link with debugging information)forcefz2forcibly build everything (ignore file timestamps))z compiler=czspecify the compiler type)z parallel=jznumber of parallel build jobs)swig-cppNz)make SWIG create C++ files (default is C))z swig-opts=Nz!list of SWIG command line options)zswig=Nzpath to the SWIG executable)userNz#add user include, library and rpath)rrr r$r%z help-compilerNzlist available compilerscCsd|_d|_d|_d|_d|_d|_d|_d|_d|_d|_ d|_ d|_ d|_ d|_ d|_d|_d|_d|_d|_d|_d|_dS)Nr) extensions build_lib plat_name build_temprpackage include_dirsdefineundef libraries library_dirsrpath link_objectsrr compilerswigswig_cpp swig_optsr%parallelselfrrrinitialize_optionsjs* zbuild_ext.initialize_optionsc Csddlm}|ddddddd d |jdur|jj|_|jj|_|}|jd d }|j dur7|jj p5g|_ t |j t rE|j t j|_ tjtjkrW|j t jtjd |j | t jj||krq|j | t jj|d|d|jdurg|_|jdurg|_nt |jt r|j t j|_|jdurg|_nt |jt r|j t j|_t jdkr-|jt jtjdtjtjkr|jt jtjd|jrt j|jd|_n t j|jd|_|j t jtt tdd}|r|j||j!dkrd}n|j!dd}t jtjd}|r't j||}|j|tj"dddkr\tj#$t jtjdrV|jt jtjddt%dn|jd |j(ro|j( d"}d#d$|D|_(|j)rz|j) d"|_)|j*durg|_*n|j* d%|_*|j+rt jt,d }t jt,d} t j-|r|j |t j-| r|j| |j| t |j.t rz t/|j.|_.WdSt0yt1d&wdS)'Nr) sysconfigbuild)r'r')r)r))r2r2)rr)r r )r6r6)r(r() plat_specificincluder.r1ntlibsDebugRelease_homewin32PCbuildcygwinbinlibpythonconfig.FPy_ENABLE_SHAREDLIBDIR,cSsg|]}|dfqS)1r).0symbolrrr sz.build_ext.finalize_options.. zparallel should be an integer)2 distutilsr:set_undefined_optionsr* distribution ext_package ext_modulesr&get_python_incr+ isinstancestrsplitospathsepsys exec_prefixbase_exec_prefixappendpathjoinextendensure_string_listr.r/r0nameprefixrr)dirnamergetattrr(platform executable startswithrget_config_var python_buildr,r-r5r%r isdirr6int ValueErrorDistutilsOptionError) r8r: py_includeplat_py_include _sys_homesuffixnew_libdefines user_includeuser_librrrfinalize_optionss                           zbuild_ext.finalize_optionscCsbddlm}|js dS|jr&|d}|j|pg|j |j ||j |j |j|jd|_ t|j tjdkrJ|jtkrJ|j |j|jdurV|j |j|jdurj|jD] \}}|j ||q^|jdur{|jD]}|j |qr|jdur|j |j|j dur|j |j |jdur|j |j|j dur|j !|j |"dS)Nr) new_compiler build_clib)r2verbosedry_runr r?)#rrr&rXhas_c_librariesget_finalized_commandr.rgget_library_namesr/rdrr2rrr rr_rir(r initializer+set_include_dirsr, define_macror-undefine_macro set_librariesset_library_dirsr0set_runtime_library_dirsr1set_link_objectsbuild_extensions)r8rrrivaluemacrorrrruns@             z build_ext.runc Csht|ts tdt|D]\}}t|trq t|tr"t|dkr&td|\}}td|t|t r:t |s>tdt|t sGtdt||d}dD]}| |}|d urat|||qP| d |_d |vrqtd | d }|rg|_g|_|D],} t| trt| dvstdt| dkr|j| dqt| dkr|j| q|||<q d S)aEnsure 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 instanceszMeach 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_objectsextra_compile_argsextra_link_argsNr0def_filez9'def_file' element of build info dict no longer supportedmacros)r<rz9'macros' element of build info dict must be 1- or 2-tupler<r)r\listDistutilsSetupError enumeratertuplelenr warnr]extension_name_rematchdictgetsetattrruntime_library_dirs define_macros undef_macrosrd) r8r&rextext_name build_infokeyvalrrrrrcheck_extensions_listVsd             zbuild_ext.check_extensions_listcCs,||jg}|jD]}||jq |SN)rr&rgr)r8 filenamesrrrrget_source_filess  zbuild_ext.get_source_filescCs2||jg}|jD] }|||jq |Sr)rr&rdget_ext_fullpathri)r8outputsrrrr get_outputss  zbuild_ext.get_outputscCs*||j|jr|dS|dSr)rr&r6_build_extensions_parallel_build_extensions_serialr7rrrrs   zbuild_ext.build_extensionsc sj}jdur t}zddlm}Wn tyd}Ynw|dur*dS||d8fddjD}tj|D]\}} | | Wdn1sYwYqAWddS1sjwYdS)NTr)ThreadPoolExecutor) max_workerscsg|] }j|qSr)submitbuild_extension)rRrexecutorr8rrrTsz8build_ext._build_extensions_parallel..) r6r_ cpu_countconcurrent.futuresr ImportErrorrr&zip_filter_build_errorsresult)r8workersrfuturesrfutrrrrs,      "z$build_ext._build_extensions_parallelc CsD|jD]}|| ||Wdn1swYqdSr)r&rr)r8rrrrrs   z"build_ext._build_extensions_serialc csXzdVWdStttfy+}z|js|d|j|fWYd}~dSd}~ww)Nz"building extension "%s" failed: %s)CCompilerErrorDistutilsError CompileErroroptionalrri)r8rerrrrs zbuild_ext._filter_build_errorsc CsL|j}|dust|ttfstd|jt|}||j}||j}|j s6t ||ds6t d|jdSt d|j|||}|jpGg}|jdd}|jD]}||fqR|jj||j||j|j ||jd}|dd|_|jr|||j|jpg}|jp|j|} |jj|||||j|j ||!||j |j| d dS)Nzjin 'ext_modules' option (extension '%s'), 'sources' must be present and must be a list of source filenamesnewerz$skipping '%s' extension (up-to-date)zbuilding '%s' extension) output_dirrr+rextra_postargsdepends)r.r/rrexport_symbolsrr) target_lang)"rr\rrrrisortedrrr rr rinfo swig_sourcesrrrrdr2compiler)r+_built_objectsrrgrlanguagedetect_languagelink_shared_object get_librariesr/rget_export_symbols) r8rrext_pathr extra_argsrr-objectsrrrrrsV         zbuild_ext.build_extensioncCs$g}g}i}|jrtd|jsd|jvsd|jvrd}nd}|D](}tj|\}} | dkrE||d||||d||<q"||q"|sO|S|jpU| } | dg} | |j|jrh| d|jsv|jD]} | | qn|D]}||} t d || | | d | |gqx|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-pythonzswigging %s to %sz-o) r4r rr5r_resplitextrdr3 find_swigrgrspawn)r8r extension new_sourcesr swig_targets target_extsourcebaserr3swig_cmdotargetrrrr2s>        zbuild_ext.swig_sourcescCsZtjdkrdStjdkr&dD]}tjd|d}tj|r#|SqdStdtj)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. posixr3r?)z1.3z1.2z1.1z c:\swig%szswig.exez>I don't know how to find (much less run) SWIG on platform '%s')r_rirerfisfileDistutilsPlatformError)r8versfnrrrrhs   zbuild_ext.find_swigcCs||}|d}||d}|js)tjj|dd|g}tj|j|Sd|dd}|d}tj | |}tj||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). rMrNrbuild_py) get_ext_fullnamer^get_ext_filenamerr_rerfr'rabspathget_package_dir)r8rfullnamemodpathfilenamer*r package_dirrrrrs   zbuild_ext.get_ext_fullpathcCs|jdur|S|jd|S)zSReturns the fullname of a given extension name. Adds the `package.` prefixNrM)r*)r8rrrrrs zbuild_ext.get_ext_fullnamecCs.ddlm}|d}|d}tjj||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"). rrprM EXT_SUFFIX)distutils.sysconfigrpr^r_rerf)r8rrpr ext_suffixrrrrs  zbuild_ext.get_ext_filenamecCsvd|jdd}z|dWnty(d|dddd}Ynwd |}||jvr8|j||jS) aReturn 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. _rMrasciirpunycode-_PyInit)rir^encodeUnicodeEncodeErrorreplacedecoderrd)r8rry initfunc_namerrrrs    zbuild_ext.get_export_symbolscCstjdkr1ddlm}t|j|s.d}|jr|d}|tjd?tjd?d@f}|j|gS|jSdd l m }d } |rH|d}|jd|gS|jS)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). rDr) MSVCCompilerz python%d%d_drFrNgetandroidapilevelTrH_PYTHON_HOST_PLATFORMANDROID_API_LEVELMACHDEP LDVERSIONrK)rarmdistutils._msvccompilerrr\r2r hexversionr.rrphasattrr_environ)r8rrtemplate pythonlibrplink_libpython ldversionrrrrs$     zbuild_ext.get_libraries) __name__ __module__ __qualname__ descriptionr_r`sep_byr user_optionsboolean_optionsr help_optionsr9r~rrrrrrr contextlibcontextmanagerrrrrrrrrrrrrrr!sp +@N   L6  r)__doc__r!r_reradistutils.corerdistutils.errorsrrrrdistutils.dep_utilrdistutils.extensionrdistutils.utilr rVr siter rrr rrrrrs&