o
    uJAfi                     @  s   d dl mZ d dlmZ ddlmZmZmZmZ ddl	m
Z
mZmZmZmZmZmZmZ 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Zd dlZd dlZd dlZejrwd dl m!Z! ddl"m#Z# ddl$m%Z% ddl&m'Z' ddl(m)Z) G dd dZ*G dd de*Z+G dd deZ,dS )    )annotations)Path   )ExternalDependencyDependencyExceptionsort_libpathsDependencyTypeName   )EnvironmentVariables	OptionKey
OrderedSet
PerMachine
Popen_safePopen_safe_loggedMachineChoice	join_args)find_external_programExternalProgram)mlog)PurePath)	lru_cacheN)Literal)ImmutableListProtocol)Environment)EnvironOrDict)PkgConfigDefineTypec                   @  s   e Zd ZU dZeddZded< eddZded< ed5ddZ	ed6d7ddZ
ed6d8ddZe	d6d9ddZd:ddZd;dd Zd<d$d%Z		&d=d>d+d,Z		&d?d@d.d/ZdAd1d2ZdBd3d4Zd&S )CPkgConfigInterfacez/Base class wrapping a pkg-config implementationFzCPerMachine[T.Union[Literal[False], T.Optional[PkgConfigInterface]]]
class_implz=PerMachine[T.Union[Literal[False], T.Optional[PkgConfigCLI]]]class_cli_implenvr   for_machiner   silentboolreturnT.Optional[PkgConfigInterface]c                 C  sd   |   r|ntj}tj| }|du r0t| ||}| sd}|s+|s+tdt	d |tj|< |S )z,Return a pkg-config implementation singletonFNFound pkg-config:NO)
is_cross_buildr   HOSTr   r   PkgConfigCLIfoundr   logredr   r    r!   impl r/   F/usr/lib/python3.10/site-packages/mesonbuild/dependencies/pkgconfig.pyinstance+   s   

zPkgConfigInterface.instanceT.Optional[PkgConfigCLI]c                 C  sn   |   r|ntj}t| ||}|r1t|ts1tj| }|du r1t| ||}| s,d}|tj|< t	
d|S )zReturn the CLI pkg-config implementation singleton
        Even when we use another implementation internally, external tools might
        still need the CLI implementation.
        FNr2   )r'   r   r(   r   r1   
isinstancer)   r   r*   Tcastr-   r/   r/   r0   _cli9   s   

zPkgConfigInterface._cliuninstalledr
   c                 C  s    t | |}|r||S t S N)r   r6   _get_envr
   )r   r    r7   clir/   r/   r0   get_envK   s   zPkgConfigInterface.get_envenvironr   c                 C  s    t ||}|r|| |S | S r8   )r   r6   
_setup_env)r<   r   r    r7   r:   r/   r/   r0   	setup_envP   s   zPkgConfigInterface.setup_envNonec                 C  s   || _ || _d S r8   )r   r    )selfr   r    r/   r/   r0   __init__V   s   
zPkgConfigInterface.__init__c                 C     t )z&Return whether pkg-config is supportedNotImplementedErrorr@   r/   r/   r0   r*   Z      zPkgConfigInterface.foundnamestrT.Optional[str]c                 C  rB   )z*Return module version or None if not foundrC   )r@   rG   r/   r/   r0   version^   rF   zPkgConfigInterface.versionNallow_systemdefine_variabler   ImmutableListProtocol[str]c                 C  rB   )zeReturn module cflags
           @allow_system: If False, remove default system include paths
        rC   )r@   rG   rK   rL   r/   r/   r0   cflagsb   s   zPkgConfigInterface.cflagsstaticc                 C  rB   )zReturn module libs
           @static: If True, also include private libraries
           @allow_system: If False, remove default system libraries search paths
        rC   )r@   rG   rO   rK   rL   r/   r/   r0   libsi   s   zPkgConfigInterface.libsvariable_namec                 C  rB   )z9Return module variable or None if variable is not definedrC   )r@   rG   rQ   rL   r/   r/   r0   variableq   s   zPkgConfigInterface.variablec                 C  rB   )z'Return all available pkg-config modulesrC   rE   r/   r/   r0   list_allv   rF   zPkgConfigInterface.list_all)r   r   r    r   r!   r"   r#   r$   F)r   r   r    r   r!   r"   r#   r2   )r   r   r    r   r7   r"   r#   r
   )
r<   r   r   r   r    r   r7   r"   r#   r   )r   r   r    r   r#   r?   r#   r"   rG   rH   r#   rI   FNrG   rH   rK   r"   rL   r   r#   rM   FFN
rG   rH   rO   r"   rK   r"   rL   r   r#   rM   rG   rH   rQ   rH   rL   r   r#   rI   r#   rM   )__name__
__module____qualname____doc__r   r   __annotations__r   staticmethodr1   r6   r;   r>   rA   r*   rJ   rN   rP   rR   rS   r/   r/   r/   r0   r   %   s0   
 



r   c                      s   e Zd ZdZd= fd
dZd>ddZeddd?ddZed@ddZ	edd		dAdBddZ
edd		dCdDd d!ZedddEd#d$ZedddFd%d&ZedGd(d)ZdHd*d+ZdId.d/ZdJdKd2d3ZdJdLd6d7ZdMdNd;d<Z  ZS )Or)   zpkg-config CLI implementationr   r   r    r   r!   r"   r#   r?   c              	     s^   t  || |   | jr+|s-tdtdtd| j  dt	| j
 d S d S d S )Nr%   YES())superrA   _detect_pkgbinpkgbinr   r+   greenboldget_pathbluepkgbin_version)r@   r   r    r!   	__class__r/   r0   rA   }   s
   
6zPkgConfigCLI.__init__c                 C  s
   t | jS r8   )r"   rh   rE   r/   r/   r0   r*      s   
zPkgConfigCLI.foundN)maxsizerG   rH   rI   c                 C  s@   t d|d| j  | d|g\}}}|dkr|S d S )NzDetermining dependency z with pkg-config executable z--modversionr   )r   debugrh   rk   _call_pkgbin)r@   rG   retrJ   _r/   r/   r0   rJ      s   zPkgConfigCLI.versionrL   r   T.List[str]c                 C  s*   g }| r| D ]}| dd|  q|S )Nz--define-variable==)appendjoin)rL   rs   pairr/   r/   r0   _define_variable_args   s
   z"PkgConfigCLI._define_variable_argsFrK   rM   c           	      C  st   d }|rt j }d|d< g }|| |7 }|d|g7 }| j||d\}}}|dkr5td| d| d| |S )	N1ZPKG_CONFIG_ALLOW_SYSTEM_CFLAGSz--cflagsr   r   zCould not generate cflags for :

)osr<   copyrz   rr   r   _split_args)	r@   rG   rK   rL   r   argsrs   outerrr/   r/   r0   rN      s   

zPkgConfigCLI.cflagsrO   c           
      C  s   d }|rt j }d|d< g }|| |7 }|r|d |d|g7 }| j||d\}}}	|dkr<td| d|	 d	| |S )
Nr{   ZPKG_CONFIG_ALLOW_SYSTEM_LIBSz--staticz--libsr|   r   zCould not generate libs for r}   r~   )r   r<   r   rz   rw   rr   r   r   )
r@   rG   rO   rK   rL   r   r   rs   r   r   r/   r/   r0   rP      s   


zPkgConfigCLI.libsrQ   c           
      C  s   g }||  |7 }|d| |g7 }| |\}}}|dkr(td| d| d| }|sF| d|g\}}}	td| d|tjsFd S td	| d
|  |S )Nz--variable=r   zCould not get variable for r}   r~   z--print-variables^$zGot pkg-config variable z : )	rz   rr   r   stripresearch	MULTILINEr   rq   )
r@   rG   rQ   rL   r   rs   r   r   rR   rt   r/   r/   r0   rR      s   zPkgConfigCLI.variablec                 C  s<   |  dg\}}}|dkrtd| ddd | D S )Nz
--list-allr   zcould not list modules:
r~   c                 S  s   g | ]
}| d dd qS ) r   r   )split).0ir/   r/   r0   
<listcomp>   s    z)PkgConfigCLI.list_all.<locals>.<listcomp>)rr   r   
splitlines)r@   rs   r   r   r/   r/   r0   rS      s   zPkgConfigCLI.list_allcmdc                 C  s
   t | S r8   )shlexr   )r   r/   r/   r0   r      s   
zPkgConfigCLI._split_argsc                 C  sL   t | j| jdd| jjddD ]}| |}|r || _|| _ d S qd | _d S )Nz
pkg-configz
Pkg-configF)allow_default_for_cross)r   r   r    default_pkgconfig_check_pkgconfigrh   rm   )r@   Zpotential_pkgbinversion_if_okr/   r/   r0   rg      s   


zPkgConfigCLI._detect_pkgbinrh   r   c                 C  s  |  std|j d S d| }z@t| dg d }d|v r2td|d W d S t| dg d	d
 \}}|jd	krRtd|d W d S W | S  t	yi   td|d Y d S  t
y   d|d}| jjj s|d7 }t| Y d S w )Nz Did not find pkg-config by name r   z--helpr   z	Pure-PerlzFound pkg-config z7 but it is Strawberry Perl and thus broken. Ignoring...z	--versionr   r	   z but it failed when ranzWe thought we found pkg-config z! but now it's not there. How odd!z' but didn't have permissions to run it.zO

On Unix-like systems this is often caused by scripts that are not executable.)r*   r   r+   rG   rx   get_commandr   
returncodewarningFileNotFoundErrorPermissionErrorr   machinesbuild
is_windowsr   )r@   rh   Zcommand_as_stringZhelptextpr   msgr/   r/   r0   r      s2   

zPkgConfigCLI._check_pkgconfigr7   r
   c                 C  s   t  }td| jd}| jjj| jd d  }|r+t| j d	 }||vr+|
| |d| | jj| j  }|rC|d|g | jj| j  }|rT|d| |dt| j g |S )Npkg_config_pathmachinezmeson-uninstalledPKG_CONFIG_PATHPKG_CONFIG_SYSROOT_DIRPKG_CONFIG_LIBDIR
PKG_CONFIG)r
   r   r    r   coredataoptionsvaluer   get_build_diras_posixrw   set
propertiesget_sys_rootget_pkg_config_libdirr   rh   r   )r@   r7   r   keyextra_pathsZuninstalled_pathsysrootZpkg_config_libdir_propr/   r/   r0   r9      s    
zPkgConfigCLI._get_envr   T.Dict[str, str]c                 C  sJ   |  |}||}| D ]\}}|dr"td| d|  q|S )NZPKG_zenv[z]: )r9   r;   items
startswithr   rq   )r@   r   r7   envvarsr   r   r/   r/   r0   r=   
  s   


zPkgConfigCLI._setup_envr   T.Optional[EnvironOrDict]T.Tuple[int, str, str]c                 C  sX   t | jtsJ |ptj}| |}| j | }t||d\}}}|j|	 |	 fS )Nr|   )
r3   rh   r   r   r<   r=   r   r   r   r   )r@   r   r   r   r   r   r   r/   r/   r0   rr     s   

zPkgConfigCLI._call_pkgbin)r   r   r    r   r!   r"   r#   r?   rU   rV   )rL   r   r#   ru   rW   rX   rY   rZ   r[   r\   )r   rH   r#   ru   r#   r?   )rh   r   r#   rI   rT   )r7   r"   r#   r
   )r   r   r7   r"   r#   r   r8   )r   ru   r   r   r#   r   )r]   r^   r_   r`   rA   r*   r   rJ   rb   rz   rN   rP   rR   rS   r   rg   r   r9   r=   rr   __classcell__r/   r/   rn   r0   r)   z   s6    


	r)   c                      s   e Zd Zd4d5 fddZd6ddZd7ddZd8ddZd9ddZd8ddZd:d d!Z	d;d"d#Z
d;d$d%Zd;d&d'Zed6d(d)Zddddddd*d<d2d3Z  ZS )=PkgConfigDependencyNrG   rH   environmentr   kwargsT.Dict[str, T.Any]languagerI   r#   r?   c              
     s  t  jtd|||d || _d| _t| j| j| j	| _
| j
s5d| j d}| jr.t|t| d S | j
|}|d u rAd S || _d| _z|   |   W d S  ty } z"td| d|  | jri g | _g | _d| _|| _W Y d }~d S d }~ww )	N	pkgconfig)r   FzPkg-config for machine z not found. Giving up.TzPkg-config error with 'z': )rf   rA   r   rG   
is_libtoolr   r1   r   r    r!   r   requiredr   r   rq   rJ   is_found
_set_cargs	_set_libscompile_args	link_argsreason)r@   rG   r   r   r   r   rJ   ern   r/   r0   rA     s8   
zPkgConfigDependency.__init__c                 C  s   d}| | jj| j| j| jS )Nz<{0} {1}: {2} {3}>)formatro   r]   rG   r   version_reqs)r@   sr/   r/   r0   __repr__@  s   zPkgConfigDependency.__repr__r   rM   ru   c              	   C  s   | j jj s| S g }|D ]m}t }|dr%t|dd j}d}n5|dr6t|dd j}d}n$|drCt|j}d}n|d	sTt	|dkrZ|d
 dkrZ|
dd}t	|d
krwt	|d
 d
krw||d
 d|dd }|| q|S )a$  
        Both MSVC and native Python on Windows cannot handle MinGW-esque /c/foo
        paths so convert them to C:/foo. We cannot resolve other paths starting
        with / like /home/foo so leave them as-is so that the user gets an
        error/warning from the compiler/linker.
        z-L/r	   Nz-L{}:/{}z-I/z-I{}:/{}/z{}:/{})-Lz-Ir   :z\ r   )r   r   r   r   r   tupler   r   partslenreplacer   rx   rw   )r@   r   	convertedargZpargsZtmplr/   r/   r0   _convert_mingw_pathsE  s(   



"z(PkgConfigDependency._convert_mingw_pathsc                 C  s2   d}| j dkr	d}| j| j|}| || _d S )NFfortranT)r   r   rN   rG   r   r   )r@   rK   rN   r/   r/   r0   r   d  s
   
zPkgConfigDependency._set_cargslibs_inraw_libs_in!T.Tuple[T.List[str], T.List[str]]c                 C  s  t  }| |}|D ]'}|dr1|ds1|dd }tj|s,tj| j |}|	| q
| jj
jtd| jd j}| |}t tt||}t  }| |}	|	D ]}|dr_qW|dru|dd |vru|	|dd  qWt|t| }
t  }g }g }|	D ]}|drn|drq|dr||v rq|dd }d}|
D ]}tj||}tj|r|} nq|du r||v rqtd	|| j || n|}n|d
r4||v rq| jr| jj|dd | j|
| jdd}nd}|dur|	| |r|d d
s|d }nbq||v rq| jr.td|dd | j || nC|drw| |}tjtj||}tj|s]tjtj|d|}tj|sltd| dd| _|}||v rwq|| q|rdd |D | }||fS )aQ  
        @libs_in: PKG_CONFIG_ALLOW_SYSTEM_LIBS=1 pkg-config --libs
        @raw_libs_in: pkg-config --libs

        We always look for the file ourselves instead of depending on the
        compiler to find it with -lfoo or foo.lib (if possible) because:
        1. We want to be able to select static or shared
        2. We need the full path of the library to calculate RPATH values
        3. De-dup of libraries is easier when we have absolute paths

        Libraries that are provided by the toolchain or are not found by
        find_library() will be added with -L -l pairs.
        r   )z-L-lz-L-Lr	   Nr   r   z-l:   zJLibrary {!r} not found for dependency {!r}, may not be successfully linkedz-lF)lib_prefix_warningr   zOStatic library {!r} not found for dependency {!r}, may not be statically linkedz.laz.libszGot a libtools specific "zD" dependenciesbut we could not compute the actual sharedlibrary pathTc                 S  s   g | ]}d | qS )r   r/   )r   Zlpr/   r/   r0   r     s    z4PkgConfigDependency._search_libs.<locals>.<listcomp>) r   r   r   r   pathisabsrx   r   r   addr   r   r   r    r   r   listexistsr   r   r   rG   rw   clib_compilerfind_librarylibtyperO   endswithextract_libtool_shlibdirnamer   r   )r@   r   r   Zprefix_libpathsraw_link_argsr   r   r   Zsystem_libpathsZ	full_argslibpathsZ
libs_foundZlibs_notfoundr   libZlibfilenameZ	foundnamelibdirtargetr   Zshared_libname
shared_libr/   r/   r0   _search_libsm  s   














z PkgConfigDependency._search_libsc                 C  sD   | j j| j| jdd}| j j| j| jdd}| ||\| _| _d S )NT)rK   F)r   rP   rG   rO   r   r   r   )r@   rP   Zraw_libsr/   r/   r0   r     s   zPkgConfigDependency._set_libsla_file	fieldnamec                 C  sx   t |dd,}|D ] }| d}|d |kr)|d dd   W  d    S q	W d    d S 1 s5w   Y  d S )Nzutf-8)encodingrv   r   r   )openr   r   )r@   r   r   flinearrr/   r/   r0   extract_field  s   
z!PkgConfigDependency.extract_fieldc                 C     |  |dS )Ndlnamer   r@   r   r/   r/   r0   extract_dlname_field     z(PkgConfigDependency.extract_dlname_fieldc                 C  r   )Nr   r   r   r/   r/   r0   extract_libdir_field  r   z(PkgConfigDependency.extract_libdir_fieldc                 C  sd   |  |}|du rdS | jj| j  r,tj|}| |}|du r%|S tj	||S tj|S )z_
        Returns the path to the shared library
        corresponding to this .la file
        N)
r   r   r   r    	is_darwinr   r   basenamer   rx   )r@   r   r   Z
dlbasenamer   r/   r/   r0   r     s   

z)PkgConfigDependency.extract_libtool_shlibc                   C  s   dS )Nr   r/   r/   r/   r/   r0   	log_tried2  rF   zPkgConfigDependency.log_tried)cmaker   
configtoolinternaldefault_valuepkgconfig_definer  r   r  r  r  r  r   c                C  sV   |rz| j | j||}|d ur|W S W n	 ty   Y nw |d ur$|S td| )Nz>Could not get pkg-config variable and no default provided for )r   rR   rG   r   )r@   r  r   r  r  r  r  rR   r/   r/   r0   get_variable6  s   z PkgConfigDependency.get_variabler8   )
rG   rH   r   r   r   r   r   rI   r#   r?   )r#   rH   )r   rM   r#   ru   r   )r   rM   r   rM   r#   r   )r   rH   r   rH   r#   rI   )r   rH   r#   rI   )r  rI   r   rI   r  rI   r  rI   r  rI   r  r   r#   rH   )r]   r^   r_   rA   r   r   r   r   r   r   r   r   r   rb   r  r	  r   r/   r/   rn   r0   r     s&    
"


	 





r   )-
__future__r   pathlibr   baser   r   r   r   mesonlibr
   r   r   r   r   r   r   r   programsr   r    r   r   	functoolsr   r   r   r   typingr4   TYPE_CHECKINGZtyping_extensionsr   Z_typingr   r   r   Z
utils.corer   Zinterpreter.type_checkingr   r   r)   r   r/   r/   r/   r0   <module>   s,   (U #