| 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 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 69 """Given a relative path like foo/bar, return the inverse relative path: | 69 """Given a relative path like foo/bar, return the inverse relative path: |
| 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('/')) | 79 depth = len(path.split(os.path.sep)) |
| 80 return '/'.join(['..'] * depth) | 80 return '/'.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 |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 173 build_dir: path from source root to build output | 173 build_dir: path from source root to build output |
| 174 abs_build_dir: absolute path to the build directory | 174 abs_build_dir: absolute path to the build directory |
| 175 """ | 175 """ |
| 176 | 176 |
| 177 self.target_outputs = target_outputs | 177 self.target_outputs = target_outputs |
| 178 self.base_dir = base_dir | 178 self.base_dir = base_dir |
| 179 self.build_dir = build_dir | 179 self.build_dir = build_dir |
| 180 self.ninja = ninja_syntax.Writer(output_file) | 180 self.ninja = ninja_syntax.Writer(output_file) |
| 181 self.flavor = flavor | 181 self.flavor = flavor |
| 182 self.abs_build_dir = abs_build_dir | 182 self.abs_build_dir = abs_build_dir |
| 183 self.obj_ext = '.obj' if flavor == 'win' else '.o' |
| 183 | 184 |
| 184 # Relative path from build output dir to base dir. | 185 # Relative path from build output dir to base dir. |
| 185 self.build_to_base = os.path.join(InvertRelativePath(build_dir), base_dir) | 186 self.build_to_base = os.path.join(InvertRelativePath(build_dir), base_dir) |
| 186 # Relative path from base dir to build dir. | 187 # Relative path from base dir to build dir. |
| 187 self.base_to_build = os.path.join(InvertRelativePath(base_dir), build_dir) | 188 self.base_to_build = os.path.join(InvertRelativePath(base_dir), build_dir) |
| 188 | 189 |
| 189 def ExpandSpecial(self, path, product_dir=None): | 190 def ExpandSpecial(self, path, product_dir=None): |
| 190 """Expand specials like $!PRODUCT_DIR in |path|. | 191 """Expand specials like $!PRODUCT_DIR in |path|. |
| 191 | 192 |
| 192 If |product_dir| is None, assumes the cwd is already the product | 193 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. | 342 # Write out the compilation steps, if any. |
| 342 link_deps = [] | 343 link_deps = [] |
| 343 sources = spec.get('sources', []) + extra_sources | 344 sources = spec.get('sources', []) + extra_sources |
| 344 if sources: | 345 if sources: |
| 345 link_deps = self.WriteSources( | 346 link_deps = self.WriteSources( |
| 346 config_name, config, sources, compile_depends_stamp, | 347 config_name, config, sources, compile_depends_stamp, |
| 347 gyp.xcode_emulation.MacPrefixHeader( | 348 gyp.xcode_emulation.MacPrefixHeader( |
| 348 self.xcode_settings, self.GypPathToNinja, | 349 self.xcode_settings, self.GypPathToNinja, |
| 349 lambda path, lang: self.GypPathToUniqueOutput(path + '-' + lang))) | 350 lambda path, lang: self.GypPathToUniqueOutput(path + '-' + lang))) |
| 350 # Some actions/rules output 'sources' that are already object files. | 351 # Some actions/rules output 'sources' that are already object files. |
| 351 link_deps += [self.GypPathToNinja(f) for f in sources if f.endswith('.o')] | 352 link_deps += [self.GypPathToNinja(f) |
| 353 for f in sources if f.endswith(self.obj_ext)] |
| 352 | 354 |
| 353 # Write out a link step, if needed. | 355 # Write out a link step, if needed. |
| 354 output = None | 356 output = None |
| 355 if link_deps or self.target.actions_stamp or actions_depends: | 357 if link_deps or self.target.actions_stamp or actions_depends: |
| 356 output = self.WriteTarget(spec, config_name, config, link_deps, | 358 output = self.WriteTarget(spec, config_name, config, link_deps, |
| 357 self.target.actions_stamp or actions_depends) | 359 self.target.actions_stamp or actions_depends) |
| 358 if self.is_mac_bundle: | 360 if self.is_mac_bundle: |
| 359 mac_bundle_depends.append(output) | 361 mac_bundle_depends.append(output) |
| 360 | 362 |
| 361 # Bundle all of the above together, if needed. | 363 # 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'): | 622 elif ext in ('c', 's', 'S'): |
| 621 command = 'cc' | 623 command = 'cc' |
| 622 elif self.flavor == 'mac' and ext == 'm': | 624 elif self.flavor == 'mac' and ext == 'm': |
| 623 command = 'objc' | 625 command = 'objc' |
| 624 elif self.flavor == 'mac' and ext == 'mm': | 626 elif self.flavor == 'mac' and ext == 'mm': |
| 625 command = 'objcxx' | 627 command = 'objcxx' |
| 626 else: | 628 else: |
| 627 # TODO: should we assert here on unexpected extensions? | 629 # TODO: should we assert here on unexpected extensions? |
| 628 continue | 630 continue |
| 629 input = self.GypPathToNinja(source) | 631 input = self.GypPathToNinja(source) |
| 630 output = self.GypPathToUniqueOutput(filename + '.o') | 632 output = self.GypPathToUniqueOutput(filename + self.obj_ext) |
| 631 implicit = precompiled_header.GetObjDependencies([input], [output]) | 633 implicit = precompiled_header.GetObjDependencies([input], [output]) |
| 632 self.ninja.build(output, command, input, | 634 self.ninja.build(output, command, input, |
| 633 implicit=[gch for _, _, gch in implicit], | 635 implicit=[gch for _, _, gch in implicit], |
| 634 order_only=predepends) | 636 order_only=predepends) |
| 635 outputs.append(output) | 637 outputs.append(output) |
| 636 | 638 |
| 637 self.WritePchTargets(pch_commands) | 639 self.WritePchTargets(pch_commands) |
| 638 | 640 |
| 639 self.ninja.newline() | 641 self.ninja.newline() |
| 640 return outputs | 642 return outputs |
| (...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 959 import gyp.generator.xcode as xcode_generator | 961 import gyp.generator.xcode as xcode_generator |
| 960 global generator_additional_non_configuration_keys | 962 global generator_additional_non_configuration_keys |
| 961 generator_additional_non_configuration_keys = getattr(xcode_generator, | 963 generator_additional_non_configuration_keys = getattr(xcode_generator, |
| 962 'generator_additional_non_configuration_keys', []) | 964 'generator_additional_non_configuration_keys', []) |
| 963 global generator_additional_path_sections | 965 global generator_additional_path_sections |
| 964 generator_additional_path_sections = getattr(xcode_generator, | 966 generator_additional_path_sections = getattr(xcode_generator, |
| 965 'generator_additional_path_sections', []) | 967 'generator_additional_path_sections', []) |
| 966 global generator_extra_sources_for_rules | 968 global generator_extra_sources_for_rules |
| 967 generator_extra_sources_for_rules = getattr(xcode_generator, | 969 generator_extra_sources_for_rules = getattr(xcode_generator, |
| 968 'generator_extra_sources_for_rules', []) | 970 'generator_extra_sources_for_rules', []) |
| 971 elif flavor == 'win': |
| 972 default_variables.setdefault('EXECUTABLE_SUFFIX', '.exe') |
| 973 default_variables.setdefault('STATIC_LIB_PREFIX', '') |
| 974 default_variables.setdefault('STATIC_LIB_SUFFIX', '.lib') |
| 975 default_variables.setdefault('SHARED_LIB_PREFIX', '') |
| 976 default_variables.setdefault('SHARED_LIB_SUFFIX', '.dll') |
| 969 else: | 977 else: |
| 970 operating_system = flavor | 978 operating_system = flavor |
| 971 if flavor == 'android': | 979 if flavor == 'android': |
| 972 operating_system = 'linux' # Keep this legacy behavior for now. | 980 operating_system = 'linux' # Keep this legacy behavior for now. |
| 973 default_variables.setdefault('OS', operating_system) | 981 default_variables.setdefault('OS', operating_system) |
| 974 default_variables.setdefault('SHARED_LIB_SUFFIX', '.so') | 982 default_variables.setdefault('SHARED_LIB_SUFFIX', '.so') |
| 975 default_variables.setdefault('SHARED_LIB_DIR', '$!PRODUCT_DIR/lib') | 983 default_variables.setdefault('SHARED_LIB_DIR', '$!PRODUCT_DIR/lib') |
| 976 default_variables.setdefault('LIB_DIR', '') | 984 default_variables.setdefault('LIB_DIR', '') |
| 977 | 985 |
| 978 | 986 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 997 config_name) | 1005 config_name) |
| 998 | 1006 |
| 999 master_ninja = ninja_syntax.Writer( | 1007 master_ninja = ninja_syntax.Writer( |
| 1000 OpenOutput(os.path.join(options.toplevel_dir, build_dir, 'build.ninja')), | 1008 OpenOutput(os.path.join(options.toplevel_dir, build_dir, 'build.ninja')), |
| 1001 width=120) | 1009 width=120) |
| 1002 | 1010 |
| 1003 # Put build-time support tools in out/{config_name}. | 1011 # Put build-time support tools in out/{config_name}. |
| 1004 gyp.common.CopyTool(flavor, os.path.join(options.toplevel_dir, build_dir)) | 1012 gyp.common.CopyTool(flavor, os.path.join(options.toplevel_dir, build_dir)) |
| 1005 | 1013 |
| 1006 # Grab make settings for CC/CXX. | 1014 # Grab make settings for CC/CXX. |
| 1007 cc, cxx = 'gcc', 'g++' | 1015 if flavor == 'win': |
| 1016 cc = cxx = 'cl' |
| 1017 else: |
| 1018 cc, cxx = 'gcc', 'g++' |
| 1008 build_file, _, _ = gyp.common.ParseQualifiedTarget(target_list[0]) | 1019 build_file, _, _ = gyp.common.ParseQualifiedTarget(target_list[0]) |
| 1009 make_global_settings = data[build_file].get('make_global_settings', []) | 1020 make_global_settings = data[build_file].get('make_global_settings', []) |
| 1010 build_to_root = InvertRelativePath(build_dir) | 1021 build_to_root = InvertRelativePath(build_dir) |
| 1011 for key, value in make_global_settings: | 1022 for key, value in make_global_settings: |
| 1012 if key == 'CC': cc = os.path.join(build_to_root, value) | 1023 if key == 'CC': cc = os.path.join(build_to_root, value) |
| 1013 if key == 'CXX': cxx = os.path.join(build_to_root, value) | 1024 if key == 'CXX': cxx = os.path.join(build_to_root, value) |
| 1014 | 1025 |
| 1015 flock = 'flock' | 1026 flock = 'flock' |
| 1016 if flavor == 'mac': | 1027 if flavor == 'mac': |
| 1017 flock = './gyp-mac-tool flock' | 1028 flock = './gyp-mac-tool flock' |
| 1018 master_ninja.variable('cc', os.environ.get('CC', cc)) | 1029 master_ninja.variable('cc', os.environ.get('CC', cc)) |
| 1019 master_ninja.variable('cxx', os.environ.get('CXX', cxx)) | 1030 master_ninja.variable('cxx', os.environ.get('CXX', cxx)) |
| 1020 master_ninja.variable('ld', flock + ' linker.lock $cxx') | 1031 if flavor == 'win': |
| 1032 master_ninja.variable('ld', 'link') |
| 1033 else: |
| 1034 master_ninja.variable('ld', flock + ' linker.lock $cxx') |
| 1021 master_ninja.variable('cc_host', '$cc') | 1035 master_ninja.variable('cc_host', '$cc') |
| 1022 master_ninja.variable('cxx_host', '$cxx') | 1036 master_ninja.variable('cxx_host', '$cxx') |
| 1023 if flavor == 'mac': | 1037 if flavor == 'mac': |
| 1024 master_ninja.variable('mac_tool', os.path.join('.', 'gyp-mac-tool')) | 1038 master_ninja.variable('mac_tool', os.path.join('.', 'gyp-mac-tool')) |
| 1025 master_ninja.newline() | 1039 master_ninja.newline() |
| 1026 | 1040 |
| 1027 master_ninja.rule( | 1041 if flavor != 'win': |
| 1028 'cc', | 1042 master_ninja.rule( |
| 1029 description='CC $out', | 1043 'cc', |
| 1030 command=('$cc -MMD -MF $out.d $defines $includes $cflags $cflags_c ' | 1044 description='CC $out', |
| 1031 '$cflags_pch_c -c $in -o $out'), | 1045 command=('$cc -MMD -MF $out.d $defines $includes $cflags $cflags_c ' |
| 1032 depfile='$out.d') | 1046 '$cflags_pch_c -c $in -o $out'), |
| 1033 master_ninja.rule( | 1047 depfile='$out.d') |
| 1034 'cxx', | 1048 master_ninja.rule( |
| 1035 description='CXX $out', | 1049 'cxx', |
| 1036 command=('$cxx -MMD -MF $out.d $defines $includes $cflags $cflags_cc ' | 1050 description='CXX $out', |
| 1037 '$cflags_pch_cc -c $in -o $out'), | 1051 command=('$cxx -MMD -MF $out.d $defines $includes $cflags $cflags_cc ' |
| 1038 depfile='$out.d') | 1052 '$cflags_pch_cc -c $in -o $out'), |
| 1039 if flavor != 'mac': | 1053 depfile='$out.d') |
| 1054 else: |
| 1055 # TODO(scottmg): Decide how /showIncludes handling should work in ninja. |
| 1056 master_ninja.rule( |
| 1057 'cc', |
| 1058 description='CC $out', |
| 1059 command=('$cc /nologo $defines $includes $cflags $cflags_c ' |
| 1060 '$cflags_pch_c /c $in /Fo$out'), |
| 1061 depfile='$out.d') |
| 1062 master_ninja.rule( |
| 1063 'cxx', |
| 1064 description='CXX $out', |
| 1065 command=('$cxx /nologo $defines $includes $cflags $cflags_cc ' |
| 1066 '$cflags_pch_cc /c $in /Fo$out'), |
| 1067 depfile='$out.d') |
| 1068 |
| 1069 if flavor != 'mac' and flavor != 'win': |
| 1040 master_ninja.rule( | 1070 master_ninja.rule( |
| 1041 'alink', | 1071 'alink', |
| 1042 description='AR $out', | 1072 description='AR $out', |
| 1043 command='rm -f $out && ar rcsT $out $in') | 1073 command='rm -f $out && ar rcsT $out $in') |
| 1044 master_ninja.rule( | 1074 master_ninja.rule( |
| 1045 'solink', | 1075 'solink', |
| 1046 description='SOLINK $out', | 1076 description='SOLINK $out', |
| 1047 command=('$ld -shared $ldflags -o $out -Wl,-soname=$soname ' | 1077 command=('$ld -shared $ldflags -o $out -Wl,-soname=$soname ' |
| 1048 '-Wl,--whole-archive $in -Wl,--no-whole-archive $libs')) | 1078 '-Wl,--whole-archive $in -Wl,--no-whole-archive $libs')) |
| 1049 master_ninja.rule( | 1079 master_ninja.rule( |
| 1050 'solink_module', | 1080 'solink_module', |
| 1051 description='SOLINK(module) $out', | 1081 description='SOLINK(module) $out', |
| 1052 command=('$ld -shared $ldflags -o $out -Wl,-soname=$soname ' | 1082 command=('$ld -shared $ldflags -o $out -Wl,-soname=$soname ' |
| 1053 '-Wl,--start-group $in -Wl,--end-group $libs')) | 1083 '-Wl,--start-group $in -Wl,--end-group $libs')) |
| 1054 master_ninja.rule( | 1084 master_ninja.rule( |
| 1055 'link', | 1085 'link', |
| 1056 description='LINK $out', | 1086 description='LINK $out', |
| 1057 command=('$ld $ldflags -o $out -Wl,-rpath=\$$ORIGIN/lib ' | 1087 command=('$ld $ldflags -o $out -Wl,-rpath=\$$ORIGIN/lib ' |
| 1058 '-Wl,--start-group $in -Wl,--end-group $libs')) | 1088 '-Wl,--start-group $in -Wl,--end-group $libs')) |
| 1089 elif flavor == 'win': |
| 1090 master_ninja.rule( |
| 1091 'alink', |
| 1092 description='AR $out', |
| 1093 command='lib /nologo /OUT:$out.lib $in') |
| 1094 master_ninja.rule( |
| 1095 'solink', |
| 1096 description='SOLINK $out', |
| 1097 command=('$ld /nologo /DLL $ldflags /OUT:$out.dll $in $libs')) |
| 1098 master_ninja.rule( |
| 1099 'solink_module', |
| 1100 description='SOLINK(module) $out', |
| 1101 command=('$ld /nologo /DLL $ldflags /OUT:$out.dll $in $libs')) |
| 1102 master_ninja.rule( |
| 1103 'link', |
| 1104 description='LINK $out', |
| 1105 command=('$ld /nologo $ldflags /OUT:$out.exe $in $libs')) |
| 1059 else: | 1106 else: |
| 1060 master_ninja.rule( | 1107 master_ninja.rule( |
| 1061 'objc', | 1108 'objc', |
| 1062 description='OBJC $out', | 1109 description='OBJC $out', |
| 1063 command=('$cc -MMD -MF $out.d $defines $includes $cflags $cflags_objc ' | 1110 command=('$cc -MMD -MF $out.d $defines $includes $cflags $cflags_objc ' |
| 1064 '$cflags_pch_objc -c $in -o $out'), | 1111 '$cflags_pch_objc -c $in -o $out'), |
| 1065 depfile='$out.d') | 1112 depfile='$out.d') |
| 1066 master_ninja.rule( | 1113 master_ninja.rule( |
| 1067 'objcxx', | 1114 'objcxx', |
| 1068 description='OBJCXX $out', | 1115 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') | 1150 command='$env $mac_tool $mactool_cmd $in $out') |
| 1104 master_ninja.rule( | 1151 master_ninja.rule( |
| 1105 'package_framework', | 1152 'package_framework', |
| 1106 description='PACKAGE FRAMEWORK $out, POSTBUILDS', | 1153 description='PACKAGE FRAMEWORK $out, POSTBUILDS', |
| 1107 command='$mac_tool package-framework $out $version$postbuilds ' | 1154 command='$mac_tool package-framework $out $version$postbuilds ' |
| 1108 '&& touch $out') | 1155 '&& touch $out') |
| 1109 master_ninja.rule( | 1156 master_ninja.rule( |
| 1110 'stamp', | 1157 'stamp', |
| 1111 description='STAMP $out', | 1158 description='STAMP $out', |
| 1112 command='${postbuilds}touch $out') | 1159 command='${postbuilds}touch $out') |
| 1113 master_ninja.rule( | 1160 if flavor == 'win': |
| 1114 'copy', | 1161 # TODO(scottmg): Copy fallback? |
| 1115 description='COPY $in $out', | 1162 master_ninja.rule( |
| 1116 command='ln -f $in $out 2>/dev/null || (rm -rf $out && cp -af $in $out)') | 1163 'copy', |
| 1164 description='COPY $in $out', |
| 1165 command='mklink /h $out $in >nul') |
| 1166 else: |
| 1167 master_ninja.rule( |
| 1168 'copy', |
| 1169 description='COPY $in $out', |
| 1170 command='ln -f $in $out 2>/dev/null || (rm -rf $out && cp -af $in $out)') |
| 1117 master_ninja.newline() | 1171 master_ninja.newline() |
| 1118 | 1172 |
| 1119 all_targets = set() | 1173 all_targets = set() |
| 1120 for build_file in params['build_files']: | 1174 for build_file in params['build_files']: |
| 1121 for target in gyp.common.AllTargets(target_list, target_dicts, build_file): | 1175 for target in gyp.common.AllTargets(target_list, target_dicts, build_file): |
| 1122 all_targets.add(target) | 1176 all_targets.add(target) |
| 1123 all_outputs = set() | 1177 all_outputs = set() |
| 1124 | 1178 |
| 1125 # target_outputs is a map from qualified target name to a Target object. | 1179 # target_outputs is a map from qualified target name to a Target object. |
| 1126 target_outputs = {} | 1180 target_outputs = {} |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1169 | 1223 |
| 1170 user_config = params.get('generator_flags', {}).get('config', None) | 1224 user_config = params.get('generator_flags', {}).get('config', None) |
| 1171 if user_config: | 1225 if user_config: |
| 1172 GenerateOutputForConfig(target_list, target_dicts, data, params, | 1226 GenerateOutputForConfig(target_list, target_dicts, data, params, |
| 1173 user_config) | 1227 user_config) |
| 1174 else: | 1228 else: |
| 1175 config_names = target_dicts[target_list[0]]['configurations'].keys() | 1229 config_names = target_dicts[target_list[0]]['configurations'].keys() |
| 1176 for config_name in config_names: | 1230 for config_name in config_names: |
| 1177 GenerateOutputForConfig(target_list, target_dicts, data, params, | 1231 GenerateOutputForConfig(target_list, target_dicts, data, params, |
| 1178 config_name) | 1232 config_name) |
| OLD | NEW |