Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(424)

Side by Side Diff: pylib/gyp/generator/ninja.py

Issue 9424042: Support import libraries for Windows ninja (Closed) Base URL: http://gyp.googlecode.com/svn/trunk/
Patch Set: Created 8 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | test/lib/TestGyp.py » ('j') | test/lib/TestGyp.py » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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)
OLDNEW
« no previous file with comments | « no previous file | test/lib/TestGyp.py » ('j') | test/lib/TestGyp.py » ('J')

Powered by Google App Engine
This is Rietveld 408576698