Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(69)

Side by Side Diff: pylib/gyp/xcode_emulation.py

Issue 10378042: Correct the order in which OutputDirectory and IntermediateDirectory are defined. (Closed) Base URL: http://gyp.googlecode.com/svn/trunk/
Patch Set: Created 8 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « pylib/gyp/generator/msvs.py ('k') | test/msvs/shared_output/common.gypi » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright (c) 2012 Google Inc. All rights reserved. 1 # Copyright (c) 2012 Google Inc. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 """ 5 """
6 This module contains classes that help to emulate xcodebuild behavior on top of 6 This module contains classes that help to emulate xcodebuild behavior on top of
7 other build systems, such as make and ninja. 7 other build systems, such as make and ninja.
8 """ 8 """
9 9
10 import gyp.common 10 import gyp.common
(...skipping 943 matching lines...) Expand 10 before | Expand all | Expand 10 after
954 str = str.replace(to_replace, '${' + variable + '}') 954 str = str.replace(to_replace, '${' + variable + '}')
955 955
956 return str 956 return str
957 957
958 958
959 def ExpandEnvVars(string, expansions): 959 def ExpandEnvVars(string, expansions):
960 """Expands ${VARIABLES}, $(VARIABLES), and $VARIABLES in string per the 960 """Expands ${VARIABLES}, $(VARIABLES), and $VARIABLES in string per the
961 expansions dict. If the variable expands to something that references 961 expansions dict. If the variable expands to something that references
962 another variable, this variable is expanded as well if it's in env -- 962 another variable, this variable is expanded as well if it's in env --
963 until no variables present in env are left.""" 963 until no variables present in env are left."""
964 for k in reversed(TopologicallySortedEnvVarKeys(expansions)): 964 for k in TopologicallySortedEnvVarKeys(expansions):
Nico 2012/05/11 19:03:34 You removed a reversed() here. That should probabl
bradn 2012/05/11 20:10:31 Done. Ah yes, that's likely it.
965 string = string.replace('${' + k + '}', expansions[k]) 965 string = string.replace('${' + k + '}', expansions[k])
966 string = string.replace('$(' + k + ')', expansions[k]) 966 string = string.replace('$(' + k + ')', expansions[k])
967 string = string.replace('$' + k, expansions[k]) 967 string = string.replace('$' + k, expansions[k])
968 return string 968 return string
969 969
970 970
971 def TopologicallySortedEnvVarKeys(env): 971 def TopologicallySortedEnvVarKeys(env):
972 """Takes a dict |env| whose values are strings that can refer to other keys, 972 """Takes a dict |env| whose values are strings that can refer to other keys,
973 for example env['foo'] = '$(bar) and $(baz)'. Returns a list L of all keys of 973 for example env['foo'] = '$(bar) and $(baz)'. Returns a list L of all keys of
974 env such that key2 is after key1 in L if env[key2] refers to env[key1]. 974 env such that key2 is after key1 in L if env[key2] refers to env[key1].
Nico 2012/05/11 19:03:34 Undo comment change
bradn 2012/05/11 20:10:31 ? this has no diff now?
975 975
976 Throws an Exception in case of dependency cycles. 976 Throws an Exception in case of dependency cycles.
977 """ 977 """
978 # Since environment variables can refer to other variables, the evaluation 978 # Since environment variables can refer to other variables, the evaluation
979 # order is important. Below is the logic to compute the dependency graph 979 # order is important. Below is the logic to compute the dependency graph
980 # and sort it. 980 # and sort it.
981 regex = re.compile(r'\$\{([a-zA-Z0-9\-_]+)\}') 981 regex = re.compile(r'\$\{([a-zA-Z0-9\-_]+)\}')
982 982 def GetEdges(node):
983 # First sort the list of keys. 983 # Use a definition of edges such that user_of_variable -> used_varible.
984 key_list = sorted(env.keys()) 984 # This happens to be easier in this case, since a variable's
985 985 # definition contains all variables it references in a single string.
986 # Phase 1: Create a set of edges of (DEPENDEE, DEPENDER) where in the graph, 986 # We can then reverse the result of the topological sort at the end.
987 # DEPENDEE -> DEPENDER. Also create sets of dependers and dependees. 987 # Since: reverse(topsort(DAG)) = topsort(reverse_edges(DAG))
988 edges = set() 988 matches = set([v for v in regex.findall(env[node]) if v in env])
989 dependees = set()
990 dependers = set()
991 for k in key_list:
992 matches = regex.findall(env[k])
993 if not len(matches):
994 continue
995
996 depends_on_other_var = False
997 for dependee in matches: 989 for dependee in matches:
998 assert '${' not in dependee, 'Nested variables not supported: ' + dependee 990 assert '${' not in dependee, 'Nested variables not supported: ' + dependee
999 if dependee in env: 991 return matches
1000 edges.add((dependee, k))
1001 dependees.add(dependee)
1002 depends_on_other_var = True
1003 if depends_on_other_var:
1004 dependers.add(k)
1005 992
1006 # Phase 2: Create a list of graph nodes with no incoming edges. 993 try:
1007 sorted_nodes = [] 994 # Topologically sort, and then reverse, because we used an edge definition
1008 edgeless_nodes = dependees - dependers 995 # that's inverted from the expected result of this function (see comment
1009 996 # above).
1010 # Phase 3: Perform Kahn topological sort. 997 order = gyp.common.TopologicallySorted(env.keys(), GetEdges)
Nico 2012/05/11 19:03:34 nit: i'd just write `return reversed(gyp.common.To
bradn 2012/05/11 20:10:31 So I'm generally avoiding reversed() when its stuf
1011 while len(edgeless_nodes): 998 order.reverse()
1012 # Find a node with no incoming edges, add it to the sorted list, and 999 return order
1013 # remove it from the list of nodes that aren't part of the graph. 1000 except CycleError, e:
1014 node = edgeless_nodes.pop() 1001 raise Exception(
1015 sorted_nodes.append(node) 1002 'Xcode environment variables are cyclically dependent: ' + str(e.nodes))
1016 key_list.remove(node)
1017
1018 # Find all the edges between |node| and other nodes.
1019 edges_to_node = [e for e in edges if e[0] == node]
1020 for edge in edges_to_node:
1021 edges.remove(edge)
1022 # If the node connected to |node| by |edge| has no other incoming edges,
1023 # add it to |edgeless_nodes|.
1024 if not len([e for e in edges if e[1] == edge[1]]):
1025 edgeless_nodes.add(edge[1])
1026
1027 # Any remaining edges indicate a cycle.
1028 if len(edges):
1029 raise Exception('Xcode environment variables are cyclically dependent: ' +
1030 str(edges))
1031
1032 # Append the "nodes" not in the graph to those that were just sorted.
1033 sorted_nodes.extend(key_list)
1034
1035 return sorted_nodes
1036 1003
1037 1004
1038 def GetSpecPostbuildCommands(spec, quiet=False): 1005 def GetSpecPostbuildCommands(spec, quiet=False):
1039 """Returns the list of postbuilds explicitly defined on |spec|, in a form 1006 """Returns the list of postbuilds explicitly defined on |spec|, in a form
1040 executable by a shell.""" 1007 executable by a shell."""
1041 postbuilds = [] 1008 postbuilds = []
1042 for postbuild in spec.get('postbuilds', []): 1009 for postbuild in spec.get('postbuilds', []):
1043 if not quiet: 1010 if not quiet:
1044 postbuilds.append('echo POSTBUILD\\(%s\\) %s' % ( 1011 postbuilds.append('echo POSTBUILD\\(%s\\) %s' % (
1045 spec['target_name'], postbuild['postbuild_name'])) 1012 spec['target_name'], postbuild['postbuild_name']))
1046 postbuilds.append(gyp.common.EncodePOSIXShellList(postbuild['action'])) 1013 postbuilds.append(gyp.common.EncodePOSIXShellList(postbuild['action']))
1047 return postbuilds 1014 return postbuilds
OLDNEW
« no previous file with comments | « pylib/gyp/generator/msvs.py ('k') | test/msvs/shared_output/common.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698