o _a|{@sdZddlZddlZddlZddlZddlmZddlTddlm Z m Z ddlm Z ddl m Z ddlmZdd lmZdd lmZd d lmZdd lmZedZddZGdddeZdS)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) py37compat) USER_BASEz3^[a-zA-Z_][a-zA-Z_0-9]*(\.[a-zA-Z_][a-zA-Z_0-9]*)*$cCsddlm}|dS)Nrshow_compilers)distutils.ccompilerrrrI/usr/lib/python3/dist-packages/setuptools/_distutils/command/build_ext.pyrs  rc@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)rr r"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_objectsr r"compilerswigswig_cpp swig_optsr'parallelselfrrrinitialize_optionsks* 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 jt|jtj|j dkrd}n|j dd}t jtjd}|rt j||}|j|tj!dddkrK|j"sE|jt jtjddt#dn|jd|$dre|j"s_|j|$dn|jd|j%rw|j% d}d d!|D|_%|j&r|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+|_+WdSt-yt.d#wdS)$Nr) sysconfigbuild)r)r))r+r+)r4r4)r r )r"r")r8r8)r*r*r ) plat_specificincluder0r3ntlibsDebugReleasewin32PCbuildcygwinlibpythonconfig.Py_ENABLE_SHAREDLIBDIR,cSsg|]}|dfqS)1r).0symbolrrr sz.build_ext.finalize_options.. zparallel should be an integer)/ distutilsr<set_undefined_optionsr, distribution ext_package ext_modulesr(get_python_incr- isinstancestrsplitospathsepsys exec_prefixbase_exec_prefixappendpathjoinextendensure_string_listr0r1r2nameprefixr r+dirnamerr*platform python_buildrget_config_varr.r/r7r'r isdirr8int ValueErrorDistutilsOptionError) r:r< py_includeplat_py_includesuffixnew_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)r4verbosedry_runr"r@)#rrzr(rWhas_c_librariesget_finalized_commandr0rfget_library_namesr1rcr{r4r|r}r"rr^rhr*r initializer-set_include_dirsr. define_macror/undefine_macro set_librariesset_library_dirsr2set_runtime_library_dirsr3set_link_objectsbuild_extensions)r:rzr{rhvaluemacrorrrruns@             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-r1r0 extra_objectsextra_compile_argsextra_link_argsNr2def_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_macrosrc) r:r(rextext_name build_infokeyvalrrrrrcheck_extensions_listUsd             zbuild_ext.check_extensions_listcCs,||jg}|jD]}||jq |SN)rr(rfr)r: filenamesrrrrget_source_filess  zbuild_ext.get_source_filescCs2||jg}|jD] }|||jq |Sr)rr(rcget_ext_fullpathrh)r:outputsrrrr get_outputss  zbuild_ext.get_outputscCs*||j|jr|dS|dSr)rr(r8_build_extensions_parallel_build_extensions_serialr9rrrrs   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)rQrexecutorr:rrrSsz8build_ext._build_extensions_parallel..) r8r^ cpu_countconcurrent.futuresr ImportErrorrr(zip_filter_build_errorsresult)r:workersrfuturesrfutrrrrs,      "z$build_ext._build_extensions_parallelc CsD|jD]}|| ||Wdn1swYqdSr)r(rr)r:rrrrrs   z"build_ext._build_extensions_serialc csXzdVWdStttfy+}z|js|d|j|fWYd}~dSd}~ww)Nz"building extension "%s" failed: %s)CCompilerErrorDistutilsError CompileErroroptionalrrh)r:rerrrrs 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-r extra_postargsdepends)r0r1rrexport_symbolsr r+ target_lang)"rr[rrrrhsortedrrr"rr r info swig_sourcesrrrrcr4compiler+r-_built_objectsrrfrlanguagedetect_languagelink_shared_object get_librariesr1rget_export_symbols) r:rrext_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) r6r rr7r^rdsplitextrcr5 find_swigrfrspawn)r:r extension new_sourcesr swig_targets target_extsourcebaserr5swig_cmdotargetrrrr1s>        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. posixr5r@)z1.3z1.2z1.1z c:\swig%szswig.exez>I don't know how to find (much less run) SWIG on platform '%s')r^rhrdreisfileDistutilsPlatformError)r:versfnrrrrgs   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). rLrNrbuild_py) get_ext_fullnamer]get_ext_filenamerr^rdrer)rabspathget_package_dir)r:rfullnamemodpathfilenamer,r package_dirrrrrs   zbuild_ext.get_ext_fullpathcCs|jdur|S|jd|S)zSReturns the fullname of a given extension name. Adds the `package.` prefixNrL)r,)r:rrrrrs 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"). rrmrL EXT_SUFFIX)distutils.sysconfigrmr]r^rdre)r:rrmr ext_suffixrrrrs  zbuild_ext.get_ext_filenamecCsz|jdd}z|dWnty&d|dddd}Ynwd|}d |}||jvr:|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. rLrasciiU_punycode-__PyInit)rhr]encodeUnicodeEncodeErrorreplacedecoderrc)r:rrhrt initfunc_namerrrrs    zbuild_ext.get_export_symbolscCstjdkr/ddlm}t|j|s.d}|jr|d}|tjd?tjd?d@f}|j|gSn@dd l m }d }|d rat td rCd }ntjdkrKd }ndt j vra|ddkrYd }n|ddkrad }|ro|d}|jd|gS|jtS)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_drFrMgetandroidapilevelTrH_PYTHON_HOST_PLATFORMANDROID_API_LEVELMACHDEP LDVERSIONrJ)r`rkdistutils._msvccompilerrr[r4r hexversionr0rrmhasattrr^environr pythonlib)r:rrtemplaterrmlink_libpython ldversionrrrrs6         zbuild_ext.get_libraries) __name__ __module__ __qualname__ descriptionr^r_sep_byr user_optionsboolean_optionsr help_optionsr;ryrrrrrrr contextlibcontextmanagerrrrrrrrrrrrrrr"sp +@N   L6  r)__doc__rr^rer`distutils.corerdistutils.errorsrrrrdistutils.dep_utilrdistutils.extensionrdistutils.utilr rUr r siter rrrrrrrrs(