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

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 961 matching lines...) Expand 10 before | Expand all | Expand 10 after
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].
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)
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