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 24 matching lines...) Expand all Loading... | |
| 35 # Special variables that may be used by gyp 'rule' targets. | 35 # Special variables that may be used by gyp 'rule' targets. |
| 36 # We generate definitions for these variables on the fly when processing a | 36 # We generate definitions for these variables on the fly when processing a |
| 37 # rule. | 37 # rule. |
| 38 'RULE_INPUT_ROOT': '${root}', | 38 'RULE_INPUT_ROOT': '${root}', |
| 39 'RULE_INPUT_DIRNAME': '${dirname}', | 39 'RULE_INPUT_DIRNAME': '${dirname}', |
| 40 'RULE_INPUT_PATH': '${source}', | 40 'RULE_INPUT_PATH': '${source}', |
| 41 'RULE_INPUT_EXT': '${ext}', | 41 'RULE_INPUT_EXT': '${ext}', |
| 42 'RULE_INPUT_NAME': '${name}', | 42 'RULE_INPUT_NAME': '${name}', |
| 43 } | 43 } |
| 44 | 44 |
| 45 # TODO(scottmg): This seems wrong, should be based on flavor. How do we push | |
| 46 # these back in later? | |
|
Evan Martin
2012/02/14 19:07:29
See make.py:
def CalculateVariables(default_varia
Nico
2012/02/14 19:14:10
See also the same function in ninja.py :-)
| |
| 47 if sys.platform == 'win32': | |
| 48 generator_default_variables['EXECUTABLE_SUFFIX'] = '.exe' | |
| 49 generator_default_variables['STATIC_LIB_PREFIX'] = '' | |
| 50 generator_default_variables['STATIC_LIB_SUFFIX'] = '.lib' | |
| 51 generator_default_variables['SHARED_LIB_PREFIX'] = '' | |
| 52 generator_default_variables['SHARED_LIB_SUFFIX'] = '.dll' | |
| 53 | |
| 45 # TODO: enable cross compiling once we figure out: | 54 # TODO: enable cross compiling once we figure out: |
| 46 # - how to not build extra host objects in the non-cross-compile case. | 55 # - how to not build extra host objects in the non-cross-compile case. |
| 47 # - how to decide what the host compiler is (should not just be $cc). | 56 # - how to decide what the host compiler is (should not just be $cc). |
| 48 # - need ld_host as well. | 57 # - need ld_host as well. |
| 49 generator_supports_multiple_toolsets = False | 58 generator_supports_multiple_toolsets = False |
| 50 | 59 |
| 51 | 60 |
| 52 def StripPrefix(arg, prefix): | 61 def StripPrefix(arg, prefix): |
| 53 if arg.startswith(prefix): | 62 if arg.startswith(prefix): |
| 54 return arg[len(prefix):] | 63 return arg[len(prefix):] |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 69 """Given a relative path like foo/bar, return the inverse relative path: | 78 """Given a relative path like foo/bar, return the inverse relative path: |
| 70 the path from the relative path back to the origin dir. | 79 the path from the relative path back to the origin dir. |
| 71 | 80 |
| 72 E.g. os.path.normpath(os.path.join(path, InvertRelativePath(path))) | 81 E.g. os.path.normpath(os.path.join(path, InvertRelativePath(path))) |
| 73 should always produce the empty string.""" | 82 should always produce the empty string.""" |
| 74 | 83 |
| 75 if not path: | 84 if not path: |
| 76 return path | 85 return path |
| 77 # Only need to handle relative paths into subdirectories for now. | 86 # Only need to handle relative paths into subdirectories for now. |
| 78 assert '..' not in path, path | 87 assert '..' not in path, path |
| 79 depth = len(path.split('/')) | 88 depth = len(path.split(os.path.sep)) |
|
scottmg
2012/02/14 18:58:48
This was *sneaky*! Paths were ../blah instead of .
Evan Martin
2012/02/14 19:07:29
Is there value in allowing us to generate files ac
| |
| 80 return '/'.join(['..'] * depth) | 89 return '/'.join(['..'] * depth) |
| 81 | 90 |
| 82 | 91 |
| 83 class Target: | 92 class Target: |
| 84 """Target represents the paths used within a single gyp target. | 93 """Target represents the paths used within a single gyp target. |
| 85 | 94 |
| 86 Conceptually, building a single target A is a series of steps: | 95 Conceptually, building a single target A is a series of steps: |
| 87 | 96 |
| 88 1) actions/rules/copies generates source/resources/etc. | 97 1) actions/rules/copies generates source/resources/etc. |
| 89 2) compiles generates .o files | 98 2) compiles generates .o files |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 173 build_dir: path from source root to build output | 182 build_dir: path from source root to build output |
| 174 abs_build_dir: absolute path to the build directory | 183 abs_build_dir: absolute path to the build directory |
| 175 """ | 184 """ |
| 176 | 185 |
| 177 self.target_outputs = target_outputs | 186 self.target_outputs = target_outputs |
| 178 self.base_dir = base_dir | 187 self.base_dir = base_dir |
| 179 self.build_dir = build_dir | 188 self.build_dir = build_dir |
| 180 self.ninja = ninja_syntax.Writer(output_file) | 189 self.ninja = ninja_syntax.Writer(output_file) |
| 181 self.flavor = flavor | 190 self.flavor = flavor |
| 182 self.abs_build_dir = abs_build_dir | 191 self.abs_build_dir = abs_build_dir |
| 192 self.obj_ext = '.obj' if flavor == 'win' else '.o' | |
| 183 | 193 |
| 184 # Relative path from build output dir to base dir. | 194 # Relative path from build output dir to base dir. |
| 185 self.build_to_base = os.path.join(InvertRelativePath(build_dir), base_dir) | 195 self.build_to_base = os.path.join(InvertRelativePath(build_dir), base_dir) |
| 186 # Relative path from base dir to build dir. | 196 # Relative path from base dir to build dir. |
| 187 self.base_to_build = os.path.join(InvertRelativePath(base_dir), build_dir) | 197 self.base_to_build = os.path.join(InvertRelativePath(base_dir), build_dir) |
| 188 | 198 |
| 189 def ExpandSpecial(self, path, product_dir=None): | 199 def ExpandSpecial(self, path, product_dir=None): |
| 190 """Expand specials like $!PRODUCT_DIR in |path|. | 200 """Expand specials like $!PRODUCT_DIR in |path|. |
| 191 | 201 |
| 192 If |product_dir| is None, assumes the cwd is already the product | 202 If |product_dir| is None, assumes the cwd is already the product |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 341 # Write out the compilation steps, if any. | 351 # Write out the compilation steps, if any. |
| 342 link_deps = [] | 352 link_deps = [] |
| 343 sources = spec.get('sources', []) + extra_sources | 353 sources = spec.get('sources', []) + extra_sources |
| 344 if sources: | 354 if sources: |
| 345 link_deps = self.WriteSources( | 355 link_deps = self.WriteSources( |
| 346 config_name, config, sources, compile_depends_stamp, | 356 config_name, config, sources, compile_depends_stamp, |
| 347 gyp.xcode_emulation.MacPrefixHeader( | 357 gyp.xcode_emulation.MacPrefixHeader( |
| 348 self.xcode_settings, self.GypPathToNinja, | 358 self.xcode_settings, self.GypPathToNinja, |
| 349 lambda path, lang: self.GypPathToUniqueOutput(path + '-' + lang))) | 359 lambda path, lang: self.GypPathToUniqueOutput(path + '-' + lang))) |
| 350 # Some actions/rules output 'sources' that are already object files. | 360 # Some actions/rules output 'sources' that are already object files. |
| 351 link_deps += [self.GypPathToNinja(f) for f in sources if f.endswith('.o')] | 361 link_deps += [self.GypPathToNinja(f) |
| 362 for f in sources if f.endswith(self.obj_ext)] | |
| 352 | 363 |
| 353 # Write out a link step, if needed. | 364 # Write out a link step, if needed. |
| 354 output = None | 365 output = None |
| 355 if link_deps or self.target.actions_stamp or actions_depends: | 366 if link_deps or self.target.actions_stamp or actions_depends: |
| 356 output = self.WriteTarget(spec, config_name, config, link_deps, | 367 output = self.WriteTarget(spec, config_name, config, link_deps, |
| 357 self.target.actions_stamp or actions_depends) | 368 self.target.actions_stamp or actions_depends) |
| 358 if self.is_mac_bundle: | 369 if self.is_mac_bundle: |
| 359 mac_bundle_depends.append(output) | 370 mac_bundle_depends.append(output) |
| 360 | 371 |
| 361 # Bundle all of the above together, if needed. | 372 # Bundle all of the above together, if needed. |
| (...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 620 elif ext in ('c', 's', 'S'): | 631 elif ext in ('c', 's', 'S'): |
| 621 command = 'cc' | 632 command = 'cc' |
| 622 elif self.flavor == 'mac' and ext == 'm': | 633 elif self.flavor == 'mac' and ext == 'm': |
| 623 command = 'objc' | 634 command = 'objc' |
| 624 elif self.flavor == 'mac' and ext == 'mm': | 635 elif self.flavor == 'mac' and ext == 'mm': |
| 625 command = 'objcxx' | 636 command = 'objcxx' |
| 626 else: | 637 else: |
| 627 # TODO: should we assert here on unexpected extensions? | 638 # TODO: should we assert here on unexpected extensions? |
| 628 continue | 639 continue |
| 629 input = self.GypPathToNinja(source) | 640 input = self.GypPathToNinja(source) |
| 630 output = self.GypPathToUniqueOutput(filename + '.o') | 641 output = self.GypPathToUniqueOutput(filename + self.obj_ext) |
| 631 implicit = precompiled_header.GetObjDependencies([input], [output]) | 642 implicit = precompiled_header.GetObjDependencies([input], [output]) |
| 632 self.ninja.build(output, command, input, | 643 self.ninja.build(output, command, input, |
| 633 implicit=[gch for _, _, gch in implicit], | 644 implicit=[gch for _, _, gch in implicit], |
| 634 order_only=predepends) | 645 order_only=predepends) |
| 635 outputs.append(output) | 646 outputs.append(output) |
| 636 | 647 |
| 637 self.WritePchTargets(pch_commands) | 648 self.WritePchTargets(pch_commands) |
| 638 | 649 |
| 639 self.ninja.newline() | 650 self.ninja.newline() |
| 640 return outputs | 651 return outputs |
| (...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 997 config_name) | 1008 config_name) |
| 998 | 1009 |
| 999 master_ninja = ninja_syntax.Writer( | 1010 master_ninja = ninja_syntax.Writer( |
| 1000 OpenOutput(os.path.join(options.toplevel_dir, build_dir, 'build.ninja')), | 1011 OpenOutput(os.path.join(options.toplevel_dir, build_dir, 'build.ninja')), |
| 1001 width=120) | 1012 width=120) |
| 1002 | 1013 |
| 1003 # Put build-time support tools in out/{config_name}. | 1014 # Put build-time support tools in out/{config_name}. |
| 1004 gyp.common.CopyTool(flavor, os.path.join(options.toplevel_dir, build_dir)) | 1015 gyp.common.CopyTool(flavor, os.path.join(options.toplevel_dir, build_dir)) |
| 1005 | 1016 |
| 1006 # Grab make settings for CC/CXX. | 1017 # Grab make settings for CC/CXX. |
| 1007 cc, cxx = 'gcc', 'g++' | 1018 if flavor == 'win': |
| 1019 cc = cxx = 'cl' | |
| 1020 else: | |
| 1021 cc, cxx = 'gcc', 'g++' | |
| 1008 build_file, _, _ = gyp.common.ParseQualifiedTarget(target_list[0]) | 1022 build_file, _, _ = gyp.common.ParseQualifiedTarget(target_list[0]) |
| 1009 make_global_settings = data[build_file].get('make_global_settings', []) | 1023 make_global_settings = data[build_file].get('make_global_settings', []) |
| 1010 build_to_root = InvertRelativePath(build_dir) | 1024 build_to_root = InvertRelativePath(build_dir) |
| 1011 for key, value in make_global_settings: | 1025 for key, value in make_global_settings: |
| 1012 if key == 'CC': cc = os.path.join(build_to_root, value) | 1026 if key == 'CC': cc = os.path.join(build_to_root, value) |
| 1013 if key == 'CXX': cxx = os.path.join(build_to_root, value) | 1027 if key == 'CXX': cxx = os.path.join(build_to_root, value) |
| 1014 | 1028 |
| 1015 flock = 'flock' | 1029 flock = 'flock' |
| 1016 if flavor == 'mac': | 1030 if flavor == 'mac': |
| 1017 flock = './gyp-mac-tool flock' | 1031 flock = './gyp-mac-tool flock' |
| 1018 master_ninja.variable('cc', os.environ.get('CC', cc)) | 1032 master_ninja.variable('cc', os.environ.get('CC', cc)) |
| 1019 master_ninja.variable('cxx', os.environ.get('CXX', cxx)) | 1033 master_ninja.variable('cxx', os.environ.get('CXX', cxx)) |
| 1020 master_ninja.variable('ld', flock + ' linker.lock $cxx') | 1034 if flavor == 'win': |
| 1035 master_ninja.variable('ld', 'link') | |
| 1036 else: | |
| 1037 master_ninja.variable('ld', flock + ' linker.lock $cxx') | |
| 1021 master_ninja.variable('cc_host', '$cc') | 1038 master_ninja.variable('cc_host', '$cc') |
| 1022 master_ninja.variable('cxx_host', '$cxx') | 1039 master_ninja.variable('cxx_host', '$cxx') |
| 1023 if flavor == 'mac': | 1040 if flavor == 'mac': |
| 1024 master_ninja.variable('mac_tool', os.path.join('.', 'gyp-mac-tool')) | 1041 master_ninja.variable('mac_tool', os.path.join('.', 'gyp-mac-tool')) |
| 1025 master_ninja.newline() | 1042 master_ninja.newline() |
| 1026 | 1043 |
| 1027 master_ninja.rule( | 1044 if flavor != 'win': |
| 1028 'cc', | 1045 master_ninja.rule( |
| 1029 description='CC $out', | 1046 'cc', |
| 1030 command=('$cc -MMD -MF $out.d $defines $includes $cflags $cflags_c ' | 1047 description='CC $out', |
| 1031 '$cflags_pch_c -c $in -o $out'), | 1048 command=('$cc -MMD -MF $out.d $defines $includes $cflags $cflags_c ' |
| 1032 depfile='$out.d') | 1049 '$cflags_pch_c -c $in -o $out'), |
| 1033 master_ninja.rule( | 1050 depfile='$out.d') |
| 1034 'cxx', | 1051 master_ninja.rule( |
| 1035 description='CXX $out', | 1052 'cxx', |
| 1036 command=('$cxx -MMD -MF $out.d $defines $includes $cflags $cflags_cc ' | 1053 description='CXX $out', |
| 1037 '$cflags_pch_cc -c $in -o $out'), | 1054 command=('$cxx -MMD -MF $out.d $defines $includes $cflags $cflags_cc ' |
| 1038 depfile='$out.d') | 1055 '$cflags_pch_cc -c $in -o $out'), |
| 1039 if flavor != 'mac': | 1056 depfile='$out.d') |
| 1057 else: | |
| 1058 # TODO(scottmg): Decide how /showIncludes handling should work in ninja. | |
| 1059 master_ninja.rule( | |
| 1060 'cc', | |
| 1061 description='CC $out', | |
| 1062 command=('$cc /nologo $defines $includes $cflags $cflags_c ' | |
| 1063 '$cflags_pch_c /c $in /Fo$out'), | |
| 1064 depfile='$out.d') | |
| 1065 master_ninja.rule( | |
| 1066 'cxx', | |
| 1067 description='CXX $out', | |
| 1068 command=('$cxx /nologo $defines $includes $cflags $cflags_cc ' | |
| 1069 '$cflags_pch_cc /c $in /Fo$out'), | |
| 1070 depfile='$out.d') | |
| 1071 | |
| 1072 if flavor != 'mac' and flavor != 'win': | |
| 1040 master_ninja.rule( | 1073 master_ninja.rule( |
| 1041 'alink', | 1074 'alink', |
| 1042 description='AR $out', | 1075 description='AR $out', |
| 1043 command='rm -f $out && ar rcsT $out $in') | 1076 command='rm -f $out && ar rcsT $out $in') |
| 1044 master_ninja.rule( | 1077 master_ninja.rule( |
| 1045 'solink', | 1078 'solink', |
| 1046 description='SOLINK $out', | 1079 description='SOLINK $out', |
| 1047 command=('$ld -shared $ldflags -o $out -Wl,-soname=$soname ' | 1080 command=('$ld -shared $ldflags -o $out -Wl,-soname=$soname ' |
| 1048 '-Wl,--whole-archive $in -Wl,--no-whole-archive $libs')) | 1081 '-Wl,--whole-archive $in -Wl,--no-whole-archive $libs')) |
| 1049 master_ninja.rule( | 1082 master_ninja.rule( |
| 1050 'solink_module', | 1083 'solink_module', |
| 1051 description='SOLINK(module) $out', | 1084 description='SOLINK(module) $out', |
| 1052 command=('$ld -shared $ldflags -o $out -Wl,-soname=$soname ' | 1085 command=('$ld -shared $ldflags -o $out -Wl,-soname=$soname ' |
| 1053 '-Wl,--start-group $in -Wl,--end-group $libs')) | 1086 '-Wl,--start-group $in -Wl,--end-group $libs')) |
| 1054 master_ninja.rule( | 1087 master_ninja.rule( |
| 1055 'link', | 1088 'link', |
| 1056 description='LINK $out', | 1089 description='LINK $out', |
| 1057 command=('$ld $ldflags -o $out -Wl,-rpath=\$$ORIGIN/lib ' | 1090 command=('$ld $ldflags -o $out -Wl,-rpath=\$$ORIGIN/lib ' |
| 1058 '-Wl,--start-group $in -Wl,--end-group $libs')) | 1091 '-Wl,--start-group $in -Wl,--end-group $libs')) |
| 1092 elif flavor == 'win': | |
| 1093 master_ninja.rule( | |
| 1094 'alink', | |
| 1095 description='AR $out', | |
| 1096 command='lib /nologo /OUT:$out.lib $in') | |
| 1097 master_ninja.rule( | |
| 1098 'solink', | |
| 1099 description='SOLINK $out', | |
| 1100 command=('$ld /nologo /DLL $ldflags /OUT:$out.dll $in $libs')) | |
| 1101 master_ninja.rule( | |
| 1102 'solink_module', | |
| 1103 description='SOLINK(module) $out', | |
| 1104 command=('$ld /nologo /DLL $ldflags /OUT:$out.dll $in $libs')) | |
| 1105 master_ninja.rule( | |
| 1106 'link', | |
| 1107 description='LINK $out', | |
| 1108 command=('$ld /nologo $ldflags /OUT:$out.exe $in $libs')) | |
| 1059 else: | 1109 else: |
| 1060 master_ninja.rule( | 1110 master_ninja.rule( |
| 1061 'objc', | 1111 'objc', |
| 1062 description='OBJC $out', | 1112 description='OBJC $out', |
| 1063 command=('$cc -MMD -MF $out.d $defines $includes $cflags $cflags_objc ' | 1113 command=('$cc -MMD -MF $out.d $defines $includes $cflags $cflags_objc ' |
| 1064 '$cflags_pch_objc -c $in -o $out'), | 1114 '$cflags_pch_objc -c $in -o $out'), |
| 1065 depfile='$out.d') | 1115 depfile='$out.d') |
| 1066 master_ninja.rule( | 1116 master_ninja.rule( |
| 1067 'objcxx', | 1117 'objcxx', |
| 1068 description='OBJCXX $out', | 1118 description='OBJCXX $out', |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1103 command='$env $mac_tool $mactool_cmd $in $out') | 1153 command='$env $mac_tool $mactool_cmd $in $out') |
| 1104 master_ninja.rule( | 1154 master_ninja.rule( |
| 1105 'package_framework', | 1155 'package_framework', |
| 1106 description='PACKAGE FRAMEWORK $out, POSTBUILDS', | 1156 description='PACKAGE FRAMEWORK $out, POSTBUILDS', |
| 1107 command='$mac_tool package-framework $out $version$postbuilds ' | 1157 command='$mac_tool package-framework $out $version$postbuilds ' |
| 1108 '&& touch $out') | 1158 '&& touch $out') |
| 1109 master_ninja.rule( | 1159 master_ninja.rule( |
| 1110 'stamp', | 1160 'stamp', |
| 1111 description='STAMP $out', | 1161 description='STAMP $out', |
| 1112 command='${postbuilds}touch $out') | 1162 command='${postbuilds}touch $out') |
| 1113 master_ninja.rule( | 1163 if flavor == 'win': |
| 1114 'copy', | 1164 # TODO(scottmg): Copy fallback? |
| 1115 description='COPY $in $out', | 1165 master_ninja.rule( |
| 1116 command='ln -f $in $out 2>/dev/null || (rm -rf $out && cp -af $in $out)') | 1166 'copy', |
| 1167 description='COPY $in $out', | |
| 1168 command='mklink /h $out $in >nul') | |
| 1169 else: | |
| 1170 master_ninja.rule( | |
| 1171 'copy', | |
| 1172 description='COPY $in $out', | |
| 1173 command='ln -f $in $out 2>/dev/null || (rm -rf $out && cp -af $in $out)') | |
| 1117 master_ninja.newline() | 1174 master_ninja.newline() |
| 1118 | 1175 |
| 1119 all_targets = set() | 1176 all_targets = set() |
| 1120 for build_file in params['build_files']: | 1177 for build_file in params['build_files']: |
| 1121 for target in gyp.common.AllTargets(target_list, target_dicts, build_file): | 1178 for target in gyp.common.AllTargets(target_list, target_dicts, build_file): |
| 1122 all_targets.add(target) | 1179 all_targets.add(target) |
| 1123 all_outputs = set() | 1180 all_outputs = set() |
| 1124 | 1181 |
| 1125 # target_outputs is a map from qualified target name to a Target object. | 1182 # target_outputs is a map from qualified target name to a Target object. |
| 1126 target_outputs = {} | 1183 target_outputs = {} |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1169 | 1226 |
| 1170 user_config = params.get('generator_flags', {}).get('config', None) | 1227 user_config = params.get('generator_flags', {}).get('config', None) |
| 1171 if user_config: | 1228 if user_config: |
| 1172 GenerateOutputForConfig(target_list, target_dicts, data, params, | 1229 GenerateOutputForConfig(target_list, target_dicts, data, params, |
| 1173 user_config) | 1230 user_config) |
| 1174 else: | 1231 else: |
| 1175 config_names = target_dicts[target_list[0]]['configurations'].keys() | 1232 config_names = target_dicts[target_list[0]]['configurations'].keys() |
| 1176 for config_name in config_names: | 1233 for config_name in config_names: |
| 1177 GenerateOutputForConfig(target_list, target_dicts, data, params, | 1234 GenerateOutputForConfig(target_list, target_dicts, data, params, |
| 1178 config_name) | 1235 config_name) |
| OLD | NEW |