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

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

Issue 10458006: mac ninja/make: Do topological sort only once instead of at each access. (Closed) Base URL: http://gyp.googlecode.com/svn/trunk/
Patch Set: Created 8 years, 6 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/ninja.py ('k') | no next file » | 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 865 matching lines...) Expand 10 before | Expand all | Expand 10 after
876 'INFOPLIST_PREPROCESSOR_DEFINITIONS', default='')) 876 'INFOPLIST_PREPROCESSOR_DEFINITIONS', default=''))
877 else: 877 else:
878 defines = [] 878 defines = []
879 879
880 dest_plist = os.path.join(product_dir, xcode_settings.GetBundlePlistPath()) 880 dest_plist = os.path.join(product_dir, xcode_settings.GetBundlePlistPath())
881 extra_env = xcode_settings.GetPerTargetSettings() 881 extra_env = xcode_settings.GetPerTargetSettings()
882 882
883 return info_plist, dest_plist, defines, extra_env 883 return info_plist, dest_plist, defines, extra_env
884 884
885 885
886 def GetXcodeEnv(xcode_settings, built_products_dir, srcroot, configuration, 886 def _GetXcodeEnv(xcode_settings, built_products_dir, srcroot, configuration,
887 additional_settings=None): 887 additional_settings=None):
888 """Return the environment variables that Xcode would set. See 888 """Return the environment variables that Xcode would set. See
889 http://developer.apple.com/library/mac/#documentation/DeveloperTools/Reference /XcodeBuildSettingRef/1-Build_Setting_Reference/build_setting_ref.html#//apple_r ef/doc/uid/TP40003931-CH3-SW153 889 http://developer.apple.com/library/mac/#documentation/DeveloperTools/Reference /XcodeBuildSettingRef/1-Build_Setting_Reference/build_setting_ref.html#//apple_r ef/doc/uid/TP40003931-CH3-SW153
890 for a full list. 890 for a full list.
891 891
892 Args: 892 Args:
893 xcode_settings: An XcodeSettings object. If this is None, this function 893 xcode_settings: An XcodeSettings object. If this is None, this function
894 returns an empty dict. 894 returns an empty dict.
895 built_products_dir: Absolute path to the built products dir. 895 built_products_dir: Absolute path to the built products dir.
896 srcroot: Absolute path to the source root. 896 srcroot: Absolute path to the source root.
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
968 for match in matches: 968 for match in matches:
969 to_replace, variable = match 969 to_replace, variable = match
970 assert '$(' not in match, '$($(FOO)) variables not supported: ' + match 970 assert '$(' not in match, '$($(FOO)) variables not supported: ' + match
971 str = str.replace(to_replace, '${' + variable + '}') 971 str = str.replace(to_replace, '${' + variable + '}')
972 972
973 return str 973 return str
974 974
975 975
976 def ExpandEnvVars(string, expansions): 976 def ExpandEnvVars(string, expansions):
977 """Expands ${VARIABLES}, $(VARIABLES), and $VARIABLES in string per the 977 """Expands ${VARIABLES}, $(VARIABLES), and $VARIABLES in string per the
978 expansions dict. If the variable expands to something that references 978 expansions list. If the variable expands to something that references
979 another variable, this variable is expanded as well if it's in env -- 979 another variable, this variable is expanded as well if it's in env --
980 until no variables present in env are left.""" 980 until no variables present in env are left."""
981 for k in reversed(TopologicallySortedEnvVarKeys(expansions)): 981 for k, v in reversed(expansions):
982 string = string.replace('${' + k + '}', expansions[k]) 982 string = string.replace('${' + k + '}', v)
983 string = string.replace('$(' + k + ')', expansions[k]) 983 string = string.replace('$(' + k + ')', v)
984 string = string.replace('$' + k, expansions[k]) 984 string = string.replace('$' + k, v)
985 return string 985 return string
986 986
987 987
988 def TopologicallySortedEnvVarKeys(env): 988 def _TopologicallySortedEnvVarKeys(env):
989 """Takes a dict |env| whose values are strings that can refer to other keys, 989 """Takes a dict |env| whose values are strings that can refer to other keys,
990 for example env['foo'] = '$(bar) and $(baz)'. Returns a list L of all keys of 990 for example env['foo'] = '$(bar) and $(baz)'. Returns a list L of all keys of
991 env such that key2 is after key1 in L if env[key2] refers to env[key1]. 991 env such that key2 is after key1 in L if env[key2] refers to env[key1].
992 992
993 Throws an Exception in case of dependency cycles. 993 Throws an Exception in case of dependency cycles.
994 """ 994 """
995 # Since environment variables can refer to other variables, the evaluation 995 # Since environment variables can refer to other variables, the evaluation
996 # order is important. Below is the logic to compute the dependency graph 996 # order is important. Below is the logic to compute the dependency graph
997 # and sort it. 997 # and sort it.
998 regex = re.compile(r'\$\{([a-zA-Z0-9\-_]+)\}') 998 regex = re.compile(r'\$\{([a-zA-Z0-9\-_]+)\}')
999 def GetEdges(node): 999 def GetEdges(node):
1000 # Use a definition of edges such that user_of_variable -> used_varible. 1000 # Use a definition of edges such that user_of_variable -> used_varible.
1001 # This happens to be easier in this case, since a variable's 1001 # This happens to be easier in this case, since a variable's
1002 # definition contains all variables it references in a single string. 1002 # definition contains all variables it references in a single string.
1003 # We can then reverse the result of the topological sort at the end. 1003 # We can then reverse the result of the topological sort at the end.
1004 # Since: reverse(topsort(DAG)) = topsort(reverse_edges(DAG)) 1004 # Since: reverse(topsort(DAG)) = topsort(reverse_edges(DAG))
1005 matches = set([v for v in regex.findall(env[node]) if v in env]) 1005 matches = set([v for v in regex.findall(env[node]) if v in env])
1006 for dependee in matches: 1006 for dependee in matches:
1007 assert '${' not in dependee, 'Nested variables not supported: ' + dependee 1007 assert '${' not in dependee, 'Nested variables not supported: ' + dependee
1008 return matches 1008 return matches
1009 1009
1010 try: 1010 try:
1011 # Topologically sort, and then reverse, because we used an edge definition 1011 # Topologically sort, and then reverse, because we used an edge definition
1012 # that's inverted from the expected result of this function (see comment 1012 # that's inverted from the expected result of this function (see comment
1013 # above). 1013 # above).
1014 order = gyp.common.TopologicallySorted(env.keys(), GetEdges) 1014 order = gyp.common.TopologicallySorted(env.keys(), GetEdges)
1015 order.reverse() 1015 order.reverse()
1016 return order 1016 return order
1017 except CycleError, e: 1017 except gyp.common.CycleError, e:
scottmg 2012/05/28 20:53:29 did this just not work before?
Nico 2012/05/28 20:57:18 Apparently. Maybe the function had no callers in
1018 raise Exception( 1018 raise Exception(
1019 'Xcode environment variables are cyclically dependent: ' + str(e.nodes)) 1019 'Xcode environment variables are cyclically dependent: ' + str(e.nodes))
1020 1020
1021 1021
1022 def GetSortedXcodeEnv(xcode_settings, built_products_dir, srcroot,
1023 configuration, additional_settings=None):
1024 env = _GetXcodeEnv(xcode_settings, built_products_dir, srcroot, configuration,
1025 additional_settings)
1026 return [(key, env[key]) for key in _TopologicallySortedEnvVarKeys(env)]
1027
1028
1022 def GetSpecPostbuildCommands(spec, quiet=False): 1029 def GetSpecPostbuildCommands(spec, quiet=False):
1023 """Returns the list of postbuilds explicitly defined on |spec|, in a form 1030 """Returns the list of postbuilds explicitly defined on |spec|, in a form
1024 executable by a shell.""" 1031 executable by a shell."""
1025 postbuilds = [] 1032 postbuilds = []
1026 for postbuild in spec.get('postbuilds', []): 1033 for postbuild in spec.get('postbuilds', []):
1027 if not quiet: 1034 if not quiet:
1028 postbuilds.append('echo POSTBUILD\\(%s\\) %s' % ( 1035 postbuilds.append('echo POSTBUILD\\(%s\\) %s' % (
1029 spec['target_name'], postbuild['postbuild_name'])) 1036 spec['target_name'], postbuild['postbuild_name']))
1030 postbuilds.append(gyp.common.EncodePOSIXShellList(postbuild['action'])) 1037 postbuilds.append(gyp.common.EncodePOSIXShellList(postbuild['action']))
1031 return postbuilds 1038 return postbuilds
OLDNEW
« no previous file with comments | « pylib/gyp/generator/ninja.py ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698