NXc@sBdZddlZddlZddlZddlZddlZyddlZejZ Wn&e k rddl Z e j Z nXej dZej dZej dZej dZdZdZd efd YZd efd YZd efdYZdefdYZdefdYZdefdYZdeeefdYZdeefdYZdefdYZdefdYZdefdYZdefd YZ d!e fd"YZ!d#e fd$YZ"d%e fd&YZ#d'e fd(YZ$d)e fd*YZ%d+e fd,YZ&d-efd.YZ'd/efd0YZ(d1efd2YZ)d3efd4YZ*d5efd6YZ+e+e)j,d7d8YZ/d?efd@YZ0dS(AsuXcode project file generator. This module is both an Xcode project file generator and a documentation of the Xcode project file format. Knowledge of the project file format was gained based on extensive experience with Xcode, and by making changes to projects in Xcode.app and observing the resultant changes in the associated project files. XCODE PROJECT FILES The generator targets the file format as written by Xcode 3.2 (specifically, 3.2.6), but past experience has taught that the format has not changed significantly in the past several years, and future versions of Xcode are able to read older project files. Xcode project files are "bundled": the project "file" from an end-user's perspective is actually a directory with an ".xcodeproj" extension. The project file from this module's perspective is actually a file inside this directory, always named "project.pbxproj". This file contains a complete description of the project and is all that is needed to use the xcodeproj. Other files contained in the xcodeproj directory are simply used to store per-user settings, such as the state of various UI elements in the Xcode application. The project.pbxproj file is a property list, stored in a format almost identical to the NeXTstep property list format. The file is able to carry Unicode data, and is encoded in UTF-8. The root element in the property list is a dictionary that contains several properties of minimal interest, and two properties of immense interest. The most important property is a dictionary named "objects". The entire structure of the project is represented by the children of this property. The objects dictionary is keyed by unique 96-bit values represented by 24 uppercase hexadecimal characters. Each value in the objects dictionary is itself a dictionary, describing an individual object. Each object in the dictionary is a member of a class, which is identified by the "isa" property of each object. A variety of classes are represented in a project file. Objects can refer to other objects by ID, using the 24-character hexadecimal object key. A project's objects form a tree, with a root object of class PBXProject at the root. As an example, the PBXProject object serves as parent to an XCConfigurationList object defining the build configurations used in the project, a PBXGroup object serving as a container for all files referenced in the project, and a list of target objects, each of which defines a target in the project. There are several different types of target object, such as PBXNativeTarget and PBXAggregateTarget. In this module, this relationship is expressed by having each target type derive from an abstract base named XCTarget. The project.pbxproj file's root dictionary also contains a property, sibling to the "objects" dictionary, named "rootObject". The value of rootObject is a 24-character object key referring to the root PBXProject object in the objects dictionary. In Xcode, every file used as input to a target or produced as a final product of a target must appear somewhere in the hierarchy rooted at the PBXGroup object referenced by the PBXProject's mainGroup property. A PBXGroup is generally represented as a folder in the Xcode application. PBXGroups can contain other PBXGroups as well as PBXFileReferences, which are pointers to actual files. Each XCTarget contains a list of build phases, represented in this module by the abstract base XCBuildPhase. Examples of concrete XCBuildPhase derivations are PBXSourcesBuildPhase and PBXFrameworksBuildPhase, which correspond to the "Compile Sources" and "Link Binary With Libraries" phases displayed in the Xcode application. Files used as input to these phases (for example, source files in the former case and libraries and frameworks in the latter) are represented by PBXBuildFile objects, referenced by elements of "files" lists in XCTarget objects. Each PBXBuildFile object refers to a PBXBuildFile object as a "weak" reference: it does not "own" the PBXBuildFile, which is owned by the root object's mainGroup or a descendant group. In most cases, the layer of indirection between an XCBuildPhase and a PBXFileReference via a PBXBuildFile appears extraneous, but there's actually one reason for this: file-specific compiler flags are added to the PBXBuildFile object so as to allow a single file to be a member of multiple targets while having distinct compiler flags for each. These flags can be modified in the Xcode applciation in the "Build" tab of a File Info window. When a project is open in the Xcode application, Xcode will rewrite it. As such, this module is careful to adhere to the formatting used by Xcode, to avoid insignificant changes appearing in the file when it is used in the Xcode application. This will keep version control repositories happy, and makes it possible to compare a project file used in Xcode to one generated by this module to determine if any significant changes were made in the application. Xcode has its own way of assigning 24-character identifiers to each object, which is not duplicated here. Because the identifier only is only generated once, when an object is created, and is then left unchanged, there is no need to attempt to duplicate Xcode's behavior in this area. The generator is free to select any identifier, even at random, to refer to the objects it creates, and Xcode will retain those identifiers and use them when subsequently rewriting the project file. However, the generator would choose new random identifiers each time the project files are generated, leading to difficulties comparing "used" project files to "pristine" ones produced by this module, and causing the appearance of changes as every object identifier is changed when updated projects are checked in to a version control repository. To mitigate this problem, this module chooses identifiers in a more deterministic way, by hashing a description of each object as well as its parent and ancestor objects. This strategy should result in minimal "shift" in IDs as successive generations of project files are produced. THIS MODULE This module introduces several classes, all derived from the XCObject class. Nearly all of the "brains" are built into the XCObject class, which understands how to create and modify objects, maintain the proper tree structure, compute identifiers, and print objects. For the most part, classes derived from XCObject need only provide a _schema class object, a dictionary that expresses what properties objects of the class may contain. Given this structure, it's possible to build a minimal project file by creating objects of the appropriate types and making the proper connections: config_list = XCConfigurationList() group = PBXGroup() project = PBXProject({'buildConfigurationList': config_list, 'mainGroup': group}) With the project object set up, it can be added to an XCProjectFile object. XCProjectFile is a pseudo-class in the sense that it is a concrete XCObject subclass that does not actually correspond to a class type found in a project file. Rather, it is used to represent the project file's root dictionary. Printing an XCProjectFile will print the entire project file, including the full "objects" dictionary. project_file = XCProjectFile({'rootObject': project}) project_file.ComputeIDs() project_file.Print() Xcode project files are always encoded in UTF-8. This module will accept strings of either the str class or the unicode class. Strings of class str are assumed to already be encoded in UTF-8. Obviously, if you're just using ASCII, you won't encounter difficulties because ASCII is a UTF-8 subset. Strings of class unicode are handled properly and encoded in UTF-8 when a project file is output. iNs^[A-Za-z0-9$./_]+$t___s [\\"]|[-]s^\$\((.*?)\)(/(.*))?$cCsLtj|}|r6|jd}|jd}n d}|}||fS(sGiven input_path, returns a tuple with sourceTree and path values. Examples: input_path (source_tree, output_path) '$(VAR)/path' ('VAR', 'path') '$(VAR)' ('VAR', None) 'path' (None, 'path') iiN(t_path_leading_variabletmatchtgrouptNone(t input_pathtsource_group_matcht source_treet output_path((s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pytSourceTreeAndPathFromPaths cCstjdd|S(Ns \$\((.*?)\)s${\1}(tretsub(t input_string((s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pytConvertVariablesToShellSyntaxstXCObjectcBseZdZiZeZgZdZx1eedkrWej deedZq'Wdeds<%s %r at 0x%x>(tNametNotImplementedErrort __class__t__name__R(Rtname((s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pyt__repr__+s  cCs|jd|jd|j}x|jjD]\}}|j|d}t|tr|r|j}||_||j|iN(tupdatetstructtpacktlen(thashtdata((s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pyt _HashUpdates iit>tIis %08X%08X%08XN(Rt _new_sha1R*R5R:tAssertionErrorR6tChildrent ComputeIDsRt digest_sizeR8tunpacktdigesttxrangettuple(Rt recursivet overwritet seed_hashR=R;R4thashablethashables_for_childt child_hashtchildtdigest_int_countt digest_intstid_intstindex((s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pyRCs4            cCsi}|j}xx|D]p}|j|kr|||j}td|jt|jt|j|jdjfn|||jtj|r#tj| r#|Sdtj|j|dS(s[Encodes a string to be placed in the project file output, mimicing Xcode behavior. Re(t _unquotedtsearcht_quotedt_escapedR Ri(RR-((s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pyt _EncodeStrings"cCs|jd||dS(Ns (twrite(Rtfilettabstline((s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pyt_XCPrint;sc Cs{d}d}|jr*d}d}d}nd}d|d}d|}t|trs||j7}|j}nt|tr||j|7}nt|tr||j|j d7}nt|t r|t|7}nit|t r|rQt |dkrQt |dkr7||jd7}q||j|d7}qQd|}x7|D]/} |||j |d| |d |7}qbW||d 7}nt|tr7d |}xdt|jD]P\} } |||j |d| |d |j |d| |d |7}qW||d7}ntd|jjd|dkrw|d|j|7}n|S(sNReturns a representation of value that may be printed in a project file, mimicing Xcode's behavior. _XCPrintableValue can handle str and int values, XCObjects (which are made printable by returning their id property), and list and dict objects composed of any of the above types. When printing a list or dict, and _should_print_single_line is False, the tabs parameter is used to determine how much to indent the lines corresponding to the items in the list or dict. If flatten_list is True, single-element lists will be transformed into strings. tRs s isutf-8it(t,t)t{s = t;t}s Can't make s printableN(Rt_should_print_single_lineR!RRR2R#RnR$tencodeR%R&R:t_XCPrintableValueR(tsortedRR)RRRd( RRqR-t flatten_listt printableRctsept element_tabstend_tabsR0titem_keyt item_value((s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pyR}>sN      * 9  c Cs|jrd}d}nd|}d}|dkrOt|trO|j}n|}|dkryt|tryt}nt}|dkrt|trt} nt} y|j||| } |j||| } |rt | dkr| d d kr| d d kr| dd !} n|| d | d |7}Wn-t k rh} t j j | d|nX|j|d |dS(s,Prints a key and value, members of an XCObject's _properties dictionary, to file. tabs is an int identifying the indentation level. If the class' _should_print_single_line variable is True, tabs is ignored and the key-value pair will be followed by a space insead of a newline. RtRs s tremoteGlobalIDStringtsettingst buildSettingsiiReis = Ryswhile printing key "%s"N(R{R!tPBXContainerItemProxyRt PBXBuildFiletTruetFalsetXCBuildConfigurationR}R:R)tgyptcommontExceptionAppendRs( RRpRqR,R-Rtafter_kvtvalue_to_printtstrip_value_quotesRt printable_keytprintable_valuete((s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pyt _XCKVPrints8             cCs|j|jr"d}d}n d}d}|j|d|jd|d||j|dd|jjx9t|jj D]"\}}|j|d||qW|j||dd S( s[Prints a reprentation of this object to file, adhering to Xcode output formatting. Rtis is = {itisas}; N( tVerifyHasRequiredPropertiesR{RsR}RRRR~RR(RRpRRR]R-((s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pytPrints   '"c Cs|dkrdSx|jD]\}}||jkrUt|d|jjn|j|dd!\}}}|r,|jtkrt|d|jjd|jjnx|D]l}t|| r|jt ko|t k rtd|d|jjd|jd |jjqqWnbt|| r|jt koT|t k rt|d|jjd|jd |jjn|rt|t r|r|j |j |scCs||jkr,t|d|jjn|j|dd!\}}}|spt|d|jjdnt||std|d|jjd|jd|jjn||jkrg|j|    '  A >& R      tXCHierarchicalElementcBs eZdZejjZeji deddgd6deddgd6deddgd6deddgd6deddgd6dedddgd 6deddgd 6deddgd 6deddgd 6dddd Z dZ dZ dZ dZdZdZRS(sVAbstract base for PBXGroup and PBXFileReference. Not represented in a project file.itcommentst fileEncodingtincludeInIndext indentWidtht lineEndingist sourceTreettabWidthtusesTabst wrapsLinescCsHtj||||d|jkr~d|jkr~|jd}tj|}|dkr~||kr~|jd|q~nd|jkrDd|jks|jddkrDt|jd\}}|dkr||jd(RRRt posixpathtbasenameRR R(RRRRRRR((s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pyRs$    cCs<d|jkr|jdSd|jkr4|jdSdSdS(NRR(RR(R((s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pyRs   cCs||jjdkr&tj|Sg}d|jkri|j|jjd|j|jdn|j}|dkr|j t j }x5|D]*}|j|jjd|j|qWn|j |j |S(sCCustom hashables for XCHierarchicalElements. XCHierarchicalElements are special. Generally, their hashes shouldn't change if the paths don't change. The normal XCObject implementation of Hashables adds a hashable for each object, which means that if the hierarchical structure changes (possibly due to changes caused when TakeOverOnlyChild runs and encounters slight changes in the hierarchy), the hashes will change. For example, if a project file initially contains a/b/f1 and a/b becomes collapsed into a/b, f1 will have a single parent a/b. If someone later adds a/f2 to the project file, a/b can no longer be collapsed, and f1 winds up with parent b and grandparent a. That would be sufficient to change f1's hash. To counteract this problem, hashables for all XCHierarchicalElements except for the main group (which has neither a name nor a path) are taken to be just the set of path components. Because hashables are inherited from parents, this provides assurance that a/b/f1 has the same set of hashables whether its parent is b or a/b. The main group is a special case. As it is permitted to have no name or path, it is permitted to use the standard XCObject hash mechanism. This is not considered a problem because there can be only one main group. t mainGroupRs.names.pathN(RaRRR5R'RRtPathFromSourceTreeAndPathRtsplitRRR3R(RR4Rt componentst component((s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pyR5s    cCsnidt6dt6dt6}||j}||j}||krZt|j|jS|dkrjdSdS(NRpRii(tPBXFileReferencetPBXGrouptPBXVariantGroupRtcmpR(RRZtvalid_class_typest self_typet other_type((s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pytCompares     c Csddddddg}|j}|j}t|toH||k}t|toc||k}| r| r|j|S||kr||krdS||kr||krdS|j|}|j|}||krdS||krdSd S( NtSourcet IntermediatestProjectst FrameworkstProductstBuildiii(RR!RRRS( RRZtordert self_namet other_nametself_intother_int self_indext other_index((s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pytCompareRootGroups&      cCsg}|jddkr8|jd|jddnd|jkr^|j|jdnt|dkr}tj|SdS(NRss$(RwRi(RR'R:RtjoinR(RR((s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pyR#s cCs|}d}xt|tr|dksJ|jd r|jd r|j}|dkr|dkrtj||}n|dkr|}n|j}qW|S(Nt/t$(RR!Rt startswithRRRR(RtxcheRt this_path((s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pytFullPath3s      N(RRRRR R*R7R#R%RRRR5RRRR(((s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pyR|s&  7  ! RcBseZdZejjZejideddggd6deddgd6deddgd6ddddZ dZ dZ d Z d Z d Zd Zd ZdZdZedZdZRS(s Attributes: _children_by_path: Maps pathnames of children of this PBXGroup to the actual child XCHierarchicalElement objects. _variant_children_by_name_and_path: Maps (name, path) tuples of PBXVariantGroup children to the actual child PBXVariantGroup objects. iR\iRRcCsYtj||||i|_i|_x*|jjdgD]}|j|q>WdS(NR\(RRt_children_by_patht"_variant_children_by_name_and_pathRtgett_AddChildToDicts(RRRRRO((s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pyRXs   cCs[tj|}xE|jjdgD].}|j}|dkr%|j|q%q%W|S(NR\(RR5RRRRR'(RR4ROt child_name((s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pyR5`s   cCs tj|S(N(RR5(R((s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pyR6oscCs|j}|rD||jkr4td|n||j|RRN( R:RRRRRRRRRtTakeOverOnlyChild(RtrecurseROtold_properties((s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pyR5s6       cCs[t|jddd|jd}s(R~RR!Rt SortGroup(RRO((s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pyR{s#N(RRRRR R*R7R#RRR5R6RRRRRRRRRR(((s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pyRHs$        ]  FtXCFileLikeElementcBseZdZRS(cCs{g}|}xh|dkrvt|trv|j}x1tdt|D]}|j|||qLW|j}qW|S(Ni(RR!RR5RGR:tinsertR(RR4Rtxche_hashablesRS((s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pyt PathHashabless  (RRR (((s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pyRstXCContainerPortalcBseZRS((RR(((s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pyR stXCRemoteObjectcBseZRS((RR(((s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pyR sRcBseZejjZejideddgd6deddgd6deddgd6deddgd6eZej Z ddddZ RS(itexplicitFileTypetlastKnownFileTypeRiRc Csttj||||d|jkr\|jdjdr\|jdd |jd6d=d?6d@dA6dBdC6dDdE6dFdG6d dH6dIdJ6dKdL6dMdN6dOdP6dQdR6dSdT6}idd6dd6dd6}|rdU}d}nntj|jd} tj| \} } | dVkr<| dWj } n|j | dX}|j | d}||j||}q||krtd|qqW|S(sGets the build setting for key. All child XCConfiguration objects must have the same value set for the setting, or a ValueError will be raised. RKsVariant values for N(RRRCR(RR,R-RNRS((s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pyRCss    cCs,x%|jdD]}|j||qWdS(s[Sets the build setting for key to value in all child XCBuildConfiguration objects. RKN(RRD(RR,R-RN((s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pyRDscCs,x%|jdD]}|j||qWdS(s{Appends value to the build setting for key, which is treated as a list, in all child XCBuildConfiguration objects. RKN(RRE(RR,R-RN((s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pyREscCs)x"|jdD]}|j|qWdS(sSDeletes the build setting key from all child XCBuildConfiguration objects. RKN(RRF(RR,RN((s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pyRFscCs)x"|jdD]}|j|qWdS(sLSets the build configuration in all child XCBuildConfiguration objects. RKN(RRG(RR-RN((s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pyRGs(RRRt_configsRR R*R7R%R#RRORPRBRCRDRERFRG(((s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pyRH5s      "    RcBskeZejjZejideddgd6deddgd6eZ ej Z dZ dZ RS(iitfileRefRcCs"|jdjd|jjS(NRUs in (RRR(R((s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pyRscCs-tj|}|j|jdj|S(NRU(RR5R3RR (RR4((s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pyR5s(RRRR R*R7RR#RR{RRfRR5(((s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pyRs   t XCBuildPhasecBseZdZejjZejidedddgd6deddggd6dedddgd6d d d dZ dZ d Z d d Z d d Zd d ZRS(s{Abstract base for build phase classes. Not represented in a project file. Attributes: _files_by_path: A dict mapping each path of a child in the files list by path (keys) to the corresponding PBXBuildFile children (values). _files_by_xcfilelikeelement: A dict mapping each XCFileLikeElement (keys) to the corresponding PBXBuildFile children (values). iiitbuildActionMasktfilest"runOnlyForDeploymentPostprocessingcCsYtj||||i|_i|_x*|jjdgD]}|j|q>WdS(NRX(RRt_files_by_patht_files_by_xcfilelikeelementRRt_AddBuildFileToDicts(RRRRt pbxbuildfile((s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pyRs   cCst|jjddS(Ns must implement FileGroup(RRR(RR((s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pyt FileGroupscCs3||jkr"td|n||j||jdD]}|j|jq^Wn|j|jx|D]}|j||qW||jkr|j||krtd|j n||j||jdrd}|d}ntd||jjf||j d<||j d(RRRRR(RtpropsR((s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pyRs cCs |jjS(N(RR(R((s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pyRscCsGtj|}|j|jdj|j|jdj|S(NRR(RR5R3R(RR4((s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pyR5s( RRRR R*R7R R%R R#RRR5(((s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pyRs   tPBXTargetDependencycBs{eZejjZejideddgd6ddjddgd6de ddgd6dZ dZ dZ RS( iRttargetit targetProxycCsB|jjdp"|jdj}d|jj|t|fS(NRRs<%s %r at 0x%x>(RRRRRR(RR((s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pyR4s%cCs |jjS(N(RR(R((s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pyR8scCs-tj|}|j|jdj|S(NR(RR5R3R(RR4((s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pyR5<sN( RRRR R*R7R#RRRRRR5(((s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pyR#s    RcBs]eZejjZejideddgd6deddgd6deddgd6RS(iiRRR(RRRR R*R7R#R(((s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pyREs  tXCTargetcBseZejjZejideddegd6deddggd6deddggd6de ddgd6de ddgd6dddddddZ dZ d Z d Zd Zd Zd ZdZdZRS(iitbuildConfigurationListt buildPhasest dependenciesRt productNamecCstj||||d|jkrQd|jkrQ|jd|jdqQnd|jkrd|jkr|jd}|jddkr|jd|jdqqndS(NRRRt PRODUCT_NAMEi(R RRRRBRD(RRRRt force_outdirt force_prefixtforce_extensiontconfigs((s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pyR`s  cCs|j}|j}||krti|d6dd6|d6|jd6}ti|d6|d6}|jd|nq|j|d}ti|d6dd6|d6|jd6}ti|jd 6|d6}|jd|dS( NRiRRRRRRR(RaRRRRtAddOrGetProjectReference(RRZt pbxprojecttother_pbxprojectt containert dependencytother_project_ref((s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pyt AddDependencyts&       cCs|jdj|S(NR(RRO(RR((s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pyROscCs|jdjS(NR(RRP(R((s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pyRPscCs|jdj|S(NR(RRB(RR,((s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pyRBscCs|jdj|S(NR(RRC(RR,((s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pyRCscCs|jdj||S(NR(RRD(RR,R-((s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pyRDscCs|jdj||S(NR(RRE(RR,R-((s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pyREscCs|jdj|S(NR(RRF(RR,((s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pyRFsN(RRR R R*R7RHRVRR#RRRRORPRBRCRDRERF(((s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pyRNs$           RitPBXNativeTargetcBseZejjZejideddeeggd6de ddggd6de ddgd6de ddgd6i dddgd 6dddgd 6d dd gd 6d dd gd6dddgd6dddgd6dddgd6dddgd6dddgd6dddgd6ddd gd!6d"dd#gd$6Z d,d,d,d,d,d,d%Zd&Zd'Zd(Zd)Zd*Zd+ZRS(-iRt buildRulesitproductReferencet productTypeswrapper.applicationRts.apps"com.apple.product-type.applications+com.apple.product-type.application.watchappswrapper.app-extensions.appexs)com.apple.product-type.watchkit-extensions$com.apple.product-type.app-extensionswrapper.cfbundles.bundlescom.apple.product-type.bundleswrapper.frameworks .frameworks com.apple.product-type.frameworkscompiled.mach-o.dylibtlibs.dylibs&com.apple.product-type.library.dynamics archive.ars.as%com.apple.product-type.library.staticscompiled.mach-o.executablescom.apple.product-type.tools.xctests'com.apple.product-type.bundle.unit-tests.soscom.googlecode.gyp.xcode.bundles wrapper.kexts.kexts'com.apple.product-type.kernel-extensioncCstj||||d|jkrd|jkrd|jkr|jd|jkrd}|j}|dkr|j}n|dkr|j|jd\} } } |jddkrd|jd<|jdd|jdd |jd d |dkr| d }qn|jdd krJ|dkrJ| d }qJn|dk rd |} | jdr|jd|n|jd|| jdr|jd} | | 7} d } |j d| |jd| qn|dk r|} n| jdr|jd| n|jd| |dk rJ|jd|n|jd} t | } | r| | | kr| | } |j d| |jd| ni| d6dd6| | | d6dd6}t |}|j ||j d|qndS(NRRRscom.googlecode.gyp.xcode.bundles&com.apple.product-type.library.dynamict MACH_O_TYPEt mh_bundletDYLIB_CURRENT_VERSIONRttDYLIB_COMPATIBILITY_VERSIONis'com.apple.product-type-bundle.unit.testt.swrapper.tWRAPPER_EXTENSIONtEXECUTABLE_EXTENSIONscompiled.mach-o.executableRtWRAPPER_PREFIXtEXECUTABLE_PREFIXtTARGET_BUILD_DIRR iRRR{R( RRRt_product_filetypesRRat ProductsGroupRDRRR:RR(RRRRRRRtproducts_groupRtfiletypetprefixtsuffixt product_namet prefix_lent ref_propsR((s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pyRsl                     cCs_d|jkrdSd}x?|jdD]0}t||r'|dksNt|}q'q'W|S(NR(RRR!RA(Rttypet the_phasetphase((s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pytGetBuildPhaseByTypeK s cCs|jt}|dkrt}t|jd}xltdt|jdD]N}|jd|}t|tst|tst|t rT|}PqTqTW|jdj ||||_ n|S(NRi( RRgRR:RRGR!RjRlRnRR(Rt headers_phaset insert_atRSR((s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pyt HeadersPhase\ s  # cCs|jt}|dkrt}t|jd}x]tdt|jdD]?}|jd|}t|tst|trT|}PqTqTW|jdj ||||_ n|S(NRi( RRjRR:RRGR!RlRnRR(Rtresources_phaseRRSR((s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pytResourcesPhaseq s  # cCs;|jt}|dkr7t}|jd|n|S(NR(RRlRR(Rt sources_phase((s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pyt SourcesPhase s   cCs;|jt}|dkr7t}|jd|n|S(NR(RRnRR(Rtframeworks_phase((s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pytFrameworksPhase s   c CsBtj||d}d}d}t|tr>d|jkr>|jd|kr>d|jkr>|jd|ks|jd|ks|jd|kr>|jd s|jddkr>|jd}|j}|j}||kr|j |d}|j |}n|j j d t i|d 6ndS( Ns%com.apple.product-type.library.statics&com.apple.product-type.library.dynamics com.apple.product-type.frameworkRRRRiRXRU(RRR!RRRBRCRRaRRRRR( RRZtstatic_library_typetshared_library_typetframework_typeRRRtother_project_product_group((s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pyR s*   N(RRRR R*R7RVRlRnRRR#RRRRRRRRR(((s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pyRsP               l     tPBXAggregateTargetcBseZRS((RR(((s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pyR st PBXProjectcBseZdZejjZeji deddgd6deddegd6de dddgd6de dddgd6de dde gd6de ddd gd 6deddgd 6de ddd gd 6de ddggd 6d$d$d$d$dZdZdZdZdZdZdZdZdZdZdZdZdZdZedZdZdZdZ d Z!d!Z"d"Z#d#Z$RS(%sE Attributes: path: "sample.xcodeproj". TODO(mark) Document me! _other_pbxprojects: A dictionary, keyed by other PBXProject objects. Each value is a reference to the dict in the projectReferences list associated with the keyed PBXProject. iR^iRs Xcode 3.2tcompatibilityVersionthasScannedForEncodingsRRttprojectDirPathtprojectReferencest projectRootttargetscCs(||_i|_tj||||S(N(Rt_other_pbxprojectsR R(RRRRR((s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pyR s  cCs3|j}|ddkr&|d }ntj|S(Nis .xcodeproj(RRR(RR((s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pyR s  cCs|jS(N(R(R((s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pytPath scCsdS(NsProject object((R((s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pyR2 scCsNtj|}d|jkrJx)|jdD]}|j|dq,Wn|S(NRt ProductGroup(R RBRR'(RR\t reference((s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pyRB s cCs|S(N((R((s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pyRa scCstd|jkr%|jdtn|jd}|j|}|dkrpti|d6}|j|n|S(NRR(RRRRRR(RRt main_groupR((s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pyt _GroupByName s  cCs |jdS(NR(R(R((s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pyt SourceGroup scCs |jdS(NR(R(R((s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pyR scCs |jdS(NR(R(R((s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pytIntermediatesGroup scCs |jdS(NR(R(R((s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pyRo scCs |jdS(NR(R(R((s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pyt ProjectsGroup scCsi|jtfd6|jtfd6|jtfd6|jtfd6}t|\}}|dkr||kr||\}}|}||fS|jtfS(sReturns a PBXGroup child of this object to which path should be added. This method is intended to choose between SourceGroup and IntermediatesGroup on the basis of whether path is present in a source directory or an intermediates directory. For the purposes of this determination, any path located within a derived file directory such as PROJECT_DERIVED_FILE_DIR is treated as being in an intermediates directory. The returned value is a two-element tuple. The first element is the PBXGroup, and the second element specifies whether that group should be organized hierarchically (True) or as a single flat list (False). tDERIVED_FILE_DIRtINTERMEDIATE_DIRtPROJECT_DERIVED_FILE_DIRtSHARED_INTERMEDIATE_DIRN(RRR RR(RRtsource_tree_groupsRt group_funcRR((s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pyRi s  cCs%|j|\}}|j||S(sReturns a PBXFileReference corresponding to path in the correct group according to RootGroupForPath's heuristics. If an existing PBXFileReference for path exists, it will be returned. Otherwise, one will be created and returned. (RiR(RRRR((s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pytAddOrGetFileInRootGroup= scCsBx;|jdjdD]%}t|tr|j|qqWdS(s9Calls TakeOverOnlyChild for all groups in the main group.RR\N(RR!RR(RRR((s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pytRootGroupsTakeOverOnlyChildrenH scCs t|jdjddd|jdjd sN(RRRRRRR3R5RRRRtisabsRRRt RelativePathRRRRR~t_SetUpProductReferencesRRtall( RRt product_groupt project_refRRt other_pathtref_dicttproject_ref_dictRtdir_path((RRs3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pyRr sD    &    cCsj|j|}xJ|j|D]9}|dk rA|j| sT|dkr| rtSqW|rftS|S(N(t_DefinedSymrootsRt_IsUniqueSymrootForTargetRR(RRRtsymrootsR.((s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pyR s cCs|jd}t}xS|jdD]B}|jd}d|kr]|j|dq(|jdq(Wt|dkrd|krtS|S(NRRKRtSYMROOTi(RtsettaddRR:(RRt config_listRtconfigtsetting((s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pyR s  cs0ddg}tfd|Dr,tStS(Ns$SRCROOTs $(SRCROOT)c3s|]}|kVqdS(N((RR(tsymroot(s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pys s(tanyRR(RRt uniquifier((Rs3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pyR s cCsx|jdD]}t|ts)qn|jd}|j|dkrti|d6dd6|d6|jd6}ti|jdd 6|jd d 6|jd d 6|d 6}|j|qqWdS( NRRRiRRRR RRRR( RR!RRRRRRR(RRRRRt other_filereftcontainer_itemtreference_proxy((s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pyR s   csdx|jjD]\}}g}x>|jdD]/}t|tsTq9n|j|jdq9W|d}t|jdd|fd|jd\}}|dkr|j|q{|j|d||q{W|j|dd |jd=dS( Ntobjectsis// !$*UTF8*$! s{ s{ RcSs t||S(N(R(RR((s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pyRM sis} (RRRsR{R~Rt _PrintObjectsR(RRpR]R-((s3ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pyR@ s    cCs^|jr|j|ddn|j|ddi}x\|jD]N}||kr]qEn|jj}||krg||sd            >f s   H-" \z