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

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

Issue 10704054: ninja mac: Smarter dylib linking. (Closed) Base URL: http://gyp.googlecode.com/svn/trunk/
Patch Set: comments Created 8 years, 5 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/ninja/solibs_avoid_relinking/gyptest-solibs-avoid-relinking.py » ('j') | no next file with comments »
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.MSVSVersion 9 import gyp.MSVSVersion
10 import gyp.system_test 10 import gyp.system_test
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
146 self.component_objs = None 146 self.component_objs = None
147 # Windows only. The import .lib is the output of a build step, but 147 # Windows only. The import .lib is the output of a build step, but
148 # because dependents only link against the lib (not both the lib and the 148 # because dependents only link against the lib (not both the lib and the
149 # dll) we keep track of the import library here. 149 # dll) we keep track of the import library here.
150 self.import_lib = None 150 self.import_lib = None
151 151
152 def Linkable(self): 152 def Linkable(self):
153 """Return true if this is a target that can be linked against.""" 153 """Return true if this is a target that can be linked against."""
154 return self.type in ('static_library', 'shared_library') 154 return self.type in ('static_library', 'shared_library')
155 155
156 def SharedLinkable(self): 156 def UsesToc(self, flavor):
157 """Return true if this is a shared library/module.""" 157 """Return true if the target should produce a restat rule based on a TOC
158 file."""
159 # For bundles, the .TOC should be produced for the binary, not for
160 # FinalOutput(). But the naive approach would put the TOC file into the
161 # bundle, so don't do this for bundles for now.
162 if flavor == 'win' or self.bundle:
163 return False
158 return self.type in ('shared_library', 'loadable_module') 164 return self.type in ('shared_library', 'loadable_module')
159 165
160 def PreActionInput(self, flavor): 166 def PreActionInput(self, flavor):
161 """Return the path, if any, that should be used as a dependency of 167 """Return the path, if any, that should be used as a dependency of
162 any dependent action step.""" 168 any dependent action step."""
163 if self.SharedLinkable() and flavor not in ['mac', 'win']: 169 if self.UsesToc(flavor):
164 return self.FinalOutput() + '.TOC' 170 return self.FinalOutput() + '.TOC'
165 return self.FinalOutput() or self.preaction_stamp 171 return self.FinalOutput() or self.preaction_stamp
166 172
167 def PreCompileInput(self): 173 def PreCompileInput(self):
168 """Return the path, if any, that should be used as a dependency of 174 """Return the path, if any, that should be used as a dependency of
169 any dependent compile step.""" 175 any dependent compile step."""
170 return self.actions_stamp or self.precompile_stamp 176 return self.actions_stamp or self.precompile_stamp
171 177
172 def FinalOutput(self): 178 def FinalOutput(self):
173 """Return the last output of the target, which depends on all prior 179 """Return the last output of the target, which depends on all prior
(...skipping 659 matching lines...) Expand 10 before | Expand all | Expand 10 after
833 if not target: 839 if not target:
834 continue 840 continue
835 linkable = target.Linkable() 841 linkable = target.Linkable()
836 if linkable: 842 if linkable:
837 if (self.flavor == 'win' and 843 if (self.flavor == 'win' and
838 target.component_objs and 844 target.component_objs and
839 self.msvs_settings.IsUseLibraryDependencyInputs(config_name)): 845 self.msvs_settings.IsUseLibraryDependencyInputs(config_name)):
840 extra_link_deps |= set(target.component_objs) 846 extra_link_deps |= set(target.component_objs)
841 elif self.flavor == 'win' and target.import_lib: 847 elif self.flavor == 'win' and target.import_lib:
842 extra_link_deps.add(target.import_lib) 848 extra_link_deps.add(target.import_lib)
843 elif target.SharedLinkable() and self.flavor not in ['mac', 'win']: 849 elif target.UsesToc(self.flavor):
844 solibs.add(target.binary) 850 solibs.add(target.binary)
845 implicit_deps.add(target.binary + '.TOC') 851 implicit_deps.add(target.binary + '.TOC')
846 else: 852 else:
847 extra_link_deps.add(target.binary) 853 extra_link_deps.add(target.binary)
848 854
849 final_output = target.FinalOutput() 855 final_output = target.FinalOutput()
850 if not linkable or final_output != target.binary: 856 if not linkable or final_output != target.binary:
851 implicit_deps.add(final_output) 857 implicit_deps.add(final_output)
852 858
853 link_deps.extend(list(extra_link_deps)) 859 link_deps.extend(list(extra_link_deps))
(...skipping 28 matching lines...) Expand all
882 if self.flavor == 'mac': 888 if self.flavor == 'mac':
883 libraries = self.xcode_settings.AdjustLibraries(libraries) 889 libraries = self.xcode_settings.AdjustLibraries(libraries)
884 elif self.flavor == 'win': 890 elif self.flavor == 'win':
885 libraries = self.msvs_settings.AdjustLibraries(libraries) 891 libraries = self.msvs_settings.AdjustLibraries(libraries)
886 self.WriteVariableList('libs', libraries) 892 self.WriteVariableList('libs', libraries)
887 893
888 self.target.binary = output 894 self.target.binary = output
889 895
890 if command in ('solink', 'solink_module'): 896 if command in ('solink', 'solink_module'):
891 extra_bindings.append(('soname', os.path.split(output)[1])) 897 extra_bindings.append(('soname', os.path.split(output)[1]))
892 extra_bindings.append(('lib', output)) 898 extra_bindings.append(('lib',
899 gyp.common.EncodePOSIXShellArgument(output)))
893 if self.flavor == 'win': 900 if self.flavor == 'win':
894 self.target.import_lib = output + '.lib' 901 self.target.import_lib = output + '.lib'
895 extra_bindings.append(('dll', output)) 902 extra_bindings.append(('dll', output))
896 extra_bindings.append(('implib', self.target.import_lib)) 903 extra_bindings.append(('implib', self.target.import_lib))
897 output = [output, self.target.import_lib] 904 output = [output, self.target.import_lib]
898 elif self.flavor != 'mac': 905 else:
899 output = [output, output + '.TOC'] 906 output = [output, output + '.TOC']
900 907
901 if len(solibs): 908 if len(solibs):
902 extra_bindings.append(('solibs', ' '.join(solibs))) 909 extra_bindings.append(('solibs', gyp.common.EncodePOSIXShellList(solibs)))
903 910
904 self.ninja.build(output, command, link_deps, 911 self.ninja.build(output, command, link_deps,
905 implicit=list(implicit_deps), 912 implicit=list(implicit_deps),
906 variables=extra_bindings) 913 variables=extra_bindings)
907 914
908 def WriteTarget(self, spec, config_name, config, link_deps, compile_deps): 915 def WriteTarget(self, spec, config_name, config, link_deps, compile_deps):
909 if spec['type'] == 'none': 916 if spec['type'] == 'none':
910 # TODO(evan): don't call this function for 'none' target types, as 917 # TODO(evan): don't call this function for 'none' target types, as
911 # it doesn't do anything, and we fake out a 'binary' with a stamp file. 918 # it doesn't do anything, and we fake out a 'binary' with a stamp file.
912 self.target.binary = compile_deps 919 self.target.binary = compile_deps
(...skipping 556 matching lines...) Expand 10 before | Expand all | Expand 10 after
1469 description='OBJCXX $out', 1476 description='OBJCXX $out',
1470 command=('$cxx -MMD -MF $out.d $defines $includes $cflags $cflags_objcc ' 1477 command=('$cxx -MMD -MF $out.d $defines $includes $cflags $cflags_objcc '
1471 '$cflags_pch_objcc -c $in -o $out'), 1478 '$cflags_pch_objcc -c $in -o $out'),
1472 depfile='$out.d') 1479 depfile='$out.d')
1473 master_ninja.rule( 1480 master_ninja.rule(
1474 'alink', 1481 'alink',
1475 description='LIBTOOL-STATIC $out, POSTBUILDS', 1482 description='LIBTOOL-STATIC $out, POSTBUILDS',
1476 command='rm -f $out && ' 1483 command='rm -f $out && '
1477 './gyp-mac-tool filter-libtool libtool -static -o $out $in' 1484 './gyp-mac-tool filter-libtool libtool -static -o $out $in'
1478 '$postbuilds') 1485 '$postbuilds')
1486
1487 # Record the public interface of $lib in $lib.TOC. See the corresponding
1488 # comment in the posix section above for details.
1489 mtime_preserving_solink_base = (
1490 'if [ ! -e $lib -o ! -e ${lib}.TOC ] || '
1491 # Always force dependent targets to relink if this library
1492 # reexports something. Handling this correctly would require
1493 # recursive TOC dumping but this is rare in practice, so punt.
1494 'otool -l $lib | grep -q LC_REEXPORT_DYLIB ; then '
1495 '%(solink)s && %(extract_toc)s > ${lib}.TOC; '
1496 'else '
1497 '%(solink)s && %(extract_toc)s > ${lib}.tmp && '
1498 'if ! cmp -s ${lib}.tmp ${lib}.TOC; then '
1499 'mv ${lib}.tmp ${lib}.TOC ; '
1500 'fi; '
1501 'fi'
1502 % { 'solink': '$ld -shared $ldflags -o $lib %(suffix)s',
1503 'extract_toc':
1504 '{ otool -l $lib | grep LC_ID_DYLIB -A 5; '
1505 'nm -gP $lib |cut -f1-2 -d\' \' |grep -v U$$; true; }'})
Mark Mentovai 2012/07/01 18:32:30 I’d be consistent with the preceding line and put
Nico 2012/07/01 19:44:32 Done.
1506
1479 # TODO(thakis): The solink_module rule is likely wrong. Xcode seems to pass 1507 # TODO(thakis): The solink_module rule is likely wrong. Xcode seems to pass
1480 # -bundle -single_module here (for osmesa.so). 1508 # -bundle -single_module here (for osmesa.so).
1481 master_ninja.rule( 1509 master_ninja.rule(
1482 'solink', 1510 'solink',
1483 description='SOLINK $out, POSTBUILDS', 1511 description='SOLINK $lib, POSTBUILDS',
1484 command=('$ld -shared $ldflags -o $out ' 1512 restat=True,
1485 '$in $libs$postbuilds')) 1513 command=(mtime_preserving_solink_base % {
1514 'suffix': '$in $solibs $libs$postbuilds'}))
1486 master_ninja.rule( 1515 master_ninja.rule(
1487 'solink_module', 1516 'solink_module',
1488 description='SOLINK(module) $out, POSTBUILDS', 1517 description='SOLINK(module) $lib, POSTBUILDS',
1489 command=('$ld -shared $ldflags -o $out ' 1518 restat=True,
1490 '$in $libs$postbuilds')) 1519 command=(mtime_preserving_solink_base % {
1520 'suffix': '$in $solibs $libs$postbuilds'}))
1521
1491 master_ninja.rule( 1522 master_ninja.rule(
1492 'link', 1523 'link',
1493 description='LINK $out, POSTBUILDS', 1524 description='LINK $out, POSTBUILDS',
1494 command=('$ld $ldflags -o $out ' 1525 command=('$ld $ldflags -o $out '
1495 '$in $libs$postbuilds')) 1526 '$in $solibs $libs$postbuilds'))
1496 master_ninja.rule( 1527 master_ninja.rule(
1497 'infoplist', 1528 'infoplist',
1498 description='INFOPLIST $out', 1529 description='INFOPLIST $out',
1499 command=('$cc -E -P -Wno-trigraphs -x c $defines $in -o $out && ' 1530 command=('$cc -E -P -Wno-trigraphs -x c $defines $in -o $out && '
1500 'plutil -convert xml1 $out $out')) 1531 'plutil -convert xml1 $out $out'))
1501 master_ninja.rule( 1532 master_ninja.rule(
1502 'mac_tool', 1533 'mac_tool',
1503 description='MACTOOL $mactool_cmd $in', 1534 description='MACTOOL $mactool_cmd $in',
1504 command='$env $mac_tool $mactool_cmd $in $out') 1535 command='$env $mac_tool $mactool_cmd $in $out')
1505 master_ninja.rule( 1536 master_ninja.rule(
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
1597 1628
1598 user_config = params.get('generator_flags', {}).get('config', None) 1629 user_config = params.get('generator_flags', {}).get('config', None)
1599 if user_config: 1630 if user_config:
1600 GenerateOutputForConfig(target_list, target_dicts, data, params, 1631 GenerateOutputForConfig(target_list, target_dicts, data, params,
1601 user_config) 1632 user_config)
1602 else: 1633 else:
1603 config_names = target_dicts[target_list[0]]['configurations'].keys() 1634 config_names = target_dicts[target_list[0]]['configurations'].keys()
1604 for config_name in config_names: 1635 for config_name in config_names:
1605 GenerateOutputForConfig(target_list, target_dicts, data, params, 1636 GenerateOutputForConfig(target_list, target_dicts, data, params,
1606 config_name) 1637 config_name)
OLDNEW
« no previous file with comments | « no previous file | test/ninja/solibs_avoid_relinking/gyptest-solibs-avoid-relinking.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698