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 import gyp | 5 import gyp |
6 import gyp.common | 6 import gyp.common |
7 import gyp.system_test | 7 import gyp.system_test |
8 import gyp.xcode_emulation | 8 import gyp.xcode_emulation |
9 import os.path | 9 import os.path |
10 import re | 10 import re |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
70 the path from the relative path back to the origin dir. | 70 the path from the relative path back to the origin dir. |
71 | 71 |
72 E.g. os.path.normpath(os.path.join(path, InvertRelativePath(path))) | 72 E.g. os.path.normpath(os.path.join(path, InvertRelativePath(path))) |
73 should always produce the empty string.""" | 73 should always produce the empty string.""" |
74 | 74 |
75 if not path: | 75 if not path: |
76 return path | 76 return path |
77 # Only need to handle relative paths into subdirectories for now. | 77 # Only need to handle relative paths into subdirectories for now. |
78 assert '..' not in path, path | 78 assert '..' not in path, path |
79 depth = len(path.split(os.path.sep)) | 79 depth = len(path.split(os.path.sep)) |
80 return '/'.join(['..'] * depth) | 80 return os.path.sep.join(['..'] * depth) |
81 | 81 |
82 | 82 |
83 class Target: | 83 class Target: |
84 """Target represents the paths used within a single gyp target. | 84 """Target represents the paths used within a single gyp target. |
85 | 85 |
86 Conceptually, building a single target A is a series of steps: | 86 Conceptually, building a single target A is a series of steps: |
87 | 87 |
88 1) actions/rules/copies generates source/resources/etc. | 88 1) actions/rules/copies generates source/resources/etc. |
89 2) compiles generates .o files | 89 2) compiles generates .o files |
90 3) link generates a binary (library/executable) | 90 3) link generates a binary (library/executable) |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
194 dir. Otherwise, |product_dir| is the relative path to the product | 194 dir. Otherwise, |product_dir| is the relative path to the product |
195 dir. | 195 dir. |
196 """ | 196 """ |
197 | 197 |
198 PRODUCT_DIR = '$!PRODUCT_DIR' | 198 PRODUCT_DIR = '$!PRODUCT_DIR' |
199 if PRODUCT_DIR in path: | 199 if PRODUCT_DIR in path: |
200 if product_dir: | 200 if product_dir: |
201 path = path.replace(PRODUCT_DIR, product_dir) | 201 path = path.replace(PRODUCT_DIR, product_dir) |
202 else: | 202 else: |
203 path = path.replace(PRODUCT_DIR + '/', '') | 203 path = path.replace(PRODUCT_DIR + '/', '') |
204 path = path.replace(PRODUCT_DIR + '\\', '') | |
204 path = path.replace(PRODUCT_DIR, '.') | 205 path = path.replace(PRODUCT_DIR, '.') |
205 | 206 |
206 INTERMEDIATE_DIR = '$!INTERMEDIATE_DIR' | 207 INTERMEDIATE_DIR = '$!INTERMEDIATE_DIR' |
207 if INTERMEDIATE_DIR in path: | 208 if INTERMEDIATE_DIR in path: |
208 int_dir = self.GypPathToUniqueOutput('gen') | 209 int_dir = self.GypPathToUniqueOutput('gen') |
209 # GypPathToUniqueOutput generates a path relative to the product dir, | 210 # GypPathToUniqueOutput generates a path relative to the product dir, |
210 # so insert product_dir in front if it is provided. | 211 # so insert product_dir in front if it is provided. |
211 path = path.replace(INTERMEDIATE_DIR, | 212 path = path.replace(INTERMEDIATE_DIR, |
212 os.path.join(product_dir or '', int_dir)) | 213 os.path.join(product_dir or '', int_dir)) |
213 | 214 |
(...skipping 690 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
904 # dir, and everything else goes into the normal place. | 905 # dir, and everything else goes into the normal place. |
905 type_in_output_root = ['executable', 'loadable_module'] | 906 type_in_output_root = ['executable', 'loadable_module'] |
906 if self.flavor == 'mac' and self.toolset == 'target': | 907 if self.flavor == 'mac' and self.toolset == 'target': |
907 type_in_output_root += ['shared_library', 'static_library'] | 908 type_in_output_root += ['shared_library', 'static_library'] |
908 | 909 |
909 if type in type_in_output_root: | 910 if type in type_in_output_root: |
910 return filename | 911 return filename |
911 elif type == 'shared_library': | 912 elif type == 'shared_library': |
912 libdir = 'lib' | 913 libdir = 'lib' |
913 if self.toolset != 'target': | 914 if self.toolset != 'target': |
914 libdir = 'lib/%s' % self.toolset | 915 libdir = os.path.join('lib', '%s' % self.toolset) |
915 return os.path.join(libdir, filename) | 916 return os.path.join(libdir, filename) |
916 else: | 917 else: |
917 return self.GypPathToUniqueOutput(filename, qualified=False) | 918 return self.GypPathToUniqueOutput(filename, qualified=False) |
918 | 919 |
919 def WriteVariableList(self, var, values): | 920 def WriteVariableList(self, var, values): |
920 if values is None: | 921 if values is None: |
921 values = [] | 922 values = [] |
922 self.ninja.variable(var, ' '.join(values)) | 923 self.ninja.variable(var, ' '.join(values)) |
923 | 924 |
924 def WriteNewNinjaRule(self, name, args, description, env={}): | 925 def WriteNewNinjaRule(self, name, args, description, env={}): |
925 """Write out a new ninja "rule" statement for a given command. | 926 """Write out a new ninja "rule" statement for a given command. |
926 | 927 |
927 Returns the name of the new rule.""" | 928 Returns the name of the new rule.""" |
928 | 929 |
929 # TODO: we shouldn't need to qualify names; we do it because | 930 # TODO: we shouldn't need to qualify names; we do it because |
930 # currently the ninja rule namespace is global, but it really | 931 # currently the ninja rule namespace is global, but it really |
931 # should be scoped to the subninja. | 932 # should be scoped to the subninja. |
932 rule_name = self.name | 933 rule_name = self.name |
933 if self.toolset == 'target': | 934 if self.toolset == 'target': |
934 rule_name += '.' + self.toolset | 935 rule_name += '.' + self.toolset |
935 rule_name += '.' + name | 936 rule_name += '.' + name |
936 rule_name = rule_name.replace(' ', '_') | 937 rule_name = rule_name.replace(' ', '_') |
937 | 938 |
938 args = args[:] | 939 args = args[:] |
939 | 940 |
940 # gyp dictates that commands are run from the base directory. | 941 # gyp dictates that commands are run from the base directory. |
941 # cd into the directory before running, and adjust paths in | 942 # cd into the directory before running, and adjust paths in |
942 # the arguments to point to the proper locations. | 943 # the arguments to point to the proper locations. |
943 cd = 'cd %s; ' % self.build_to_base | 944 if self.flavor == 'win': |
945 cd = 'cmd /s /c "cd %s && ' % self.build_to_base | |
946 else: | |
947 cd = 'cd %s; ' % self.build_to_base | |
944 args = [self.ExpandSpecial(arg, self.base_to_build) for arg in args] | 948 args = [self.ExpandSpecial(arg, self.base_to_build) for arg in args] |
945 env = self.ComputeExportEnvString(env) | 949 env = self.ComputeExportEnvString(env) |
946 command = gyp.common.EncodePOSIXShellList(args) | 950 if self.flavor == 'win': |
951 # TODO(scottmg): Really don't want encourage cygwin, but I'm not sure | |
952 # how much sh is depended upon. For now, double quote args to make most | |
953 # things work. | |
Evan Martin
2012/02/16 16:10:33
I think there's a gyp attribute related to whether
| |
954 command = args[0] + ' "' + '" "'.join(args[1:]) + '""' | |
955 else: | |
956 command = gyp.common.EncodePOSIXShellList(args) | |
947 if env: | 957 if env: |
948 # If an environment is passed in, variables in the command should be | 958 # If an environment is passed in, variables in the command should be |
949 # read from it, instead of from ninja's internal variables. | 959 # read from it, instead of from ninja's internal variables. |
950 command = ninja_syntax.escape(command) | 960 command = ninja_syntax.escape(command) |
951 | 961 |
952 command = cd + env + command | 962 command = cd + env + command |
953 # GYP rules/actions express being no-ops by not touching their outputs. | 963 # GYP rules/actions express being no-ops by not touching their outputs. |
954 # Avoid executing downstream dependencies in this case by specifying | 964 # Avoid executing downstream dependencies in this case by specifying |
955 # restat=1 to ninja. | 965 # restat=1 to ninja. |
956 self.ninja.rule(rule_name, command, description, restat=True) | 966 self.ninja.rule(rule_name, command, description, restat=True) |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
988 default_variables.setdefault('STATIC_LIB_PREFIX', '') | 998 default_variables.setdefault('STATIC_LIB_PREFIX', '') |
989 default_variables.setdefault('STATIC_LIB_SUFFIX', '.lib') | 999 default_variables.setdefault('STATIC_LIB_SUFFIX', '.lib') |
990 default_variables.setdefault('SHARED_LIB_PREFIX', '') | 1000 default_variables.setdefault('SHARED_LIB_PREFIX', '') |
991 default_variables.setdefault('SHARED_LIB_SUFFIX', '.dll') | 1001 default_variables.setdefault('SHARED_LIB_SUFFIX', '.dll') |
992 else: | 1002 else: |
993 operating_system = flavor | 1003 operating_system = flavor |
994 if flavor == 'android': | 1004 if flavor == 'android': |
995 operating_system = 'linux' # Keep this legacy behavior for now. | 1005 operating_system = 'linux' # Keep this legacy behavior for now. |
996 default_variables.setdefault('OS', operating_system) | 1006 default_variables.setdefault('OS', operating_system) |
997 default_variables.setdefault('SHARED_LIB_SUFFIX', '.so') | 1007 default_variables.setdefault('SHARED_LIB_SUFFIX', '.so') |
998 default_variables.setdefault('SHARED_LIB_DIR', '$!PRODUCT_DIR/lib') | 1008 default_variables.setdefault('SHARED_LIB_DIR', |
1009 os.path.join('$!PRODUCT_DIR', 'lib')) | |
999 default_variables.setdefault('LIB_DIR', '') | 1010 default_variables.setdefault('LIB_DIR', '') |
1000 | 1011 |
1001 | 1012 |
1002 def OpenOutput(path): | 1013 def OpenOutput(path): |
1003 """Open |path| for writing, creating directories if necessary.""" | 1014 """Open |path| for writing, creating directories if necessary.""" |
1004 try: | 1015 try: |
1005 os.makedirs(os.path.dirname(path)) | 1016 os.makedirs(os.path.dirname(path)) |
1006 except OSError: | 1017 except OSError: |
1007 pass | 1018 pass |
1008 return open(path, 'w') | 1019 return open(path, 'w') |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1103 '-Wl,--start-group $in -Wl,--end-group $libs')) | 1114 '-Wl,--start-group $in -Wl,--end-group $libs')) |
1104 master_ninja.rule( | 1115 master_ninja.rule( |
1105 'link', | 1116 'link', |
1106 description='LINK $out', | 1117 description='LINK $out', |
1107 command=('$ld $ldflags -o $out -Wl,-rpath=\$$ORIGIN/lib ' | 1118 command=('$ld $ldflags -o $out -Wl,-rpath=\$$ORIGIN/lib ' |
1108 '-Wl,--start-group $in -Wl,--end-group $libs')) | 1119 '-Wl,--start-group $in -Wl,--end-group $libs')) |
1109 elif flavor == 'win': | 1120 elif flavor == 'win': |
1110 master_ninja.rule( | 1121 master_ninja.rule( |
1111 'alink', | 1122 'alink', |
1112 description='AR $out', | 1123 description='AR $out', |
1113 command='lib /nologo /OUT:$out.lib $in') | 1124 command='lib /nologo /OUT:$out $in') |
1114 master_ninja.rule( | 1125 master_ninja.rule( |
1115 'solink', | 1126 'solink', |
1116 description='SOLINK $out', | 1127 description='SOLINK $out', |
1117 command=('$ld /nologo /DLL $ldflags /OUT:$out $in $libs')) | 1128 command=('$ld /nologo /DLL $ldflags /OUT:$out $in $libs')) |
1118 master_ninja.rule( | 1129 master_ninja.rule( |
1119 'solink_module', | 1130 'solink_module', |
1120 description='SOLINK(module) $out', | 1131 description='SOLINK(module) $out', |
1121 command=('$ld /nologo /DLL $ldflags /OUT:$out $in $libs')) | 1132 command=('$ld /nologo /DLL $ldflags /OUT:$out $in $libs')) |
1122 master_ninja.rule( | 1133 master_ninja.rule( |
1123 'link', | 1134 'link', |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1243 | 1254 |
1244 user_config = params.get('generator_flags', {}).get('config', None) | 1255 user_config = params.get('generator_flags', {}).get('config', None) |
1245 if user_config: | 1256 if user_config: |
1246 GenerateOutputForConfig(target_list, target_dicts, data, params, | 1257 GenerateOutputForConfig(target_list, target_dicts, data, params, |
1247 user_config) | 1258 user_config) |
1248 else: | 1259 else: |
1249 config_names = target_dicts[target_list[0]]['configurations'].keys() | 1260 config_names = target_dicts[target_list[0]]['configurations'].keys() |
1250 for config_name in config_names: | 1261 for config_name in config_names: |
1251 GenerateOutputForConfig(target_list, target_dicts, data, params, | 1262 GenerateOutputForConfig(target_list, target_dicts, data, params, |
1252 config_name) | 1263 config_name) |
OLD | NEW |