B
    b#                @   sX  d Z ddlZddlZddlZddlZddlZddlmZ ddlZ	ddl
Z	ddlZ	ddlmZ ddlZ	ddlmZmZ ddlZ	ddlZ	ddlZ	ddlZ	ddlZ	ddlZ	ddlZ	ddl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!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z+m,Z,m-Z- G dd dZ.e.Z/d	Z0d	Z1d	Z2i a3i Z4d
d Z5e	j6j6e5e	j7j8j9j8e	j7j:j;d	dddZ<dd Z=ddddddddgZ>g Z?dd Z@dd ZAdd ZBdd ZCd d! ZDd"d# ZEd$d% ZFG d&d' d'e ZGG d(d) d)eZHeId*ZJd+d, ZKG d-d. d.ZLd=d/d0ZMd>d1d2ZNd3d4 ZOd5d6 ZPG d7d8 d8eLZQG d9d: d:eQZReQZSd;d< ZTdS )?a"  Base class for construction Environments.

These are the primary objects used to communicate dependency and
construction information to the build engine.

Keyword arguments supplied when the construction Environment is created
are construction variables used to initialize the Environment.
    N)UserDict)logInstanceCreation)	UserError
BuildError)
AppendPathCLVarLogicalLinesMethodWrapperPrependPathSplitWhereIsflattenis_Dictis_Listis_Sequence	is_Stringis_Tuplesemi_deepcopysemi_deepcopy_dictto_String_for_substuniquer_hashablesc               @   s   e Zd ZdS )_NullN)__name__
__module____qualname__ r   r   0lib/python3.7/site-packages/SCons/Environment.pyr   M   s   r   Tc             C   s   d S )Nr   )envtargetsourcer   r   r   alias_builderY   s    r    AliasBuilder)actiontarget_factorysource_factorymultiis_explicitnamec             C   sh   |d k	r|| d< |sd S xJdd |D D ]8}t |s<t|rV|^}}}| j|f|}q(| |}q(W d S )Ntoolpathc             S   s   g | ]}|r|qS r   r   ).0_fr   r   r   
<listcomp>n   s    zapply_tools.<locals>.<listcomp>)r   r   Tool)r   toolsr(   toolZtoolnameZtoolargsrest_r   r   r   apply_toolse   s    
r1   ZCHANGED_SOURCESZCHANGED_TARGETSZSOURCEZSOURCESZTARGETZTARGETSZUNCHANGED_SOURCESZUNCHANGED_TARGETSc             C   sJ   t | }x<|  D ],}|tkrd}tjtjj||  ||= qW |S )Nz/Ignoring attempt to set reserved variable `$%s')r   copykeysreserved_construction_var_namesSConsWarningswarnReservedVariableWarning)dictresultkmsgr   r   r   copy_non_reserved_keywords   s    
r=   c             C   s   d}t jt jj||  d S )Nz/Ignoring attempt to set reserved variable `$%s')r5   r6   r7   r8   )r   keyvaluer<   r   r   r   _set_reserved   s    r@   c             C   s(   || j |< d}tjtjj||  d S )NzM`$%s' will be reserved in a future release and setting it will become ignored)_dictr5   r6   r7   ZFutureReservedVariableWarning)r   r>   r?   r<   r   r   r   _set_future_reserved   s    
rB   c             C   s   y*| j | }x|  D ]
}||= qW W n( tk
rR   t|| }|| j |< Y nX x0| D ]$\}}tj|s^t	dt
| q^W || d S )Nz%s is not a Builder.)rA   r2   r3   KeyErrorBuilderDictitemsr5   BuilderZis_a_Builderr   reprupdate)r   r>   r?   Zbdr;   vr   r   r   _set_BUILDERS   s    

rJ   c             C   s   | j |= |   d S )N)rA   scanner_map_delete)r   r>   r   r   r   _del_SCANNERS   s    rL   c             C   s   || j |< |   d S )N)rA   rK   )r   r>   r?   r   r   r   _set_SCANNERS   s    
rM   c          	   C   st   t  }g }|r|   xL| D ]D}y ||kr>|| || W q tk
r^   || Y qX qW |rp|  |S )z=Delete duplicates from a sequence, keeping the first or last.)setreverseappendadd	TypeError)lZ	keep_lastseenr:   ir   r   r   _delete_duplicates   s    

rV   c                   sF   e Zd ZdZdef fdd	Zdd Zdd Zd	d
 Zdd Z	  Z
S )BuilderWrappera  
    A MethodWrapper subclass that that associates an environment with
    a Builder.

    This mainly exists to wrap the __call__() function so that all calls
    to Builders can have their argument lists massaged in the same way
    (treat a lone argument as the source, treat two arguments as target
    then source, make sure both target and source are lists) without
    having to have cut-and-paste code to do it.

    As a bit of obsessive backwards compatibility, we also intercept
    attempts to get or set the "env" or "builder" attributes, which were
    the names we used before we put the common functionality into the
    MethodWrapper base class.  We'll keep this around for a while in case
    people shipped Tool modules that reached into the wrapper (like the
    Tool/qt.py module does, or did).  There shouldn't be a lot attribute
    fetching or setting on these, so a little extra work shouldn't hurt.
    Nc                sR   |t kr|}d }|d k	r&t|s&|g}|d k	r<t|s<|g}t j||f||S )N)_nullr   super__call__)selfr   r   argskw)	__class__r   r   rZ      s    zBuilderWrapper.__call__c             C   s   dt | j S )Nz<BuilderWrapper %s>)rG   r'   )r[   r   r   r   __repr__   s    zBuilderWrapper.__repr__c             C   s   |   S )N)r_   )r[   r   r   r   __str__   s    zBuilderWrapper.__str__c             C   s(   |dkr| j S |dkr| jS t|d S )Nr   builder)objectmethodAttributeError)r[   r'   r   r   r   __getattr__   s
    zBuilderWrapper.__getattr__c             C   s.   |dkr|| _ n|dkr || _n
|| j|< d S )Nr   ra   )rb   rc   __dict__)r[   r'   r?   r   r   r   __setattr__   s
    zBuilderWrapper.__setattr__)r   r   r   __doc__rX   rZ   r_   r`   re   rg   __classcell__r   r   )r^   r   rW      s   
rW   c                   sH   e Zd ZdZ fddZdd Z fddZ fdd	Zd
d Z  Z	S )rD   zThis is a dictionary-like class used by an Environment to hold
    the Builders.  We need to do this because every time someone changes
    the Builders in the Environment's BUILDERS dictionary, we must
    update the Environment's attributes.c                s   || _ t | d S )N)r   rY   __init__)r[   mappingr   )r^   r   r   rj     s    zBuilderDict.__init__c             C   s   t dd S )Nz"cannot semi_deepcopy a BuilderDict)rR   )r[   r   r   r   __semi_deepcopy__  s    zBuilderDict.__semi_deepcopy__c                sT   yt | j|j}W n tk
r&   Y nX | j| t || t| j|| d S )N)getattrr   rc   rd   RemoveMethodrY   __setitem__rW   )r[   itemvalrc   )r^   r   r   ro   "  s    zBuilderDict.__setitem__c                s   t  | t| j| d S )N)rY   __delitem__delattrr   )r[   rp   )r^   r   r   rr   ,  s    zBuilderDict.__delitem__c             C   s&   x |  D ]\}}| || q
W d S )N)rE   ro   )r[   rk   rU   rI   r   r   r   rH   0  s    zBuilderDict.update)
r   r   r   rh   rj   rl   ro   rr   rH   ri   r   r   )r^   r   rD     s   
rD   z[_a-zA-Z]\w*$c             C   s
   t | S )zNReturn if the specified string is a legitimate construction
    variable.
    )_is_valid_varmatch)Zvarstrr   r   r   is_valid_construction_var8  s    rv   c               @   s  e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	d8ddZ
dd Zdd Zdd Zdd Zd9ddZeefddZdd Zdd  Zd:d"d#Zd;d$d%Zd<d&d'Zd=d(d)ZeZed*d+d,Zd>d-d.Zd/d0 Zd1d2 Zed*d3d4Zd?dd*d6d7Z dS )@SubstitutionEnvironmentae  Base class for different flavors of construction environments.

    This class contains a minimal set of methods that handle construction
    variable expansion and conversion of strings to Nodes, which may or
    may not be actually useful as a stand-alone class.  Which methods
    ended up in this class is pretty arbitrary right now.  They're
    basically the ones which we've empirically determined are common to
    the different construction environment subclasses, and most of the
    others that use or touch the underlying dictionary of construction
    variables.

    Eventually, this class should contain all the methods that we
    determine are necessary for a "minimal" interface to the build engine.
    A full "native Python" SCons environment has gotten pretty heavyweight
    with all of the methods and Tools and construction variables we've
    jammed in there, so it would be nice to have a lighter weight
    alternative for interfaces that don't need all of the bells and
    whistles.  (At some point, we'll also probably rename this class
    "Base," since that more reflects what we want this class to become,
    but because we've released comments that tell people to subclass
    Environment.Base to create their own flavors of construction
    environment, we'll save that for a future refactoring when this
    class actually becomes useful.)
    c             K   sR   t jjrt| d t jj | _t jjj	| _
t jj| _| | _|   g | _dS )zGInitialization of an underlying SubstitutionEnvironment class.
        z#Environment.SubstitutionEnvironmentN)r5   Debugtrack_instancesr   NodeFSget_default_fsfsAliasdefault_ansansarg2nodes_lookupslookup_listr2   rA   _init_specialadded_methods)r[   r]   r   r   r   rj   Z  s     


z SubstitutionEnvironment.__init__c             C   sn   i | _ t| j d< i | _xtD ]}t| j|< qW xtD ]}t| j|< q4W t| jd< t| jd< t	| j
 | _dS )z[Initial the dispatch tables for special handling of
        special construction variables.SCANNERSBUILDERSN)_special_delrL   _special_setr4   r@   &future_reserved_construction_var_namesrB   rJ   rM   listr3   _special_set_keys)r[   r>   r   r   r   r   f  s    




z%SubstitutionEnvironment._init_specialc             C   s   | j |j kS )N)rA   )r[   otherr   r   r   __eq__x  s    zSubstitutionEnvironment.__eq__c             C   s(   | j |}|r|| | n| j|= d S )N)r   getrA   )r[   r>   Zspecialr   r   r   rr   {  s    z#SubstitutionEnvironment.__delitem__c             C   s
   | j | S )N)rA   )r[   r>   r   r   r   __getitem__  s    z#SubstitutionEnvironment.__getitem__c             C   sL   || j kr| j| | || n*|| jkr>t|s>td| || j|< d S )Nz"Illegal construction variable `%s')r   r   rA   rt   ru   r   )r[   r>   r?   r   r   r   ro     s
    
z#SubstitutionEnvironment.__setitem__Nc             C   s   | j ||S )z*Emulates the get() method of dictionaries.)rA   r   )r[   r>   defaultr   r   r   r     s    zSubstitutionEnvironment.getc             C   s
   || j kS )N)rA   )r[   r>   r   r   r   __contains__  s    z$SubstitutionEnvironment.__contains__c             C   s
   | j  S )z+Emulates the keys() method of dictionaries.)rA   r3   )r[   r   r   r   r3     s    zSubstitutionEnvironment.keysc             C   s
   | j  S )z-Emulates the values() method of dictionaries.)rA   values)r[   r   r   r   r     s    zSubstitutionEnvironment.valuesc             C   s
   | j  S )z,Emulates the items() method of dictionaries.)rA   rE   )r[   r   r   r   rE     s    zSubstitutionEnvironment.itemsc             C   s   | j ||S )z1Emulates the setdefault() method of dictionaries.)rA   
setdefault)r[   r>   r   r   r   r   r     s    z"SubstitutionEnvironment.setdefaultc       	      K   s
  |t kr| jj}|t kr| j}|s&g S t|}g }x|D ]}t|rd }x|D ]}||}|d k	rNP qNW |d k	rt|rd|d< | j|f|}|r||}t|r|| q|	| n<|rd|d< || j|f|}t|r|| n
|	| q8|	| q8W |S )N   raw)
rX   r}   Filer   r   r   substr   extendrP   )	r[   r\   Znode_factoryr   r]   nodesrI   nrS   r   r   r   	arg2nodes  s@    

z!SubstitutionEnvironment.arg2nodesc             C   s   | j S )N)rA   )r[   r   r   r   gvars  s    zSubstitutionEnvironment.gvarsc             C   s   i S )Nr   )r[   r   r   r   lvars  s    zSubstitutionEnvironment.lvarsr   c       	   
   C   sD   |   }|  }| |d< |r*||  tj|| ||||||S )a  Recursively interpolates construction variables from the
        Environment into the specified string, returning the expanded
        result.  Construction variables are specified by a $ prefix
        in the string and begin with an initial underscore or
        alphabetic character followed by any number of underscores
        or alphanumeric characters.  The construction variable names
        may be surrounded by curly braces to separate the name from
        trailing characters.
        __env__)r   r   rH   	get_lvarsr5   Substscons_subst)	r[   stringr   r   r   convexecutorr   r   r   r   r   r     s    
zSubstitutionEnvironment.substc             C   sN   i }xD|  D ]8\}}| ||||}t|r>| ||||}|||< qW |S )N)rE   r   r   )r[   r]   r   r   r   nkwr;   rI   r   r   r   subst_kw  s    z SubstitutionEnvironment.subst_kwc       	   
   C   sD   |   }|  }| |d< |r*||  tj|| ||||||S )zbCalls through to SCons.Subst.scons_subst_list().  See
        the documentation for that function.r   )r   r   rH   r   r5   r   scons_subst_list)	r[   r   r   r   r   r   r   r   r   r   r   r   
subst_list  s    z"SubstitutionEnvironment.subst_listc             C   s   t |s|g}dd }g }xh|D ]`}t|rn| j||||d}t |rvt|dkr\|d }qvdtt|}n||}|| q W |S )zlSubstitute a path list, turning EntryProxies into Nodes
        and leaving Nodes (and other objects) as-is.c             S   s2   y
| j }W n tk
r&   t| } Y nX | } | S )a  This is the "string conversion" routine that we have our
            substitutions use to return Nodes, not strings.  This relies
            on the fact that an EntryProxy object has a get() method that
            returns the underlying Node that it wraps, which is a bit of
            architectural dependence that we might need to break or modify
            in the future in response to additional requirements.)r   rd   r   )objr   r   r   r   s  s    
z-SubstitutionEnvironment.subst_path.<locals>.s)r   r   r   r   r    )r   r   r   lenjoinmapr   rP   )r[   pathr   r   r   rpr   r   r   
subst_path  s    

z"SubstitutionEnvironment.subst_path)returnc             C   s|   ddl }d|j|jdd}t|s*d|d< tjj| |f|}| \}}| }|rdtj	
d|  |rxtd||f |S )	a  Emulate command substitution.

        Provides behavior conceptually like POSIX Shell notation
        for running a command in backquotes (backticks) by running
        ``command`` and returning the resulting output string.

        This is not really a public API any longer, it is provided for the
        use of :meth:`ParseFlags` (which supports it using a syntax of
        !command) and :meth:`ParseConfig`.

        Raises:
            OSError: if the external command returned non-zero exit status.
        r   NdevnullT)stdinstdoutstderrZuniversal_newlinesshellr   z'%s' exited %d)
subprocessPIPEr   r5   ActionZ_subprocZcommunicatewaitsysr   writeOSError)r[   commandr   r]   r   outerrstatusr   r   r   backtick2  s    z SubstitutionEnvironment.backtickc             C   s   t | ||}| j| dS )z
        Adds the specified function as a method of this construction
        environment with the specified name.  If the name is omitted,
        the default name is the name of the function itself.
        N)r	   r   rP   )r[   functionr'   rc   r   r   r   	AddMethodY  s    z!SubstitutionEnvironment.AddMethodc                s    fdd| j D | _ dS )z
        Removes the specified function's MethodWrapper from the
        added_methods list, so we don't re-bind it when making a clone.
        c                s   g | ]}|j  k	r|qS r   )rc   )r)   Zdm)r   r   r   r+   g  s    z8SubstitutionEnvironment.RemoveMethod.<locals>.<listcomp>N)r   )r[   r   r   )r   r   rn   b  s    z$SubstitutionEnvironment.RemoveMethodc             C   st   |s| S t |}|s| S i }d}x6| D ]*\}}|dkr@|}q*tj|| |||< q*W t| |}|rp|| |S )a  
        Produce a modified environment whose variables are overridden by
        the overrides dictionaries.  "overrides" is a dictionary that
        will override the variables of this environment.

        This function is much more efficient than Clone() or creating
        a new Environment because it doesn't copy the construction
        environment dictionary, it just wraps the underlying construction
        environment, and doesn't even create a wrapper object if there
        are no overrides.
        Nparse_flags)r=   rE   r5   r   scons_subst_onceOverrideEnvironment
MergeFlags)r[   	overridesoZmergesr>   r?   r   r   r   r   Overridei  s      

z SubstitutionEnvironment.Overridec                sj   t dt dt dt dg t dg t dt dg g t dg d fdd x|D ]} | qVW S )a  Return a dict of parsed flags.

        Parse ``flags`` and return a dict with the flags distributed into
        the appropriate construction variable names.  The flags are treated
        as a typical set of command-line flags for a GNU-style toolchain,
        such as might have been generated by one of the {foo}-config scripts,
        and used to populate the entries based on knowledge embedded in
        this method - the choices are not expected to be portable to other
        toolchains.

        If one of the ``flags`` strings begins with a bang (exclamation mark),
        it is assumed to be a command and the rest of the string is executed;
        the result of that evaluation is then added to the dict.
        r   )ASFLAGSCFLAGSCCFLAGSCXXFLAGS
CPPDEFINESCPPFLAGSCPPPATHFRAMEWORKPATH
FRAMEWORKSLIBPATHLIBS	LINKFLAGSRPATHc                sR  | sd S t | s*x| D ]} | qW d S | d dkrH| dd  } fdd}t| }d }x|D ]} |r|dkr||  nH|dkrdj| f}d | n|d	krd	j| f}d | n|d
krd
| f}d | d | n|dkr.d| f}d | n|dkrPd| f}d | n|dkrrd| f}d | n`|dkrd| f}d | d | n0|dkrd| f}d | n| |  d }qj| d dkrd j|  qj| dkrd |  d}qj| d d dkrZ| dd  rTd | dd   nd}qj| d d dkr| dd  rd | dd   nd}qj| d d dkr| dd  rЈd | dd   nd}qj| d d dkrd | dd   d |  qj| d d dkr| d d dkrJd  | dd   nb| d d! d"krtd  | d!d   n8| d d# d$krd  | d#d   nd |  qj| d d d%krЈd& |  qj| d d d'kr| dd  r|| dd   nd}qj| d(krd)}qj| d d* d+krBd, | d*d   qj| d d d-kr| dd  rzd, | dd   nd,}qj| d.krd |  d |  qj| d/krd |  qj| d d0 d1kr d2| d0d  krd3}nd4}| |  qj| d d5kr,d |  d |  qj| d6kr<| }qjd |  qjW d S )7Nr   !r   c             S   sN   |  d}t|dkr&|d |  n$|d |d d|dd  g d S )N=r   r   r   )splitr   rP   r   )r'   rk   tr   r   r   append_define  s    
zKSubstitutionEnvironment.ParseFlags.<locals>.do_parse.<locals>.append_definer   z-includer   z-imacrosz	-isysrootr   z-isystemz-iquotez
-idirafterz-archz--param)-+r   z-dylib_file   z-Lr   z-lz-Ir      z-Wa,r   z-Wl,   z-Wl,-rpath=r      z-Wl,-R,   z-Wl,-Rz-Wp,r   z-Dz
-frameworkr      z-frameworkdir=r   z-F)z-mno-cygwinz-pthreadz-openmpz-fmerge-all-constantsz-fopenmpz	-mwindows   z-std=z++r   r   r   )z-includez-imacrosz	-isysrootz-isystemz-iquotez
-idirafterz-archz--param)r   r   shlexr   r}   r   rP   )argr   r   ZparamsZappend_next_arg_tor>   )do_parserk   r[   r   r   r     s    
 











z4SubstitutionEnvironment.ParseFlags.<locals>.do_parse)r   )r[   flagsr   r   )r   rk   r[   r   
ParseFlags  s$     
z"SubstitutionEnvironment.ParseFlagsTc       	      C   sT  t |s| |}|s&| jf | dS x&| D ]\}}|sBq2t|}y| | }W n tk
rn   |}Y nnX |sz|}nb|ry|| }W nP ttfk
r   y
|j}W n$ tk
r   |	d| |}Y n
X || Y nX g }|dd dkrxP|D ]}||kr|| qW n0x.|ddd D ]}||kr$|	d| q$W || |< q2W dS )a   Merge flags into construction variables.

        Merges the flags from ``args`` into this construction environent.
        If ``args`` is not a dict, it is first converted to one with
        flags distributed into appropriate construction variables.
        See :meth:`ParseFlags`.

        Args:
            args: flags to merge
            unique: merge flags rather than appending (default: True).
                When merging, path variables are retained from the front,
                other construction variables from the end.
        Nr   PATH)
r   r   AppendrE   r   rC   rR   rP   rd   insert)	r[   r\   uniquer>   r?   origadd_to_origr   rI   r   r   r   r   E  sD    





z"SubstitutionEnvironment.MergeFlags)N)N)r   NNNN)r   NN)r   NNNN)NN)N)T)!r   r   r   rh   rj   r   r   rr   r   ro   r   r   r3   r   rE   r   rX   r   r   r   r   r   r   r   subst_target_sourcestrr   r   rn   r   r9   r   r   r   r   r   r   rw   @  s8   

+

	


''
	 Brw   c             C   s   t j j}|| |||S )N)r5   DefaultsDefaultEnvironmentdecide_source)
dependencyr   prev_ni	repo_nodefr   r   r   default_decide_source  s    r   c             C   s   t j j}|| |||S )N)r5   r   r   decide_target)r   r   r   r   r   r   r   r   default_decide_target  s    r  c             C   s   t jj| ||S )N)r5   CacheDirZcopy_from_cache)r   srcdstr   r   r   default_copy_from_cache  s    r  c             C   s   t jj| ||S )N)r5   r  Zcopy_to_cache)r   r  r  r   r   r   default_copy_to_cache  s    r  c               @   s  e Zd ZdZdddZdd ZdddZd	d
 ZdddZe	j
jdd Zdd ZdddZdd Zdd Zdd Zdd Zdd Zdd Zd ejd!fd"d#Zdd$d%Zg ddfd&d'Zdd(d)Zdd*d+Zdd,d-Zdd.d/Zdd0d1Zdd2d3Zd4d5 Z d6d7 Z!d8d9 Z"dd;d<Z#d=d> Z$dd@dAZ%ddBdCZ&dDdE Z'dFdG Z(d ejd?fdHdIZ)ddJdKZ*dLdM Z+dNdO Z,dPdQ Z-dRdS Z.de	j/j/dTdUdVZ/ddWdXZ0dYdZ Z1d[d\ Z2d]d^ Z3g dfd_d`Z4dadb Z5dcdd Z6ddedfZ7dgdh Z8didj Z9dkdl Z:dmdn Z;dodp Z<dqdr Z=dsdt Z>dudv Z?dwdx Z@dydz ZAd{d| ZBd}d~ ZCdd ZDdd ZEdd ZFdddZGdd ZHdd ZIdd ZJdd ZKdd ZLdd ZMdd ZNdd ZOe	jPQ dfddZRdd ZSdd ZTdddZUdddZVdddZWdd ZXdS )BaseaA  Base class for "real" construction Environments.

    These are the primary objects used to communicate dependency
    and construction information to the build engine.

    Keyword arguments supplied when the construction Environment
    is created are construction variables used to initialize the
    Environment.
    Nc          	   K   s&  t jjrt| d i | _t jj | _t jj	j
| _t jj| _tt jj| _|   g | _t| _t| _d| _t| jd | | jd< |dkr| jdd}|dkrt j }t|rt j|}t|| jd< ||  | jdd| jd< | jdd| jd< | jdd| jd< | jd	d| jd	< d
|kr:|d
 }|d
= | jf | t|  }|rr|t|   }|!|  i }x8|D ]0}	y| j|	 ||	< W n t"k
r   Y nX q|W t j#$|  |dkr| jdd}|dkrdg}t%| || x |& D ]\}
}|| j|
< qW |r"| '| dS )a  Initialization of a basic SCons construction environment.

        Sets up special construction variables like BUILDER,
        PLATFORM, etc., and searches for and applies available Tools.

        Note that we do *not* call the underlying base class
        (SubsitutionEnvironment) initialization, because we need to
        initialize things in a very specific order that doesn't work
        with the much simpler base class initialization.
        zEnvironment.BaseFr   NPLATFORMZHOST_OSZ	HOST_ARCHZ	TARGET_OSZTARGET_ARCHZoptionsZTOOLSr   )(r5   rx   ry   r   _memorz   r{   r|   r}   r~   r   r   r   r   r   r   ZConstructionEnvironmentrA   r   r   r  r   r   r   cache_timestamp_newerrD   r   Platformr   r   Replacer   r3   ZUpdaterC   r,   ZInitializersr1   rE   r   )r[   platformr-   r(   Z	variablesr   r]   r3   Zsaver;   r>   rq   r   r   r   rj     sb     







zBase.__init__c             C   s(   y| j d | S  tk
r"   dS X dS )zHFetch the builder with the specified name from the environment.
        r   N)rA   rC   )r[   r'   r   r   r   get_builder  s    zBase.get_builderc             C   s:   |dkr|  dtjj}t|tjjs6tdt| |S )zValidate the passed custom CacheDir class, or if no args are passed,
        validate the custom CacheDir class from the environment.
        NCACHEDIR_CLASSz2Custom CACHEDIR_CLASS %s not derived from CacheDir)r   r5   r  
issubclassr   r   )r[   custom_classr   r   r   validate_CacheDir_class  s
    zBase.validate_CacheDir_classc             C   s   y
| j }W n  tk
r*   tj j }Y nX |  }y"|| jkrTt| j|krT| jS W n tk
rj   Y nX ||}|| _|| _|S )N)	_CacheDir_pathrd   r5   r   r   r  Z_last_CacheDir_pathtypeZ_last_CacheDir)r[   r   Zcachedir_classZcdr   r   r   get_CacheDir*  s    


zBase.get_CacheDirr   c             C   sj   |}yt |tjjj}W n tk
r,   Y n*X |rVy
|j}W n tk
rP   Y nX d}|sft| j	|}|S )z`Return a factory function for creating Nodes for this
        construction environment.
        N)
r  r5   rz   r{   r  rR   r   rd   rm   r}   )r[   factoryr   r'   Zis_noder   r   r   get_factoryA  s     
 zBase.get_factoryc             C   s   y
| j d S  tk
r   Y nX i }y| jd }W n tk
rF   Y nhX t|sX|g}n|d d  }|  x@|D ]8}x2|| D ]$}|r| d dkr| }|||< qW qrW || j d< |S )N_gsmr   r  win32)r	  rC   rA   r   rO   Z	get_skeyslower)r[   r:   Zscannersscannerr;   r   r   r   r  ^  s(    


z	Base._gsmc             C   s&   |r| d dkr|  }|  |S )zJFind the appropriate scanner given a key (usually a file suffix).
        r  r  )r  r  r   )r[   Zskeyr   r   r   get_scanner  s    zBase.get_scannerc             C   s&   y| j d= W n tk
r    Y nX dS )z7Delete the cached scanner map (if we need to).
        r  N)r	  rC   )r[   r]   r   r   r   rK     s    zBase.scanner_map_deletec             C   s   | j | dS )zPrivate method to update an environment's consvar dict directly.

        Bypasses the normal checks that occur when users try to set items.
        N)rA   rH   )r[   r   r   r   r   _update  s    zBase._updatec             C   s.   x(|  D ]\}}|| jkr
|| j|< q
W dS )a,  Private method to add new items to an environment's consvar dict.

        Only adds items from `other` whose keys do not already appear in
        the existing dict; values from `other` are not used for replacement.
        Bypasses the normal checks that occur when users try to set items.
        N)rE   rA   )r[   r   r;   rI   r   r   r   _update_onlynew  s    
zBase._update_onlynewc             C   s2   y| j S  tk
r,   tj j }|| _ |S X d S )N)Zsrc_sig_typerd   r5   r   r   )r[   r   r   r   r   get_src_sig_type  s    zBase.get_src_sig_typec             C   s2   y| j S  tk
r,   tj j }|| _ |S X d S )N)Ztgt_sig_typerd   r5   r   r   )r[   r   r   r   r   get_tgt_sig_type  s    zBase.get_tgt_sig_typec       
      K   s*  t |}x| D ]\}}y6|dkrHt| j| rH| j| g| j|< | j| }W n> tk
r   |dkrt|r|g| j|< n
|| j|< wY nX y
|j}W n tk
r0   y|| | j|< W nf ttfk
r(   y
|j}W n2 tk
r   |r|	d| || j|< Y nX |r$|| Y nX wY nX t
|r|dkrg }x<| D ]0\}}	|	dk	rv|||	f n||f qTW |}||7 }|| j|< nxv|D ]}	d||	< qW qy|| W q tttfk
r   t|r
x(| D ]\}}	|	||< qW nd||< Y qX qW | | dS )zAppend values to construction variables in an Environment.

        The variable is created if it is not already present.
        r   r   N)r=   rE   r   rA   rC   rH   rd   rR   rP   r   r   
ValueErrorr   rK   )
r[   r]   r>   rq   r   update_dictr   tmpr;   rI   r   r   r   r     s\    







zBase.Appendc             C   s4   t |st|}|r0|d dkr0t| j|}|S )zzAllow Dirs and strings beginning with # for top-relative.

        Note this uses the current env's fs (in self).
        r   #)r   r   r}   Dir)r[   r   r   r   r   _canonicalize  s
    zBase._canonicalizeENVFc             C   sd   d}|| j kr*|| j | kr*| j | | }t||||| jd}|| j krRi | j |< || j | |< dS )a  Append path elements to the path *name* in the *envname*
        dictionary for this environment.  Will only add any particular
        path once, and will normpath and normcase all paths to help
        assure this.  This can also handle the case where the env
        variable is a list instead of a string.

        If *delete_existing* is False, a *newpath* element already in the path
        will not be moved to the end (it will be left where it is).
        r   )canonicalizeN)rA   r   r&  )r[   r'   newpathenvnamesepdelete_existingr   nvr   r   r   AppendENVPath  s    

zBase.AppendENVPathc       	         s  t |}x| D ]\}tr0t||| jksH| j| dkrT| j|< qt| j| r|tr|| j|  qtr>| j|  |dkrg }xjD ]b}t|rt|dkr||d |d f n||d f qt	|r|| q||f qW |t r`g }x<  D ]0\}}|dk	rH|||f n||f q&W | nt
 rt fg n|g }xr D ]j}t|rt|dkr||d |d f n||d f n"t	|r|| n||f q~W | nt s g |rfdd D  n fd	dD   | j|< q| j|  t r|dkrg }xr D ]j}t|rt|dkr||d |d f n||d f n"t	|r|| n||f qfW | tr*g }x< D ]0\}}|dk	r|||f n||f qW |nt
r<fg|rhttfd
d    | j|< n fdd D    | j|< nH|rttfdd   g | j|< n krֈ g | j|< q|dkrt
 r g nPt r@g }x<  D ]0\}}|dk	r*|||f n||f qW | t
rb krZg ngnNtrg }x: D ].\}}|dk	r|||f n
|| qzW ||rȇfdd D    | j|< qW | | dS )zAppend values to existing construction variables
        in an Environment, if they're not already there.
        If delete_existing is True, removes existing values first, so
        values move to end.
        )r   Nr   r   r   r   Nc                s   g | ]}| kr|qS r   r   )r)   x)rq   r   r   r+   f  s    z%Base.AppendUnique.<locals>.<listcomp>c                s   g | ]}| kr|qS r   r   )r)   r/  )dkr   r   r+   h  s    c             S   s   | |kS )Nr   )r/  rq   r   r   r   <lambda>      z#Base.AppendUnique.<locals>.<lambda>c                s   g | ]}| kr|qS r   r   )r)   r/  )rq   r   r   r+     s    c             S   s   | |kS )Nr   )r/  rq   r   r   r   r1    r2  c                s   g | ]}| kr|qS r   r   )r)   r/  )rq   r   r   r+     s    )r=   rE   r   rV   rA   r   rH   r   rP   r   r   r   filterrK   )	r[   r,  r]   r>   r#  rU   r;   rI   jr   )r0  rq   r   AppendUnique-  s    






























zBase.AppendUniquec             K   s   | j di }t| }t| j dg|_ t|||j d< g |_x0| jD ]&}|t| |jkrF|j|	| qFW i |_
t|}i }x(| D ]\}	}
tj|
| |	||	< qW |jf | t||| |jf | |r|| tjjrt| d |S )am  Return a copy of a construction Environment.

        The copy is like a Python "deep copy"--that is, independent
        copies are made recursively of each objects--except that
        a reference is copied when an object is not deep-copyable
        (like a function).  There are no references to any mutable
        objects in the original Environment.
        r   zEnvironment.EnvironmentClone)rA   r   r2   r   rD   r   rm   r'   rP   cloner	  r=   rE   r5   r   r   r  r1   r   rx   ry   r   )r[   r-   r(   r   r]   Zbuildersr6  Zmwnewr>   r?   r   r   r   Clone  s*    


 
z
Base.Clonec             C   s"   | |||rdS | ||||S )Nr   )Zchanged_stater   )r[   r   r   r   r   r   r   r   _changed_build  s    zBase._changed_buildc             C   s   | |||S )N)Zchanged_content)r[   r   r   r   r   r   r   r   _changed_content  s    zBase._changed_contentc             C   s<   |  }| }|dkr(|||||S |||||S d S )Nr   )Zget_build_envr   r   r   )r[   r   r   r   r   Z
target_envr  r   r   r   _changed_source  s
    zBase._changed_sourcec             C   s   | |||S )N)Zchanged_timestamp_then_content)r[   r   r   r   r   r   r   r   _changed_timestamp_then_content  s    z$Base._changed_timestamp_then_contentc             C   s   | |||S )N)Zchanged_timestamp_newer)r[   r   r   r   r   r   r   r   _changed_timestamp_newer  s    zBase._changed_timestamp_newerc             C   s   | |||S )N)Zchanged_timestamp_match)r[   r   r   r   r   r   r   r   _changed_timestamp_match  s    zBase._changed_timestamp_matchc             C   st   d| _ |dkr| j}nN|dkr&| j}n>|dkr<| j}d| _ n(|dkrL| j}nt|sdtdt| || _|| _	d S )NF)ZMD5Zcontent)zMD5-timestampzcontent-timestamp)ztimestamp-newerZmakeTztimestamp-matchzUnknown Decider value %s)
r
  r:  r<  r=  r>  callabler   rG   r   r   )r[   r   r   r   r   Decider  s    zBase.Deciderc             C   s2   t |s|g}x|D ]}| |}|r|S qW dS )zReturn the first available program from one or more possibilities.

        Args:
            progs (str or list): one or more command names to check for

        N)r   r   )r[   Zprogsprogr   r   r   r   Detect  s    

 zBase.Detectc                s4   |s
 j S  fdd|D }t|dkr0|d }|S )a  Return construction variables from an environment.

        Args:
          \*args (optional): variable names to look up

        Returns:
          If `args` omitted, the dictionary of all construction variables.
          If one arg, the corresponding value is returned.
          If more than one arg, a list of values is returned.

        Raises:
          KeyError: if any of `args` is not in the construction environment.

        c                s   g | ]} j | qS r   )rA   )r)   r/  )r[   r   r   r+   1  s    z#Base.Dictionary.<locals>.<listcomp>r   r   )rA   r   )r[   r\   dlistr   )r[   r   
Dictionary   s    zBase.Dictionaryprettyc       	      C   s~   |r|  |}n|   }| }|dkrFddl}|jdd}||S |dkrnddl}dd }|j|d	|d
S td| dS )a   Return construction variables serialized to a string.

        Args:
          key (optional): if None, format the whole dict of variables.
            Else format the value of `key` (Default value = None)
          format (str, optional): specify the format to serialize to.
            `"pretty"` generates a pretty-printed string,
            `"json"` a JSON-formatted string.
            (Default value = `"pretty"`)

        rE  r   Nr   )indentjsonc             S   s   t t| jS )N)r   r  r   )r   r   r   r   non_serializableW  s    z#Base.Dump.<locals>.non_serializabler   )rF  r   z%Unsupported serialization format: %s.)rD  r  pprintZPrettyPrinterZpformatrG  dumpsr!  )	r[   r>   formatZcvarsZfmtrI  ZpprG  rH  r   r   r   Dump7  s    
z	Base.Dumpc             C   sl   |  d| }|  d| }xJ|D ]B}tjt|}|dt| |kr"|t| d |kr"|S q"W dS )a)  Search a list of paths for something that matches the prefix and suffix.

        Args:
          paths: the list of paths or nodes.
          prefix: construction variable for the prefix.
          suffix: construction variable for the suffix.

        Returns: the matched path or None

        $N)r   osr   basenamer   r   )r[   pathsprefixsuffixr   r'   r   r   r   FindIxes^  s    
*zBase.FindIxesTc             C   sF   |dkr|fdd}|}t |r*d|}| |}|| | ||S )at  Parse the result of running a command to update construction vars.

        Use ``function`` to parse the output of running ``command``
        in order to modify the current environment.

        Args:
            command: a string or a list of strings representing a command
              and its arguments.
            function: called to process the result of ``command``, which will
              be passed as ``args``.  If ``function`` is omitted or ``None``,
              :meth:`MergeFlags` is used. Takes 3 args ``(env, args, unique)``
            unique: whether no duplicate values are allowed (default true)
        Nc             S   s   |  ||S )N)r   )r   cmdr   r   r   r   
parse_conf  s    z$Base.ParseConfig.<locals>.parse_conf )r   r   r   r   )r[   r   r   r   rU  r   r   r   ParseConfigs  s    

zBase.ParseConfigc          
   C   s  |  |}y&t|d}t| }W dQ R X W n tk
rJ   |rF dS X dd |D }g }xP|D ]H}y|dd\}}	W n ttfk
r   Y qdX || |	 f qdW |rg }
x|D ]}|
	|d  qW t
|
dkrtd||
f x|D ]\}}	| ||	 qW dS )	a  
        Parse a mkdep-style file for explicit dependencies.  This is
        completely abusable, and should be unnecessary in the "normal"
        case of proper SCons configuration, but it may help make
        the transition from a Make hierarchy easier for some people
        to swallow.  It can also be genuinely useful when using a tool
        that can write a .d file, but for which writing a scanner would
        be too complicated.
        r   Nc             S   s   g | ]}|d  dkr|qS )r   r$  r   )r)   rS   r   r   r   r+     s    z%Base.ParseDepends.<locals>.<listcomp>:r   r   z2More than one dependency target found in `%s':  %s)r   openr   	readlinesIOErrorr   rd   r!  rP   r   r   r   Depends)r[   filenameZ
must_existZonly_onefplinesZtdlistliner   ZdependstargetsZtdr   r   r   ParseDepends  s4    



zBase.ParseDependsc             C   s   |  |}tj|| S )N)r   r5   r  )r[   r  r   r   r   r    s    
zBase.Platformc       	      K   st  t |}xZ| D ]L\}}y| j| }W n  tk
rL   || j|< wY nX y
|j}W n tk
r   y|| | j|< W n^ ttfk
r   y
|j}W n$ tk
r   |r|d| Y nX |r|| || j|< Y nX wY nX t	|rxt|D ]}d||< qW qy|| W q ttt
fk
r`   t|rTx(| D ]\}}|||< q<W nd||< Y qX qW | | dS )zPrepend values to construction variables in an Environment.

        The variable is created if it is not already present.
        r   N)r=   rE   rA   rC   rH   rd   rR   rP   r   r   r!  r   rK   )	r[   r]   r>   rq   r   r"  Z
add_to_valrI   r;   r   r   r   Prepend  sB    





zBase.Prependc             C   sd   d}|| j kr*|| j | kr*| j | | }t||||| jd}|| j krRi | j |< || j | |< dS )a  Prepend path elements to the path *name* in the *envname*
        dictionary for this environment.  Will only add any particular
        path once, and will normpath and normcase all paths to help
        assure this.  This can also handle the case where the env
        variable is a list instead of a string.

        If *delete_existing* is False, a *newpath* component already in the path
        will not be moved to the front (it will be left where it is).
        r   )r(  N)rA   r
   r&  )r[   r'   r)  r*  r+  r,  r   r-  r   r   r   PrependENVPath  s    



zBase.PrependENVPathc                sj  t |}xP| D ]B\}tr2t| || jksJ| j| dkrV| j|< qt| j| r~tr~| j|  qtr| j|  t s g |rfdd D  n fddD   | j|< q| j|  t r2|rfdd D  g  | j|< n krXg  | j|< q|rJfdd D    | j|< qW | | dS )zPrepend values to existing construction variables
        in an Environment, if they're not already there.
        If delete_existing is True, removes existing values first, so
        values move to front.
        )r   Nc                s   g | ]}| kr|qS r   r   )r)   r/  )rq   r   r   r+   %  s    z&Base.PrependUnique.<locals>.<listcomp>c                s   g | ]}| kr|qS r   r   )r)   r/  )r0  r   r   r+   '  s    c                s   g | ]}| kr|qS r   r   )r)   r/  )rq   r   r   r+   /  s    c                s   g | ]}| kr|qS r   r   )r)   r/  )rq   r   r   r+   6  s    N)r=   rE   r   rV   rA   r   rH   rK   )r[   r,  r]   r>   r   )r0  rq   r   PrependUnique  s6    



zBase.PrependUniquec             K   sb   y|d }W n t k
r    Y nX t|| }|d= | d| t|}| t| | | dS )zyReplace existing construction variables in an Environment
        with new construction variables and/or values.
        r   N)rC   rD   ro   r=   r  r   rK   )r[   r]   Zkwbdr   r   r   r  :  s    
zBase.Replacec             C   s   |  d| }|  d| }|  d| }|  d| }tjt|\}}|dt| |krp|t|d }|t| d |kr|dt|  }tj||| | S )a  
        Replace old_prefix with new_prefix and old_suffix with new_suffix.

        env - Environment used to interpolate variables.
        path - the path that will be modified.
        old_prefix - construction variable for the old prefix.
        old_suffix - construction variable for the old suffix.
        new_prefix - construction variable for the new prefix.
        new_suffix - construction variable for the new suffix.
        rM  N)r   rN  r   r   r   r   r   )r[   r   Z
old_prefixZ
old_suffixZ
new_prefixZ
new_suffixdirr'   r   r   r   ReplaceIxesJ  s    zBase.ReplaceIxesc             K   s6   x$t | D ]}|| jkr||= qW | jf | d S )N)r   r3   rA   r  )r[   r]   r;   r   r   r   
SetDefaultb  s    

zBase.SetDefaultc             C   s   | j | |  S )N)r}   r%  r   srcnodeZget_abspath)r[   tpr   r   r   _find_toolpath_dirh  s    zBase._find_toolpath_dir)r   c             K   sT   t |rH| |}|d kr&| dg }tt| j|}tjj||f|}||  |S )Nr(   )r   r   r   r   r   rk  r5   r,   )r[   r.   r(   kwargsr   r   r   r,   k  s    
z	Base.Toolc             C   s   |sdS |dkr8y| d d }W qJ t k
r4   Y qJX nt|rJ| |}|dkrzy| d d }W q t k
rv   Y qX nt|r| |}t| |}t|d |||}|r|S dS )zFind prog in the path. Nr'  r   ZPATHEXTr   )rC   r   r   r   r   )r[   rA  r   ZpathextZrejectr   r   r   r   u  s*    

zBase.WhereIsc             O   s2   | fdd}t t||}| |}tjj||S )Nc             S   s   t | r|| } | S )N)r   r   )ar[   r   r   r   subst_string  s    
z!Base.Action.<locals>.subst_string)r   r   r   r5   r   )r[   r\   r]   rn  nargsr   r   r   r   r     s    
zBase.Actionc             C   s`   |  || jj}tj|}i }xdd |D D ]}d||< q0W x| D ]}|| qJW |S )Nc             S   s   g | ]}|  qS r   )get_executor)r)   r   r   r   r   r+     s    z%Base.AddPreAction.<locals>.<listcomp>r   )r   r}   Entryr5   r   r3   Zadd_pre_action)r[   filesr"   r   uniqr   r   r   r   AddPreAction  s    zBase.AddPreActionc             C   s`   |  || jj}tj|}i }xdd |D D ]}d||< q0W x| D ]}|| qJW |S )Nc             S   s   g | ]}|  qS r   )rp  )r)   r   r   r   r   r+     s    z&Base.AddPostAction.<locals>.<listcomp>r   )r   r}   rq  r5   r   r3   Zadd_post_action)r[   rr  r"   r   rs  r   r   r   r   AddPostAction  s    zBase.AddPostActionc             K   s  |  || jj}t|s|g}dd |D }|sj|s8|S g }x(|D ] }|t}||| || qBW |S | |}	|	t	j

|| jjdd d t	jjf |	}g }xf|D ]^}| }
|
d ks|
tkr|}
n|
j| |	d< t	jjf |	}
|  ||
| ||j|  qW |S )Nc             S   s   g | ]}|r|qS r   r   )r)   r*   r   r   r   r+     s    zBase.Alias.<locals>.<listcomp>r   )r"   r$   r%   r&   r"   )r   r   r~   r   r  r!   r   r   rH   r5   r   r}   rq  rF   r"   Zconvertsources)r[   r   r   r"   r]   tlistr:   r   bldr   br   r   r   r~     s:    





z
Base.Aliasc             G   sB   g }x"|D ]}| | || jj q
W x|D ]}|  q.W |S )N)r   r   r}   rq  Zset_always_build)r[   ra  rw  r   r   r   r   AlwaysBuild  s    

zBase.AlwaysBuildc             K   s   |  |}tjjf |S )N)r   r5   rF   )r[   r]   r   r   r   r   rF     s    
zBase.Builderc             C   s>   |d k	r|  |}|| _|r*| || d< tjjr:|   d S )Nr  )r   r  r  r5   r   Zexecute_actionsr  )r[   r   r  r   r   r   r    s    
zBase.CacheDirc          	   C   sb   |  || jj}|  || jj}x<|D ]4}yt| | W q& tk
rX   |t|< Y q&X q&W d S )N)r   r}   rq  CleanTargetsr   rC   )r[   ra  rr  rw  Zflistr   r   r   r   Clean  s    
z
Base.Cleanc             O   st   | g}|r||  |d  }| |}|ddd |d< y| |d |d< W n tk
rd   Y nX tjj||S )Nr   Z_depthr   Zcustom_tests)r   r   r   rC   r5   ZSConf)r[   r\   r]   ro  r   r   r   r   	Configure  s    
zBase.Configurec             K   s   || j j| j jd}y|d |d< W n tk
r8   Y nX |d= y|d |d< W n tk
rd   Y nX |d= y|d |d< W n tk
r   Y nX |d= y|d |d< W n tk
r   Y nX |d= tjjf |}|| ||f|S )zBuilds the supplied target files from the supplied
        source files using the supplied action.  Action may
        be any type that the Builder constructor will accept
        for an action.)r"   r#   r$   Zsource_scannerZtarget_scannerr$   r#   )r}   rq  rC   r5   rF   )r[   r   r   r"   r]   Zbkwrx  r   r   r   Command  s2    zBase.Commandc             C   s<   |  || jj}|  || jj}x|D ]}|| q&W |S )z8Explicity specify that 'target's depend on 'dependency'.)r   r}   rq  Zadd_dependency)r[   r   r   rw  rC  r   r   r   r   r\  E  s
    
zBase.Dependsc             O   sV   |  |}t|rBg }x&|D ]}|| jj|f|| qW |S | jj|f||S )z	
        )r   r   rP   r}   r%  )r[   r'   r\   r]   r   r:   er   r   r   r%  M  s    

zBase.Dirc             C   sF   |  |}t|r:g }x|D ]}|| j| qW |S | j|S )N)r   r   rP   r}   PyPackageDir)r[   Z
modulenamer   r:   r  r   r   r   r  X  s    

zBase.PyPackageDirc             G   sB   g }x"|D ]}| | || jj q
W x|D ]}|  q.W |S )z2Tags a target so that it will not be cleaned by -c)r   r   r}   rq  Zset_noclean)r[   ra  rw  r   r   r   r   NoCleana  s    

zBase.NoCleanc             G   sB   g }x"|D ]}| | || jj q
W x|D ]}|  q.W |S )z+Tags a target so that it will not be cached)r   r   r}   rq  Zset_nocache)r[   ra  rw  r   r   r   r   NoCachej  s    

zBase.NoCachec             O   sV   |  |}t|rBg }x&|D ]}|| jj|f|| qW |S | jj|f||S )z	
        )r   r   rP   r}   rq  )r[   r'   r\   r]   r   r:   r  r   r   r   rq  s  s    

z
Base.Entryc             K   s   t jjf | |S )N)r5   Environmentr   )r[   r]   r   r   r   r  ~  s    zBase.Environmentc             O   s`   | j |f||}|g g | }t|trX|j}|jrB|jd | }tjd|  |jS |S dS )z:Directly execute an action through an Environment
        z: zscons: *** %s
N)	r   
isinstancer   errstrr]  r   r   r   r   )r[   r"   r\   r]   r:   r  r   r   r   Execute  s    
zBase.Executec             O   sV   |  |}t|rBg }x&|D ]}|| jj|f|| qW |S | jj|f||S )z	
        )r   r   rP   r}   r   )r[   r'   r\   r]   r   r:   r  r   r   r   r     s    

z	Base.Filec             C   s.   |  |}| || jj}tjj|t|S )N)	r   r   r}   r%  r5   rz   r{   Z	find_filetuple)r[   filedirsr   r   r   r   FindFile  s    
zBase.FindFilec             C   s   t |S )N)r   )r[   Zsequencer   r   r   Flatten  s    zBase.Flattenc             C   s2   t tt| || jj}t|r&|S |d S d S )Nr   )r   r   r   r   r}   rq  r   )r[   rr  r:   r   r   r   GetBuildPath  s    zBase.GetBuildPathc             C   s   | j | |||||S )N)r}   Globr   )r[   patternZondiskr   ZstringsZexcluder   r   r   r    s    z	Base.Globc             C   s<   |  || jj}|  || jj}x|D ]}|| q&W |S )zIgnore a dependency.)r   r}   rq  Z
add_ignore)r[   r   r   rw  rC  r   r   r   r   Ignore  s
    
zBase.Ignorec             C   s   t j|S )N)r5   r   Literal)r[   r   r   r   r   r    s    zBase.Literalc             G   sd   g }xZ|D ]R}t |tjjr0|  || q
x*| || jjD ]}|  || qBW q
W |S )N)r  r5   rz   Z	set_localrP   r   r}   rq  )r[   ra  ZretZtargr   r   r   r   Local  s    
z
Base.Localc             G   sB   g }x"|D ]}| | || jj q
W x|D ]}|  q.W |S )N)r   r   r}   rq  Zset_precious)r[   ra  rw  r   r   r   r   Precious  s    

zBase.Preciousc             G   sB   g }x"|D ]}| | || jj q
W x|D ]}|  q.W |S )N)r   r   r}   rq  Z
set_pseudo)r[   ra  rw  r   r   r   r   Pseudo  s    

zBase.Pseudoc             O   s&   |  t|| jj}| jj|| d S )N)r   r   r}   r%  
Repository)r[   r  r]   r   r   r   r    s    zBase.Repositoryc             C   s<   |  || jj}|  || jj}x|D ]}|| q&W |S )zSpecify that 'prerequisite' must be built before 'target',
        (but 'target' does not actually depend on 'prerequisite'
        and need not be rebuilt if it changes).)r   r}   rq  Zadd_prerequisite)r[   r   Zprerequisiterw  Zplistr   r   r   r   Requires  s
    
zBase.Requiresc             O   sF   g }x(|D ] }t |r | |}|| q
W | |}tjj||S )N)r   r   rP   r   r5   ScannerZScannerBase)r[   r\   r]   ro  r   r   r   r   r   r    s    


zBase.Scannerc             C   s   |d k	r4|  |}tj|s4tjt| jj|}|rrtj|}tj	|}|rrtj
|sr| tj| tj|| d S )N)r   rN  r   isabsr   r   r}   ZSConstruct_dirnormpathdirnameexistsr  r5   r   ZMkdirSConsignr   )r[   r'   Z
dbm_moduleZsconsign_dirr   r   r   SConsignFile  s    
zBase.SConsignFilec             C   s   |  || jj}|  || jj}g }xx|D ]p}| rFtdt| || d|_| | d}x&|D ]}||j	krj|j	
| d}qjW |r*|
| q*W |S )zSTell scons that side_effects are built as side
        effects of building targets.z=Multiple ways to build the same target were specified for: %sr   FT)r   r}   rq  Z multiple_side_effect_has_builderr   r   Z
add_sourceside_effectr  side_effectsrP   )r[   r  r   r  ra  Zadded_side_effectsZaddedr   r   r   
SideEffect  s"    




zBase.SideEffectc             C   s>   t |rtt| j|S t|r.| | S | |gS dS )aS  This function converts a string or list into a list of strings
        or Nodes.  This makes things easier for users by allowing files to
        be specified as a white-space separated list to be split.

        The input rules are:
            - A single string containing names separated by spaces. These will be
              split apart at the spaces.
            - A single Node instance
            - A list containing either strings or Node instances. Any strings
              in the list are not split at spaces.

        In all cases, the function returns a list of Nodes and strings.N)r   r   r   r   r   r   )r[   r   r   r   r   r   	  s
    z
Base.Splitc             C   s   t jj|||S )z	
        )r5   rz   PythonZValueWithMemo)r[   r?   Zbuilt_valuer'   r   r   r   Value!	  s    z
Base.Valuer   c             C   s<   |  || jjd }|  || jjd }| j||| d S )Nr   )r   r}   r%  
VariantDir)r[   Zvariant_dirZsrc_dirZ	duplicater   r   r   r  &	  s    zBase.VariantDir.c                sT   |  || jjd }g  fdd  |  dd }tt|ttS )z- returns a list of all source files.
        r   c                sb   x\| D ]T}t |tjjjr( |  q| r< |j qt | tjjj	r
| qW d S )N)r  r5   rz   r{   r%  all_childrenZhas_builderrv  Zdisambiguater   rP   )Zssr   )build_sourcerv  r   r   r  1	  s    
z*Base.FindSourceFiles.<locals>.build_sourcec             S   s   x| |   kr|   } qW | S )N)ri  )noder   r   r   final_source;	  s    z*Base.FindSourceFiles.<locals>.final_source)r   r}   rq  r  r   r   rN   )r[   r  r  r   )r  rv  r   FindSourceFiles+	  s    zBase.FindSourceFilesc             C   s(   ddl m} |jdkr"t|j|_|jS )zO returns the list of all targets of the Install and InstallAs Builder.
        r   )installN)
SCons.Toolr  Z_UNIQUE_INSTALLED_FILESr   Z_INSTALLED_FILES)r[   r  r   r   r   FindInstalledFilesC	  s    
zBase.FindInstalledFiles)NNNNN)N)r   )N)F)N)N)N)N)N)N)NrE  )NT)NF)F)N)NNN)N)TFFN)NN)r   )r  )Yr   r   r   rh   rj   r  r  r  r  r5   ZMemoizeZCountMethodCallr  r  rK   r  r  r  r   r   r&  rN  pathsepr.  r5  r8  r9  r:  r;  r<  r=  r>  r@  rB  rD  rL  rS  rW  rb  r  rc  rd  re  r  rg  rh  rk  r,   r   r   rt  ru  r~   rz  rF   r  r|  r}  r~  r\  r%  r  r  r  rq  r  r  r   r  r  r  r  r  r  r  r  r  r  r  r  r  Zcurrent_sconsign_filenamer  r  r   r  r  r  r  r   r   r   r   r    s   	    
b

!
Q
 0






'

(A
(

 	

5

-			

	


r  c               @   s   e Zd ZdZd'ddZdd Zdd Zd	d
 Zdd Zdd Z	d(ddZ
dd Zdd Zdd Zdd Zdd Zd)ddZdd Zdd  Zd!d" Zd#d$ Zd%d& ZdS )*r   a$  A proxy that overrides variables in a wrapped construction
    environment by returning values from an overrides dictionary in
    preference to values from the underlying subject environment.

    This is a lightweight (I hope) proxy that passes through most use of
    attributes to the underlying Environment.Base class, but has just
    enough additional methods defined to act like a real construction
    environment with overridden values.  It can wrap either a Base
    construction environment, or another OverrideEnvironment, which
    can in turn nest arbitrary OverrideEnvironments...

    Note that we do *not* call the underlying base class
    (SubsitutionEnvironment) initialization, because we get most of those
    from proxying the attributes of the subject construction environment.
    But because we subclass SubstitutionEnvironment, this class also
    has inherited arg2nodes() and subst*() methods; those methods can't
    be proxied because they need *this* object's methods to fetch the
    values from the overrides dictionary.
    Nc             C   s>   t jjrt| d || jd< |d kr0i | jd< n
|| jd< d S )NzEnvironment.OverrideEnvironment	__subjectr   )r5   rx   ry   r   rf   )r[   subjectr   r   r   r   rj   a	  s     

zOverrideEnvironment.__init__c             C   s,   t | jd |}t|tr$|| S |S d S )Nr  )rm   rf   r  r	   r6  )r[   r'   attrr   r   r   re   j	  s    	

zOverrideEnvironment.__getattr__c             C   s   t | jd || d S )Nr  )setattrrf   )r[   r'   r?   r   r   r   rg   y	  s    zOverrideEnvironment.__setattr__c             C   s4   y| j d | S  tk
r.   | j d |S X d S )Nr   r  )rf   rC   r   )r[   r>   r   r   r   r   }	  s    zOverrideEnvironment.__getitem__c             C   s&   t |std| || jd |< d S )Nz"Illegal construction variable `%s'r   )rv   r   rf   )r[   r>   r?   r   r   r   ro   	  s    zOverrideEnvironment.__setitem__c             C   sf   y| j d |= W n tk
r(   d}Y nX d}y| j d |}W n tk
r`   |sX d }Y nX |S )Nr   r   r   r  )rf   rC   rr   )r[   r>   Zdeletedr:   r   r   r   rr   	  s    

zOverrideEnvironment.__delitem__c             C   s6   y| j d | S  tk
r0   | j d ||S X dS )z*Emulates the get() method of dictionaries.r   r  N)rf   rC   r   )r[   r>   r   r   r   r   r   	  s    zOverrideEnvironment.getc             C   s    || j d krdS || j d kS )Nr   Tr  )rf   )r[   r>   r   r   r   r   	  s    z OverrideEnvironment.__contains__c                sT   | j d     | j d  |s* S  fdd|D }t|dkrP|d }|S )Nr  r   c                s   g | ]} | qS r   r   )r)   r/  )dr   r   r+   	  s    z2OverrideEnvironment.Dictionary.<locals>.<listcomp>r   r   )rf   rD  r2   rH   r   )r[   r\   rC  r   )r  r   rD  	  s    zOverrideEnvironment.Dictionaryc             C   s   |    S )z,Emulates the items() method of dictionaries.)rD  rE   )r[   r   r   r   rE   	  s    zOverrideEnvironment.itemsc             C   s   |    S )z+Emulates the keys() method of dictionaries.)rD  r3   )r[   r   r   r   r3   	  s    zOverrideEnvironment.keysc             C   s   |    S )z-Emulates the values() method of dictionaries.)rD  r   )r[   r   r   r   r   	  s    zOverrideEnvironment.valuesc             C   s2   y
|  |S  tk
r,   || jd |< |S X dS )z1Emulates the setdefault() method of dictionaries.r   N)r   rC   rf   )r[   r>   r   r   r   r   r   	  s
    
zOverrideEnvironment.setdefaultc             C   s   | j d | d S )Nr   )rf   rH   )r[   r   r   r   r   r  	  s    zOverrideEnvironment._updatec             C   s6   x0|  D ]$\}}|| jd kr
|| jd |< q
W dS )zUpdate a dict with new keys.

        Unlike the .update method, if the key is already present,
        it is not replaced.
        r   N)rE   rf   )r[   r   r;   rI   r   r   r   r  	  s    z#OverrideEnvironment._update_onlynewc             C   s   | j d  S )Nr  )rf   r   )r[   r   r   r   r   	  s    zOverrideEnvironment.gvarsc             C   s"   | j d  }|| j d  |S )Nr  r   )rf   r   rH   )r[   r   r   r   r   r   	  s    zOverrideEnvironment.lvarsc             K   s    t |}| jd t| d S )Nr   )r=   rf   rH   r   )r[   r]   r   r   r   r  	  s    zOverrideEnvironment.Replace)N)N)N)r   r   r   rh   rj   re   rg   r   ro   rr   r   r   rD  rE   r3   r   r   r  r  r   r   r  r   r   r   r   r   L	  s&   
	


	
r   c             C   s   G dd dt }|| S )a  
    An entry point for returning a proxy subclass instance that overrides
    the subst*() methods so they don't actually perform construction
    variable substitution.  This is specifically intended to be the shim
    layer in between global function calls (which don't want construction
    variable substitution) and the DefaultEnvironment() (which would
    substitute variables if left to its own devices).

    We have to wrap this in a function that allows us to delay definition of
    the class until it's necessary, so that when it subclasses Environment
    it will pick up whatever Environment subclass the wrapper interface
    might have assigned to SCons.Environment.Environment.
    c               @   sT   e Zd Zdd Zdd Zdd Zdd Zd	d
 Zdd Zdd Z	dd Z
dd ZdS )z1NoSubstitutionProxy.<locals>._NoSubstitutionProxyc             S   s   || j d< d S )Nr  )rf   )r[   r  r   r   r   rj   	  s    z:NoSubstitutionProxy.<locals>._NoSubstitutionProxy.__init__c             S   s   t | jd |S )Nr  )rm   rf   )r[   r'   r   r   r   re   	  s    z=NoSubstitutionProxy.<locals>._NoSubstitutionProxy.__getattr__c             S   s   t | jd ||S )Nr  )r  rf   )r[   r'   r?   r   r   r   rg   	  s    z=NoSubstitutionProxy.<locals>._NoSubstitutionProxy.__setattr__c             S   s,   d|kr |d   |d< |d= ni |d< d S )Nr   r   )r   )r[   Zkwdictr   r   r   executor_to_lvars	  s    zCNoSubstitutionProxy.<locals>._NoSubstitutionProxy.executor_to_lvarsc             S   s4   y|d }W n t k
r    Y nX |d= ||d< d S )Nr   mode)rC   )r[   rk   r   r   r   r   raw_to_mode
  s    z=NoSubstitutionProxy.<locals>._NoSubstitutionProxy.raw_to_modec             _   s   |S )Nr   )r[   r   r\   rl  r   r   r   r   
  s    z7NoSubstitutionProxy.<locals>._NoSubstitutionProxy.substc             _   s   |S )Nr   )r[   r]   r\   rl  r   r   r   r   
  s    z:NoSubstitutionProxy.<locals>._NoSubstitutionProxy.subst_kwc             _   s>   || f| }|  }i |d< | | | | tjj||S )Nr   )r2   r  r  r5   r   r   )r[   r   r\   rl  ro  r   r   r   r   r   
  s    

z<NoSubstitutionProxy.<locals>._NoSubstitutionProxy.subst_listc             _   s>   || f| }|  }i |d< | | | | tjj||S )Nr   )r2   r  r  r5   r   r   )r[   r   r\   rl  ro  r   r   r   r   r   
  s    

zENoSubstitutionProxy.<locals>._NoSubstitutionProxy.subst_target_sourceN)r   r   r   rj   re   rg   r  r  r   r   r   r   r   r   r   r   _NoSubstitutionProxy	  s   	r  )r  )r  r  r   r   r   NoSubstitutionProxy	  s    0r  )N)N)Urh   r2   rN  r   rer   collectionsr   ZSCons.Actionr5   ZSCons.BuilderZSCons.Debugr   ZSCons.DefaultsZSCons.Errorsr   r   ZSCons.MemoizeZ
SCons.NodeZSCons.Node.AliasZSCons.Node.FSZSCons.Node.PythonZSCons.PlatformZSCons.SConfZSCons.SConsignZSCons.Substr  ZSCons.WarningsZ
SCons.Utilr   r   r   r	   r
   r   r   r   r   r   r   r   r   r   r   r   r   r   rX   Z_warn_copy_deprecatedZ"_warn_source_signatures_deprecatedZ"_warn_target_signatures_deprecatedr{  ZCalculatorArgsr    rF   rz   r~   r   r{   rq  r!   r1   r4   r   r=   r@   rB   rJ   rL   rM   rV   rW   rD   compilert   rv   rw   r   r  r  r  r  r   r  r  r   r   r   r   <module>   s   L
	">%
    H

           A 