Chromium Code Reviews| 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 |