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

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
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 950 matching lines...) Expand 10 before | Expand all | Expand 10 after
961 str = str.replace(to_replace, '${' + variable + '}') 961 str = str.replace(to_replace, '${' + variable + '}')
962 962
963 return str 963 return str
964 964
965 965
966 def ExpandEnvVars(string, expansions): 966 def ExpandEnvVars(string, expansions):
967 """Expands ${VARIABLES}, $(VARIABLES), and $VARIABLES in string per the 967 """Expands ${VARIABLES}, $(VARIABLES), and $VARIABLES in string per the
968 expansions dict. If the variable expands to something that references 968 expansions dict. If the variable expands to something that references
969 another variable, this variable is expanded as well if it's in env -- 969 another variable, this variable is expanded as well if it's in env --
970 until no variables present in env are left.""" 970 until no variables present in env are left."""
971 for k in reversed(TopologicallySortedEnvVarKeys(expansions)): 971 for k in TopologicallySortedEnvVarKeys(expansions):
972 string = string.replace('${' + k + '}', expansions[k]) 972 string = string.replace('${' + k + '}', expansions[k])
973 string = string.replace('$(' + k + ')', expansions[k]) 973 string = string.replace('$(' + k + ')', expansions[k])
974 string = string.replace('$' + k, expansions[k]) 974 string = string.replace('$' + k, expansions[k])
975 return string 975 return string
976 976
977 977
978 def TopologicallySortedEnvVarKeys(env): 978 def TopologicallySortedEnvVarKeys(env):
979 """Takes a dict |env| whose values are strings that can refer to other keys, 979 """Takes a dict |env| whose values are strings that can refer to other keys,
980 for example env['foo'] = '$(bar) and $(baz)'. Returns a list L of all keys of 980 for example env['foo'] = '$(bar) and $(baz)'. Returns a list L of all keys of
981 env such that key2 is after key1 in L if env[key2] refers to env[key1]. 981 env such that key1 is after key2 in L if env[key2] refers to env[key1].
982 982
983 Throws an Exception in case of dependency cycles. 983 Throws an Exception in case of dependency cycles.
984 """ 984 """
985 # Since environment variables can refer to other variables, the evaluation 985 # Since environment variables can refer to other variables, the evaluation
986 # order is important. Below is the logic to compute the dependency graph 986 # order is important. Below is the logic to compute the dependency graph
987 # and sort it. 987 # and sort it.
988 regex = re.compile(r'\$\{([a-zA-Z0-9\-_]+)\}') 988 regex = re.compile(r'\$\{([a-zA-Z0-9\-_]+)\}')
989 989 def GetEdges(node):
Nico 2012/05/11 14:53:44 This function is the wrong way round. We want an e
bradn 2012/05/11 18:57:23 Done.
990 # First sort the list of keys. 990 # Get all variable references for variable defined in env.
991 key_list = sorted(env.keys()) 991 matches = set([v for v in regex.findall(env[node]) if v in env])
992
993 # Phase 1: Create a set of edges of (DEPENDEE, DEPENDER) where in the graph,
994 # DEPENDEE -> DEPENDER. Also create sets of dependers and dependees.
995 edges = set()
996 dependees = set()
997 dependers = set()
998 for k in key_list:
999 matches = regex.findall(env[k])
1000 if not len(matches):
1001 continue
1002
1003 depends_on_other_var = False
1004 for dependee in matches: 992 for dependee in matches:
1005 assert '${' not in dependee, 'Nested variables not supported: ' + dependee 993 assert '${' not in dependee, 'Nested variables not supported: ' + dependee
1006 if dependee in env: 994 return matches
1007 edges.add((dependee, k))
1008 dependees.add(dependee)
1009 depends_on_other_var = True
1010 if depends_on_other_var:
1011 dependers.add(k)
1012 995
1013 # Phase 2: Create a list of graph nodes with no incoming edges. 996 try:
1014 sorted_nodes = [] 997 return gyp.common.TopologicallySorted(env.keys(), GetEdges)
1015 edgeless_nodes = dependees - dependers 998 except CycleError, e:
1016 999 raise Exception(
1017 # Phase 3: Perform Kahn topological sort. 1000 'Xcode environment variables are cyclically dependent: ' + str(e.nodes))
1018 while len(edgeless_nodes):
1019 # Find a node with no incoming edges, add it to the sorted list, and
1020 # remove it from the list of nodes that aren't part of the graph.
1021 node = edgeless_nodes.pop()
1022 sorted_nodes.append(node)
1023 key_list.remove(node)
1024
1025 # Find all the edges between |node| and other nodes.
1026 edges_to_node = [e for e in edges if e[0] == node]
1027 for edge in edges_to_node:
1028 edges.remove(edge)
1029 # If the node connected to |node| by |edge| has no other incoming edges,
1030 # add it to |edgeless_nodes|.
1031 if not len([e for e in edges if e[1] == edge[1]]):
1032 edgeless_nodes.add(edge[1])
1033
1034 # Any remaining edges indicate a cycle.
1035 if len(edges):
1036 raise Exception('Xcode environment variables are cyclically dependent: ' +
1037 str(edges))
1038
1039 # Append the "nodes" not in the graph to those that were just sorted.
1040 sorted_nodes.extend(key_list)
1041
1042 return sorted_nodes
1043 1001
1044 1002
1045 def GetSpecPostbuildCommands(spec, quiet=False): 1003 def GetSpecPostbuildCommands(spec, quiet=False):
1046 """Returns the list of postbuilds explicitly defined on |spec|, in a form 1004 """Returns the list of postbuilds explicitly defined on |spec|, in a form
1047 executable by a shell.""" 1005 executable by a shell."""
1048 postbuilds = [] 1006 postbuilds = []
1049 for postbuild in spec.get('postbuilds', []): 1007 for postbuild in spec.get('postbuilds', []):
1050 if not quiet: 1008 if not quiet:
1051 postbuilds.append('echo POSTBUILD\\(%s\\) %s' % ( 1009 postbuilds.append('echo POSTBUILD\\(%s\\) %s' % (
1052 spec['target_name'], postbuild['postbuild_name'])) 1010 spec['target_name'], postbuild['postbuild_name']))
1053 postbuilds.append(gyp.common.EncodePOSIXShellList(postbuild['action'])) 1011 postbuilds.append(gyp.common.EncodePOSIXShellList(postbuild['action']))
1054 return postbuilds 1012 return postbuilds
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698