OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |