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 copy | 5 import copy |
6 import gyp | 6 import gyp |
7 import gyp.common | 7 import gyp.common |
8 import gyp.msvs_emulation | 8 import gyp.msvs_emulation |
9 import gyp.system_test | 9 import gyp.system_test |
10 import gyp.xcode_emulation | 10 import gyp.xcode_emulation |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
111 # File representing whether any input dependencies necessary for | 111 # File representing whether any input dependencies necessary for |
112 # dependent actions have completed. | 112 # dependent actions have completed. |
113 self.preaction_stamp = None | 113 self.preaction_stamp = None |
114 # File representing whether any input dependencies necessary for | 114 # File representing whether any input dependencies necessary for |
115 # dependent compiles have completed. | 115 # dependent compiles have completed. |
116 self.precompile_stamp = None | 116 self.precompile_stamp = None |
117 # File representing the completion of actions/rules/copies, if any. | 117 # File representing the completion of actions/rules/copies, if any. |
118 self.actions_stamp = None | 118 self.actions_stamp = None |
119 # Path to the output of the link step, if any. | 119 # Path to the output of the link step, if any. |
120 self.binary = None | 120 self.binary = None |
121 # Path to the import library (output by the link step), if any. Used for | |
122 # Windows DLLs. | |
123 self.import_library = None | |
121 # Path to the file representing the completion of building the bundle, | 124 # Path to the file representing the completion of building the bundle, |
122 # if any. | 125 # if any. |
123 self.bundle = None | 126 self.bundle = None |
124 | 127 |
125 def Linkable(self): | 128 def Linkable(self): |
126 """Return true if this is a target that can be linked against.""" | 129 """Return true if this is a target that can be linked against.""" |
127 return self.type in ('static_library', 'shared_library') | 130 return self.type in ('static_library', 'shared_library') |
128 | 131 |
129 def PreActionInput(self): | 132 def PreActionInput(self): |
130 """Return the path, if any, that should be used as a dependency of | 133 """Return the path, if any, that should be used as a dependency of |
(...skipping 525 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
656 'cc': 'cflags_pch_cc', | 659 'cc': 'cflags_pch_cc', |
657 'm': 'cflags_pch_objc', | 660 'm': 'cflags_pch_objc', |
658 'mm': 'cflags_pch_objcc', | 661 'mm': 'cflags_pch_objcc', |
659 }[lang] | 662 }[lang] |
660 | 663 |
661 cmd = { 'c': 'cc', 'cc': 'cxx', 'm': 'objc', 'mm': 'objcxx', }.get(lang) | 664 cmd = { 'c': 'cc', 'cc': 'cxx', 'm': 'objc', 'mm': 'objcxx', }.get(lang) |
662 self.ninja.build(gch, cmd, input, variables=[(var_name, lang_flag)]) | 665 self.ninja.build(gch, cmd, input, variables=[(var_name, lang_flag)]) |
663 | 666 |
664 | 667 |
665 def WriteLink(self, spec, config_name, config, link_deps): | 668 def WriteLink(self, spec, config_name, config, link_deps): |
666 """Write out a link step. Returns the path to the output.""" | 669 """Write out a link step. Returns the path to the output(s).""" |
667 | 670 |
668 command = { | 671 command = { |
669 'executable': 'link', | 672 'executable': 'link', |
670 'loadable_module': 'solink_module', | 673 'loadable_module': 'solink_module', |
671 'shared_library': 'solink', | 674 'shared_library': 'solink', |
672 }[spec['type']] | 675 }[spec['type']] |
673 | 676 |
674 implicit_deps = set() | 677 implicit_deps = set() |
675 | 678 |
676 if 'dependencies' in spec: | 679 if 'dependencies' in spec: |
677 # Two kinds of dependencies: | 680 # Two kinds of dependencies: |
678 # - Linkable dependencies (like a .a or a .so): add them to the link line. | 681 # - Linkable dependencies (like a .a or a .so): add them to the link line. |
679 # - Non-linkable dependencies (like a rule that generates a file | 682 # - Non-linkable dependencies (like a rule that generates a file |
680 # and writes a stamp file): add them to implicit_deps | 683 # and writes a stamp file): add them to implicit_deps |
681 extra_link_deps = set() | 684 extra_link_deps = set() |
682 for dep in spec['dependencies']: | 685 for dep in spec['dependencies']: |
683 target = self.target_outputs.get(dep) | 686 target = self.target_outputs.get(dep) |
684 if not target: | 687 if not target: |
685 continue | 688 continue |
686 linkable = target.Linkable() | 689 linkable = target.Linkable() |
687 if linkable: | 690 if linkable: |
688 extra_link_deps.add(target.binary) | 691 extra_link_deps.add(target.import_library or target.binary) |
Evan Martin
2012/02/21 18:10:47
Would it make more sense for target.Linkable() to
Nico
2012/02/21 18:20:54
Why is this needed? It looks like the build step w
Evan Martin
2012/02/21 18:23:45
extra_link_deps are specifically the files that ne
Nico
2012/02/21 18:27:40
I see. Is it possible to make target.binary the im
| |
689 | 692 |
690 final_output = target.FinalOutput() | 693 final_output = target.FinalOutput() |
691 if not linkable or final_output != target.binary: | 694 if not linkable or final_output != target.binary: |
692 implicit_deps.add(final_output) | 695 implicit_deps.add(final_output) |
693 | 696 |
694 link_deps.extend(list(extra_link_deps)) | 697 link_deps.extend(list(extra_link_deps)) |
695 | 698 |
696 extra_bindings = [] | 699 extra_bindings = [] |
697 if self.is_mac_bundle: | 700 if self.is_mac_bundle: |
698 output = self.ComputeMacBundleBinaryOutput() | 701 output = self.ComputeMacBundleBinaryOutput() |
(...skipping 13 matching lines...) Expand all Loading... | |
712 ldflags))) | 715 ldflags))) |
713 | 716 |
714 libraries = gyp.common.uniquer(map(self.ExpandSpecial, | 717 libraries = gyp.common.uniquer(map(self.ExpandSpecial, |
715 spec.get('libraries', []))) | 718 spec.get('libraries', []))) |
716 if self.flavor == 'mac': | 719 if self.flavor == 'mac': |
717 libraries = self.xcode_settings.AdjustLibraries(libraries) | 720 libraries = self.xcode_settings.AdjustLibraries(libraries) |
718 self.WriteVariableList('libs', libraries) | 721 self.WriteVariableList('libs', libraries) |
719 | 722 |
720 if command in ('solink', 'solink_module'): | 723 if command in ('solink', 'solink_module'): |
721 extra_bindings.append(('soname', os.path.split(output)[1])) | 724 extra_bindings.append(('soname', os.path.split(output)[1])) |
725 if self.flavor == 'win': | |
726 import_lib = output + '.lib' | |
727 extra_bindings.append(('dll', output)) | |
728 extra_bindings.append(('implib', import_lib)) | |
729 output = [output, import_lib] | |
722 | 730 |
723 self.ninja.build(output, command, link_deps, | 731 self.ninja.build(output, command, link_deps, |
724 implicit=list(implicit_deps), | 732 implicit=list(implicit_deps), |
725 variables=extra_bindings) | 733 variables=extra_bindings) |
726 return output | 734 return output |
727 | 735 |
728 def WriteTarget(self, spec, config_name, config, link_deps, compile_deps): | 736 def WriteTarget(self, spec, config_name, config, link_deps, compile_deps): |
729 if spec['type'] == 'none': | 737 if spec['type'] == 'none': |
730 # TODO(evan): don't call this function for 'none' target types, as | 738 # TODO(evan): don't call this function for 'none' target types, as |
731 # it doesn't do anything, and we fake out a 'binary' with a stamp file. | 739 # it doesn't do anything, and we fake out a 'binary' with a stamp file. |
732 self.target.binary = compile_deps | 740 self.target.binary = compile_deps |
733 elif spec['type'] == 'static_library': | 741 elif spec['type'] == 'static_library': |
734 self.target.binary = self.ComputeOutput(spec) | 742 self.target.binary = self.ComputeOutput(spec) |
735 self.ninja.build(self.target.binary, 'alink', link_deps, | 743 self.ninja.build(self.target.binary, 'alink', link_deps, |
736 order_only=compile_deps, | 744 order_only=compile_deps, |
737 variables=[('postbuilds', self.GetPostbuildCommand( | 745 variables=[('postbuilds', self.GetPostbuildCommand( |
738 spec, self.target.binary, self.target.binary))]) | 746 spec, self.target.binary, self.target.binary))]) |
739 else: | 747 else: |
740 self.target.binary = self.WriteLink(spec, config_name, config, link_deps) | 748 output = self.WriteLink(spec, config_name, config, link_deps) |
749 if isinstance(output, list): | |
750 self.target.binary, self.target.import_library = output | |
Evan Martin
2012/02/21 18:10:47
This makes me feel a little funny. I wonder if it'
scottmg
2012/02/21 18:45:46
Yeah, that would be a little tidier.
But, I have
| |
751 else: | |
752 self.target.binary = output | |
741 return self.target.binary | 753 return self.target.binary |
742 | 754 |
743 def WriteMacBundle(self, spec, mac_bundle_depends): | 755 def WriteMacBundle(self, spec, mac_bundle_depends): |
744 assert self.is_mac_bundle | 756 assert self.is_mac_bundle |
745 package_framework = spec['type'] in ('shared_library', 'loadable_module') | 757 package_framework = spec['type'] in ('shared_library', 'loadable_module') |
746 output = self.ComputeMacBundleOutput() | 758 output = self.ComputeMacBundleOutput() |
747 postbuild = self.GetPostbuildCommand(spec, output, self.target.binary, | 759 postbuild = self.GetPostbuildCommand(spec, output, self.target.binary, |
748 is_command_start=not package_framework) | 760 is_command_start=not package_framework) |
749 variables = [] | 761 variables = [] |
750 if postbuild: | 762 if postbuild: |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
896 | 908 |
897 if 'product_dir' in spec: | 909 if 'product_dir' in spec: |
898 path = os.path.join(spec['product_dir'], filename) | 910 path = os.path.join(spec['product_dir'], filename) |
899 return self.ExpandSpecial(path) | 911 return self.ExpandSpecial(path) |
900 | 912 |
901 # Some products go into the output root, libraries go into shared library | 913 # Some products go into the output root, libraries go into shared library |
902 # dir, and everything else goes into the normal place. | 914 # dir, and everything else goes into the normal place. |
903 type_in_output_root = ['executable', 'loadable_module'] | 915 type_in_output_root = ['executable', 'loadable_module'] |
904 if self.flavor == 'mac' and self.toolset == 'target': | 916 if self.flavor == 'mac' and self.toolset == 'target': |
905 type_in_output_root += ['shared_library', 'static_library'] | 917 type_in_output_root += ['shared_library', 'static_library'] |
918 elif self.flavor == 'win' and self.toolset == 'target': | |
919 type_in_output_root += ['shared_library'] | |
Nico
2012/02/21 18:20:54
Is there a test for this?
scottmg
2012/02/21 18:45:46
test/library/gyptest-shared.py
| |
906 | 920 |
907 if type in type_in_output_root: | 921 if type in type_in_output_root: |
908 return filename | 922 return filename |
909 elif type == 'shared_library': | 923 elif type == 'shared_library': |
910 libdir = 'lib' | 924 libdir = 'lib' |
911 if self.toolset != 'target': | 925 if self.toolset != 'target': |
912 libdir = os.path.join('lib', '%s' % self.toolset) | 926 libdir = os.path.join('lib', '%s' % self.toolset) |
913 return os.path.join(libdir, filename) | 927 return os.path.join(libdir, filename) |
914 else: | 928 else: |
915 return self.GypPathToUniqueOutput(filename, qualified=False) | 929 return self.GypPathToUniqueOutput(filename, qualified=False) |
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1111 command=('$ld -shared $ldflags -o $out -Wl,-soname=$soname ' | 1125 command=('$ld -shared $ldflags -o $out -Wl,-soname=$soname ' |
1112 '-Wl,--start-group $in -Wl,--end-group $libs')) | 1126 '-Wl,--start-group $in -Wl,--end-group $libs')) |
1113 master_ninja.rule( | 1127 master_ninja.rule( |
1114 'link', | 1128 'link', |
1115 description='LINK $out', | 1129 description='LINK $out', |
1116 command=('$ld $ldflags -o $out -Wl,-rpath=\$$ORIGIN/lib ' | 1130 command=('$ld $ldflags -o $out -Wl,-rpath=\$$ORIGIN/lib ' |
1117 '-Wl,--start-group $in -Wl,--end-group $libs')) | 1131 '-Wl,--start-group $in -Wl,--end-group $libs')) |
1118 elif flavor == 'win': | 1132 elif flavor == 'win': |
1119 master_ninja.rule( | 1133 master_ninja.rule( |
1120 'alink', | 1134 'alink', |
1121 description='AR $out', | 1135 description='LIB $out', |
1122 command='lib /nologo /OUT:$out $in') | 1136 command='lib /nologo /OUT:$out $in') |
1123 master_ninja.rule( | 1137 master_ninja.rule( |
1124 'solink', | 1138 'solink', |
1125 description='SOLINK $out', | 1139 description='LINK_DLL $dll', |
Evan Martin
2012/02/21 18:10:47
FWIW, the description is free text. So you can us
scottmg
2012/02/21 18:45:46
Done.
| |
1126 command=('$ld /nologo /DLL $ldflags /OUT:$out $in $libs')) | 1140 command=('$ld /nologo /IMPLIB:$implib /DLL $ldflags /OUT:$dll $in $libs')) |
1127 master_ninja.rule( | 1141 master_ninja.rule( |
1128 'solink_module', | 1142 'solink_module', |
1129 description='SOLINK(module) $out', | 1143 description='LINK_DLL $dll', |
1130 command=('$ld /nologo /DLL $ldflags /OUT:$out $in $libs')) | 1144 command=('$ld /nologo /IMPLIB:$implib /DLL $ldflags /OUT:$dll $in $libs')) |
1131 master_ninja.rule( | 1145 master_ninja.rule( |
1132 'link', | 1146 'link', |
1133 description='LINK $out', | 1147 description='LINK $out', |
1134 command=('$ld /nologo $ldflags /OUT:$out $in $libs')) | 1148 command=('$ld /nologo $ldflags /OUT:$out $in $libs')) |
1135 else: | 1149 else: |
1136 master_ninja.rule( | 1150 master_ninja.rule( |
1137 'objc', | 1151 'objc', |
1138 description='OBJC $out', | 1152 description='OBJC $out', |
1139 command=('$cc -MMD -MF $out.d $defines $includes $cflags $cflags_objc ' | 1153 command=('$cc -MMD -MF $out.d $defines $includes $cflags $cflags_objc ' |
1140 '$cflags_pch_objc -c $in -o $out'), | 1154 '$cflags_pch_objc -c $in -o $out'), |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1252 | 1266 |
1253 user_config = params.get('generator_flags', {}).get('config', None) | 1267 user_config = params.get('generator_flags', {}).get('config', None) |
1254 if user_config: | 1268 if user_config: |
1255 GenerateOutputForConfig(target_list, target_dicts, data, params, | 1269 GenerateOutputForConfig(target_list, target_dicts, data, params, |
1256 user_config) | 1270 user_config) |
1257 else: | 1271 else: |
1258 config_names = target_dicts[target_list[0]]['configurations'].keys() | 1272 config_names = target_dicts[target_list[0]]['configurations'].keys() |
1259 for config_name in config_names: | 1273 for config_name in config_names: |
1260 GenerateOutputForConfig(target_list, target_dicts, data, params, | 1274 GenerateOutputForConfig(target_list, target_dicts, data, params, |
1261 config_name) | 1275 config_name) |
OLD | NEW |