ó
@K7]c           @` s?  d  d l  m Z m Z m Z d  d l Z d  d l Z d  d l Z d  d l m Z m	 Z	 m
 Z
 m Z m Z d  d l Z d  d l m Z d  d l m Z d  d l m Z d  d l m Z dK Z i d d 6d d 6d d 6d d 6d d 6Z i d d  6d! d" 6d# d$ 6d% d& 6d' d( 6d) d* 6d+ d, 6d- d. 6d/ d0 6d1 d2 6d3 d4 6Z d5 „  Z d6 „  Z d7 „  Z d8 „  Z d9 „  Z d: „  Z d; „  Z d< „  Z  d= „  Z! d e d> „ Z# d d? „ Z$ d d@ „ Z% dA „  Z& dB „  Z' d e( dC „ Z) d e( dD „ Z* e( dE „ Z+ e( dF „ Z, e- dG k r;e j. dH k r;x$ dL D] Z/ e0 e/ e e/ ƒ ƒ qWq;n  d S(M   i    (   t   absolute_importt   divisiont   print_functionN(   t   Popent   check_outputt   PIPEt   STDOUTt   CalledProcessError(   t   inspect_rpaths(   t   utils(   t   islice(   t#   find_preferably_prefixed_executables   .pys   .pycs   .pyos   .hs   .as   .cs   .txts   .htmls   .xmls   .pngs   .jpgs   .gifs   .classs   MachO-universals   Êþº¾s
   MachO-i386s   Îúíþs   MachO-x86_64s   Ïúíþs	   MachO-ppcs   þíúÎs   MachO-ppc64s   þíúÏt	   MH_OBJECTi   t
   MH_EXECUTEi   t	   MH_FVMLIBi   t   MH_COREi   t
   MH_PRELOADi   t   MH_DYLIBi   t   MH_DYLINKERi   t	   MH_BUNDLEi   t   MH_DYLIB_STUBi	   t   MH_DSYMi
   t   MH_KEXT_BUNDLEi   c         C` so   |  j  t ƒ s4 t j j |  ƒ s4 t j j |  ƒ r8 t St |  d ƒ  } | j d ƒ } Wd  QXt	 | t
 k ƒ S(   Nt   rbi   (   t   endswitht   NO_EXTt   ost   patht   islinkt   isfilet   Falset   opent   readt   boolt   MAGIC(   R   t   fit   head(    (    s9   lib/python2.7/site-packages/conda_build/os_utils/macho.pyt   is_macho)   s
    4c         C` s   t  |  ƒ d k S(   Nt   DYLIB(   t   human_filetype(   R   (    (    s9   lib/python2.7/site-packages/conda_build/os_utils/macho.pyt   is_dylib1   s    c         C` sá   t  d ƒ } t | d |  f ƒ j d ƒ } | j ƒ  } | d j |  d f ƒ sj t d j |  | ƒ ƒ ‚ n  | d j |  d f ƒ s t |  ƒ ‚ xK | D]C } | j ƒ  j d ƒ r– | j	 ƒ  } t
 | d ƒ } t | d	 Sq– Wd  S(
   Nt   otools   -hs   utf-8i    s   Mach headersE   Expected `otool -h` output to start with Mach header or {0}, got:
{1}t   0xi   i   (   R   R   t   decodet
   splitlinest
   startswitht
   ValueErrort   formatt   AssertionErrort   stript   splitt   intt   FILETYPE(   R   t   ott   outputt   linest   linet   headert   filetype(    (    s9   lib/python2.7/site-packages/conda_build/os_utils/macho.pyR'   5   s    %c         C` s:   d } t  |  ƒ d k r6 |  d j ƒ  d | k r6 t St S(   Nt   LC_ID_DYLIBt   LC_LOAD_DYLIBi   (   R;   R<   (   t   lenR2   t   TrueR   (   R7   t
   dylib_info(    (    s9   lib/python2.7/site-packages/conda_build/os_utils/macho.pyt   is_dylib_infoG   s    ,c         C` s4   t  |  ƒ d k r0 |  d j ƒ  d d k r0 t St S(   Ni   R;   (   R=   R2   R>   R   (   R7   (    (    s9   lib/python2.7/site-packages/conda_build/os_utils/macho.pyt   is_id_dylibN   s    ,c         C` s4   t  |  ƒ d k r0 |  d j ƒ  d d k r0 t St S(   Ni   R<   (   R=   R2   R>   R   (   R7   (    (    s9   lib/python2.7/site-packages/conda_build/os_utils/macho.pyt   is_load_dylibT   s    ,c         C` s4   t  |  ƒ d k r0 |  d j ƒ  d d k r0 t St S(   Ni   t   LC_RPATH(   R=   R2   R>   R   (   R7   (    (    s9   lib/python2.7/site-packages/conda_build/os_utils/macho.pyt   is_rpathZ   s    ,c         c` sc   d } xM t  |  ƒ D]? \ } } | j d ƒ r | | k  rI |  | | !Vn  | } q q W|  | Vd S(   s4   yields each load command from the output of otool -li   s   Load commandN(   t	   enumerateR-   (   R7   t   at   lnR8   (    (    s9   lib/python2.7/site-packages/conda_build/os_utils/macho.pyt   _get_load_commands`   s    c   	      C` s¥  g  } x˜t  |  ƒ D]Š} | | ƒ r i  } x_t | d t | ƒ ƒ D]E} | j ƒ  } t | ƒ d k rw | \ } } nä | d d k s— | d d k rì | d d k rÖ | d d } t | d d	  ƒ } | | | <n  | d d !\ } } no | d d
 k r(d j | d d !ƒ } d j | d ƒ } n3 | d d k r[d j | d d !ƒ } | d } n  y t | ƒ } Wn t k
 r~n X| | | <qD W| j | ƒ q q W| S(   s  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.
    i   i   i    t   nameR   s   (offsets    offseti   iÿÿÿÿt   timet    t   currentt   compatibility(   RL   RM   (   RH   R
   R=   R2   R3   t   joinR.   t   append(	   R7   t	   cb_filtert   resultt   lcmdst   lcdictR8   t   listyt   keyt   value(    (    s9   lib/python2.7/site-packages/conda_build/os_utils/macho.pyt   _get_matching_load_commandsk   s6     c         C` sy   t  t d | ƒ d |  g d t ƒj d ƒ } | j ƒ  } t | ƒ d k  rl t j d | t j ƒ rl t	 ‚ n  t
 | | ƒ S(   s€  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.
    R)   s   -lt   stderrs   utf-8i
   s1   .*(is not a Mach-O|invalid|expected|unexpected).*(   R   R   R   R+   R,   R=   t   ret   matcht	   MULTILINER   RW   (   R   t   build_prefixRP   R7   t   lines_split(    (    s9   lib/python2.7/site-packages/conda_build/os_utils/macho.pyR)   •   s    	c         C` s-   t  |  | t ƒ } g  | D] } | d ^ q S(   s+   Return a list of the loaded dylib pathnamesRI   (   R)   RB   (   R   R\   t   dylib_loadst
   dylib_load(    (    s9   lib/python2.7/site-packages/conda_build/os_utils/macho.pyt
   get_dylibs²   s    c         C` sD   t  |  | t ƒ } y# g  | D] } | d ^ q d SWn d SXd S(   s@   Returns the id name of the Mach-O file `path` or an empty stringRI   i    t    N(   R)   RA   (   R   R\   R^   R_   (    (    s9   lib/python2.7/site-packages/conda_build/os_utils/macho.pyt   get_id¸   s
    #c         C` s   t  |  d t d t ƒ} | S(   s!   Return a list of the dylib rpathst   resolve_dirnamest   use_os_varnames(   R   R   R>   (   R   t	   res_pyldd(    (    s9   lib/python2.7/site-packages/conda_build/os_utils/macho.pyt
   get_rpathsÁ   s    c         C` sY   y t  j |  | ƒ Wn> t t j f k
 rT } t j t ƒ } | j t | ƒ ƒ n Xd  S(   N(	   R   t   chmodt   OSErrorR	   t   PermissionErrort
   get_loggert   __name__t   warnt   str(   t   filenamet   modet   et   log(    (    s9   lib/python2.7/site-packages/conda_build/os_utils/macho.pyt   _chmodÇ   s
    c   	      C` sÿ   t  d | ƒ g } | j |  ƒ | r; t d j | ƒ ƒ n  t j t j |  d ƒ j ƒ } | t j B} | | k r‡ t	 |  d | ƒ n  t
 | d t d t ƒ} | j ƒ  \ } } | j d ƒ } | j d ƒ } | | k rï t	 |  d | ƒ n  | j | | f S(   Nt   install_name_toolRK   iÿÿÿÿt   stdoutRX   s   utf-8(   R   t   extendt   printRN   t   statt   S_IMODER   t   st_modet   S_IWUSRRr   R   R   t   communicateR+   t
   returncode(	   t   argsR\   t   verboset	   args_fullt   old_modet   new_modet   subproct   outt   err(    (    s9   lib/python2.7/site-packages/conda_build/os_utils/macho.pyRs   Ï   s    c         C` s   d | |  g } t  | | ƒ \ } } } d | k rE t d |  ƒ d Sd | k r_ t d ƒ d St | d t j ƒ| r‹ t d | ƒ ‚ n  d S(	   s+   Add an `rpath` to the Mach-O file at `path`s
   -add_rpaths'   Mach-O dynamic shared library stub files4   Skipping Mach-O dynamic shared library stub file %s
Ns4   would duplicate path, file already has LC_RPATH for:s2   Skipping -add_rpath, file already has LC_RPATH sett   files,   install_name_tool failed with exit status %d(   Rs   Rv   t   sysRX   t   RuntimeError(   R   t   rpathR\   R~   R}   t   codet   _RX   (    (    s9   lib/python2.7/site-packages/conda_build/os_utils/macho.pyt	   add_rpathá   s    
c         C` sŒ   d | |  g } t  | ƒ \ } } } d | k rB t d |  ƒ d Sd | k r\ t d ƒ d St | d t j ƒ| rˆ t d | ƒ ‚ n  d S(	   s0   Delete an `rpath` from the Mach-O file at `path`s   -delete_rpaths'   Mach-O dynamic shared library stub files4   Skipping Mach-O dynamic shared library stub file %s
Ns#   no LC_RPATH load command with path:s:   Skipping -delete_rpath, file doesn't contain that LC_RPATHR…   s,   install_name_tool failed with exit status %d(   Rs   Rv   R†   RX   R‡   (   R   Rˆ   R~   R}   R‰   RŠ   RX   (    (    s9   lib/python2.7/site-packages/conda_build/os_utils/macho.pyt   delete_rpathò   s    
c         C` s3  g  } xE t  | ƒ D]7 \ } } | |  | ƒ } | r | j | | f ƒ q q Wt }	 xØ | D]Ð \ } } g  }
 | | d d k rš |
 j d | |  f ƒ n! |
 j d | | d | |  f ƒ t |
 | ƒ \ } } } d | k rù t d |  ƒ t }	 q[ n t | d t j ƒ| r[ t	 d	 | | f ƒ ‚ q[ q[ W|	 S(
   s¯  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   cmdR;   s   -ids   -changeRI   s'   Mach-O dynamic shared library stub files3   Skipping Mach-O dynamic shared library stub file %sR…   s;   install_name_tool failed with exit status %d, stderr of:
%s(
   RE   RO   R>   Ru   Rs   Rv   R   R†   RX   R‡   (   R   R\   t   cb_funct   dylibsR~   t   changest   indext   dylibt   new_namet   retR}   R‰   RŠ   RX   (    (    s9   lib/python2.7/site-packages/conda_build/os_utils/macho.pyt   install_name_change  s*    !t   __main__t   darwins   /bin/lss   /etc/locate.rc(   s   .pys   .pycs   .pyos   .hs   .as   .cs   .txts   .htmls   .xmls   .pngs   .jpgs   .gifs   .class(   s   /bin/lss   /etc/locate.rc(1   t
   __future__R    R   R   RY   Rw   R†   t
   subprocessR   R   R   R   R   R   t   conda_build.os_utils.pylddR   t   conda_buildR	   t	   itertoolsR
   t   conda_build.os_utils.externalR   R   R"   R4   R%   R(   R'   R@   RA   RB   RD   RH   RW   t   NoneR)   R`   Rb   Rf   Rr   R   Rs   R‹   RŒ   R•   Rk   t   platformR   Rv   (    (    (    s9   lib/python2.7/site-packages/conda_build/os_utils/macho.pyt   <module>   sf   ( 

									*			%