
    xhe%/                     v   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mZm	Z	m
Z
mZ ddlmZ ddlmZ ddlmZ d	Zd
dddddZddddddddddddZd Zd Zd Zd Zd  Zd! Zd" Zd# Zd$ Zd2d&Zdefd'Zd3d(Zd3d)Z d3d*Z!d+ Z"d4d,Z#d4d-Z$d4d.Z%d2d/Z&e'd0k    rerd1D ]Z( e)e( ee(                     dS dS dS )5    N)islice)PIPESTDOUTCalledProcessErrorPopencheck_output   )utils)on_mac   )#find_preferably_prefixed_executable)z.pyz.pycz.pyoz.hz.az.cz.txtz.htmlz.xmlz.pngz.jpgz.gifz.classz.inz.shz.yamlz.mdz.acz.m4z.ccz.plistzMachO-universalz
MachO-i386zMachO-x86_64z	MachO-ppczMachO-ppc64)s   s   s   s   s   	MH_OBJECT
MH_EXECUTE	MH_FVMLIBMH_CORE
MH_PRELOADMH_DYLIBMH_DYLINKER	MH_BUNDLEMH_DYLIB_STUBMH_DSYMMH_KEXT_BUNDLE)r   r	                     	   
      c                 \   |                      t                    s>t          j                            |           st          j                            |           sdS t          | d          5 }|                    d          }d d d            n# 1 swxY w Y   t          |t          v           S )NFrbr   )
endswithNO_EXTospathislinkisfileopenreadboolMAGIC)r'   fiheads      :lib/python3.11/site-packages/conda_build/os_utils/macho.pyis_machor1   =   s    }}V t 4 4 BGNN4<P<P u	dD		 Rwwqzz              s   +BBBc                 (    t          |           dk    S )NDYLIB)human_filetype)r'   build_prefixs     r0   is_dylibr6   E   s    $7**    c                 "   t          d|          }t          |d| f                              d          }|                                }|d                             | df          st          d|  d|           |d                             | df          s
J |             |D ]i}|                                                    d          r@|                                }t          |d	                   }t          |         d
d          c S jd S )Notoolz-hutf-8r   zMach headerz8Expected `otool -h` output to start with Mach header or z, got:
0xr   r   )
find_apple_cctools_executabler   decode
splitlines
startswith
ValueErrorstripsplitintFILETYPE)r'   r5   r9   outputlineslineheaderfiletypes           r0   r4   r4   I   s3   )'<@@E5$-..55g>>FE8m455 
6#6 6-36 6
 
 	
 8m455;;t;;; * *::<<""4(( 	*ZZ\\F6!9~~HH%abb))))	** *r7   c                 x    d}t          |           dk    r$| d                                         d         |v rdS dS )N)LC_ID_DYLIBLC_LOAD_DYLIBr   TFlenrB   )rF   
dylib_infos     r0   is_dylib_inforP   [   s=    1J
5zzA~~%(..**1-;;t5r7   c                 x    t          |           dk    r&| d                                         d         dk    rdS dS )Nr   rK   TFrM   rF   s    r0   is_id_dylibrS   b   s8    
5zzA~~%(..**1->>t5r7   c                 x    t          |           dk    r&| d                                         d         dk    rdS dS )Nr   rL   TFrM   rR   s    r0   is_load_dylibrU   h   s8    
5zzA~~%(..**1-@@t5r7   c                 x    t          |           dk    r&| d                                         d         dk    rdS dS )Nr   LC_RPATHTFrM   rR   s    r0   is_rpathrX   n   s8    
5zzA~~%(..**1-;;t5r7   c              #      K   d}t          |           D ].\  }}|                    d          r||k     r| ||         V  |}/| |d         V  dS )z4yields each load command from the output of otool -lr   zLoad commandN)	enumerater?   )rF   alnrG   s       r0   _get_load_commandsr]   t   sr      	Ae$$  D??>** 	2vvAbDk!!!A
)OOOOOr7   c                    g }t          |           D ]q} ||          rbi }t          |dt          |                    D ]+}|                                }t          |          dk    r|\  }}n|d         dk    s|d         dk    rG|d         dk    r-|d         dz   }t	          |d         d	d
                   }|||<   |dd         \  }}nv|d         dk    r;d                    |dd                   }d                    |dd	                   }n/|d         dv r%d                    |dd                   }|d         }	 t	          |          }n# t          $ r Y nw xY w|||<   -|                    |           s|S )a  Workhorse function for otool

    Does the work of filtering load commands and making a list
    of dicts. The logic for splitting the free-form lines into
    keys and values in entirely encoded here. Values that can
    be converted to ints are converted to ints.
    r   r	   r   namer'   z(offsetz offsetr   Ntime )currentcompatibility)r]   r   rN   rB   rC   joinr@   append)	rF   	cb_filterresultlcmdslcdictrG   listykeyvalues	            r0   _get_matching_load_commandsrn      s    F#E** " "9U 	"FuaU44 $ $

 u::??!&JC1X''58v+=+= Qx9,,#Ah2 #E!HSbSM 2 2&+s!&qsJC1X''((51:..CHHU122Y//EE1X!===((51:..C!!HEJJEE!   D#sMM&!!!Ms   E
E$#E$Fc                    t          | |d          }|D ]f}	 d|v rt          |d          5 }|                                }d d d            n# 1 swxY w Y   |                    d          dk    r	 t	          dd| gt
          	                              d
                                          d         }nM# t          $ r@}t          j
        t                    }	|	                    d| d|j                    |d }~ww xY w|}t          j                            |          r|c S nM# t          $ r@}
t#          d                    |                     t'          j        d           Y d }
~
nd }
~
ww xY w|c S d S )NT)all_matchesz/usr/binr#   s   usr/lib/libxcselect.dylibr`   xcrunz-findstderrr:   r   zERROR :: Found `zE` but is is an Apple Xcode stub executable
and it returned an error:
zERROR :: Failed to run `{}`.  Please use `conda` to install `cctools` into your base environment.
         An option on macOS is to install `Xcode` or `Command Line Tools for Xcode`.r   )r   r*   r+   findr   r   r=   r>   	Exceptionr
   
get_logger__name__errorrE   r&   r'   existsprintformatsysexit)r_   r5   nofailtoolstoolfstool_xcrelog_s              r0   r<   r<      s   /lPTUUUE  	T!!$%% !A! ! ! ! ! ! ! ! ! ! ! ! ! ! !666772== ('7D)A&QQQ#VG__'Z\\!- !
 %      #.x88		Et E E:;(E E      $Dw~~d++ $# 	 	 	ggmgmh h   HQKKKKKKKK	 ? s_   D,AD,A	D,A	D,4AB98D,9
D;C>>D%D,,
E666E11E6c                 H   t          d|          }t          |d| gt                                        d          }|                                }t          |          dk     r0t          j        d|t          j                  rt          d|          t          ||          S )a  A wrapper around otool -l

    Parse the output of the otool -l 'load commands', filtered by
    cb_filter, returning a list of dictionairies for the records.

    cb_filter receives the whole load command record, including the
    first line, the 'Load Command N' one. All the records have been
    pre-stripped of white space.

    The output of otool -l is entirely freeform; delineation between
    key and value doesn't formally exist, so that is hard coded. I
    didn't want to use regexes to parse it for speed purposes.

    Any key values that can be converted to integers are converted
    to integers, the rest are strings.
    r9   z-lrr   r:   r    z1.*(is not a Mach-O|invalid|expected|unexpected).*r`   )r<   r   r   r=   r>   rN   rematch	MULTILINEr   rn   )r'   r5   rg   r9   rF   lines_splits         r0   r9   r9      s    " *'<@@E%t,V<<<CCGLLE""$$K ;"
?	
 	
 
 !U+++&{I>>>r7   c                 F    t          | |t                    }d |D             S )z+Return a list of the loaded dylib pathnamesc                     g | ]
}|d          S r_    .0
dylib_loads     r0   
<listcomp>zget_dylibs.<locals>.<listcomp>       ===:Jv===r7   )r9   rU   r'   r5   dylib_loadss      r0   
get_dylibsr      s'    lM::K======r7   c                 d    t          | |t                    }	 d |D             d         S #  Y dS xY w)z@Returns the id name of the Mach-O file `path` or an empty stringc                     g | ]
}|d          S r   r   r   s     r0   r   zget_id.<locals>.<listcomp>   s    AAAz
6"AAAr7   r    )r9   rS   r   s      r0   get_idr      sA    lK88KAA[AAA!DDrrs   * /c                 F    t          | |t                    }d |D             S )z!Return a list of the dylib rpathsc                     g | ]
}|d          S )r'   r   r   s     r0   r   zget_rpaths.<locals>.<listcomp>   r   r7   )r9   rX   r   s      r0   
get_rpathsr      s'    lH55K======r7   c                     	 t          j        | |           d S # t          t          j        f$ rF}t          j        t                    }|                    t          |                     Y d }~d S d }~ww xY wN)	r&   chmodOSErrorr
   PermissionErrorrv   rw   warnstr)filenamemoder   r   s       r0   _chmodr     s    
4     U*+   x((Qs    A5;A00A5c                 T   t          d|          g}|                    |            |r"t          d                    |                     t	          j        t          j        | d                   j                  }|t          j        z  }||k    rt          | d         |           t          |t          t                    }|                                \  }}|                    d          }|                    d          }||k    rt          | d         |           |j        ||fS )Ninstall_name_toolrb   r`   )stdoutrs   r:   )r<   extendrz   re   statS_IMODEr&   st_modeS_IWUSRr   r   r   communicater=   
returncode)	argsr5   verbose	args_fullold_modenew_modesubprocouterrs	            r0   r   r   
  s   ./BLQQRIT #chhy!!"""|BGDH--566H$,&H8tBx"""Id4888G""$$HC
**W

C
**W

C8tBx"""sC''r7   c                    t          |           sdS d|| g}t          ||          \  }}}d|v rt          d| z             dS d|v rt          d           dS t          |t          j                   |rt          d|z            dS )	z+Add an `rpath` to the Mach-O file at `path`Nz
-add_rpath'Mach-O dynamic shared library stub file4Skipping Mach-O dynamic shared library stub file %s
z4would duplicate path, file already has LC_RPATH for:z2Skipping -add_rpath, file already has LC_RPATH setfile,install_name_tool failed with exit status %dr1   r   rz   r|   rs   RuntimeErrorr'   rpathr5   r   r   coder   rs   s           r0   	add_rpathr     s    D>> %&D'l;;OD!V0F::ELMMM	?6	I	IBCCCf3:&&&& 	VMPTTUUU	V 	Vr7   c                    t          |           sdS d|| g}t          ||          \  }}}d|v rt          d| z             dS d|v rt          d           dS t          |t          j                   |rt          d|z            dS )	z0Delete an `rpath` from the Mach-O file at `path`Nz-delete_rpathr   r   z#no LC_RPATH load command with path:z:Skipping -delete_rpath, file doesn't contain that LC_RPATHr   r   r   r   s           r0   delete_rpathr   .  s    D>> UD)D'l;;OD!V0F::ELMMM	.&	8	8JKKKf3:&&&& 	VMPTTUUU	V 	Vr7   c                    g }t          |          D ]*\  }} || |          }|r|                    ||f           +d}	|D ]\  }}g }
||         d         dk    r|
                    d|| f           n%|
                    d||         d         || f           t          |
|          \  }}}d|v rt	          d| z             d	}	t	          |t
          j        
           |rt          d||fz            |	S )a  Change dynamic shared library load name or id name of Mach-O Binary `path`.

    `cb_func` is called for each shared library load command. The dictionary of
    the load command is passed in and the callback returns the new name or None
    if the name should be unchanged.

    When dealing with id load commands, `install_name_tool -id` is used.
    When dealing with dylib load commands `install_name_tool -change` is used.
    TcmdrK   z-idz-changer_   r   z3Skipping Mach-O dynamic shared library stub file %sFr   z;install_name_tool failed with exit status %d, stderr of:
%s)rZ   rf   r   r   rz   r|   rs   r   )r'   r5   cb_funcdylibsr   changesindexdylibnew_nameretr   r   r   rs   s                 r0   install_name_changer   @  sL    G!&)) . .u74'' 	.NNE8,---
C"  x%==00KK$/0000KKF5M&$98TJKKK+D,??a4>>G$NOOOC&sz**** 	N.!  	
 Jr7   __main__)z/bin/lsz/etc/locate.rc)Fr   )NF)*r&   r   r   r|   	itertoolsr   
subprocessr   r   r   r   r   r   r
   r   externalr   r%   r-   rD   r1   r6   r4   rP   rS   rU   rX   r]   rn   r<   r9   r   r   r   r   r   r   r   r   rw   r'   rz   r   r7   r0   <module>r      s   
			 				  



       L L L L L L L L L L L L L L             9 9 9 9 9 9
2 +%'$&	 	    + + +* * *$          ' ' 'T! ! ! !H "] ? ? ? ?@> > > >   > > > >  ( ( ( ($V V V V$V V V V$$ $ $ $N z (/ 	( 	(DE$'''' ( (	( 	(r7   