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

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: . 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 WriteToc(self, flavor):
Ami GONE FROM CHROMIUM 2012/07/01 03:51:25 s/WriteToc/UsesToc/ ?
Nico 2012/07/01 16:33:22 Done.
157 """Return true if this is a shared library/module.""" 157 """Return if the target should produce a restat rule based on a TOC file."""
Ami GONE FROM CHROMIUM 2012/07/01 03:51:25 s/if/true if/ to match the other method in this cl
Nico 2012/07/01 16:33:22 Done.
158 # For bundles, the .TOC should be produced for the binary, not for
159 # FinalOutput(). But the naive approach would put the TOC file into the
160 # bundle, so don't do this for bundles for now.
161 if flavor == 'win' or self.bundle:
162 return False
158 return self.type in ('shared_library', 'loadable_module') 163 return self.type in ('shared_library', 'loadable_module')
159 164
160 def PreActionInput(self, flavor): 165 def PreActionInput(self, flavor):
161 """Return the path, if any, that should be used as a dependency of 166 """Return the path, if any, that should be used as a dependency of
162 any dependent action step.""" 167 any dependent action step."""
163 if self.SharedLinkable() and flavor not in ['mac', 'win']: 168 if self.WriteToc(flavor):
164 return self.FinalOutput() + '.TOC' 169 return self.FinalOutput() + '.TOC'
165 return self.FinalOutput() or self.preaction_stamp 170 return self.FinalOutput() or self.preaction_stamp
166 171
167 def PreCompileInput(self): 172 def PreCompileInput(self):
168 """Return the path, if any, that should be used as a dependency of 173 """Return the path, if any, that should be used as a dependency of
169 any dependent compile step.""" 174 any dependent compile step."""
170 return self.actions_stamp or self.precompile_stamp 175 return self.actions_stamp or self.precompile_stamp
171 176
172 def FinalOutput(self): 177 def FinalOutput(self):
173 """Return the last output of the target, which depends on all prior 178 """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: 838 if not target:
834 continue 839 continue
835 linkable = target.Linkable() 840 linkable = target.Linkable()
836 if linkable: 841 if linkable:
837 if (self.flavor == 'win' and 842 if (self.flavor == 'win' and
838 target.component_objs and 843 target.component_objs and
839 self.msvs_settings.IsUseLibraryDependencyInputs(config_name)): 844 self.msvs_settings.IsUseLibraryDependencyInputs(config_name)):
840 extra_link_deps |= set(target.component_objs) 845 extra_link_deps |= set(target.component_objs)
841 elif self.flavor == 'win' and target.import_lib: 846 elif self.flavor == 'win' and target.import_lib:
842 extra_link_deps.add(target.import_lib) 847 extra_link_deps.add(target.import_lib)
843 elif target.SharedLinkable() and self.flavor not in ['mac', 'win']: 848 elif target.WriteToc(self.flavor):
844 solibs.add(target.binary) 849 solibs.add(target.binary)
845 implicit_deps.add(target.binary + '.TOC') 850 implicit_deps.add(target.binary + '.TOC')
846 else: 851 else:
847 extra_link_deps.add(target.binary) 852 extra_link_deps.add(target.binary)
848 853
849 final_output = target.FinalOutput() 854 final_output = target.FinalOutput()
850 if not linkable or final_output != target.binary: 855 if not linkable or final_output != target.binary:
851 implicit_deps.add(final_output) 856 implicit_deps.add(final_output)
852 857
853 link_deps.extend(list(extra_link_deps)) 858 link_deps.extend(list(extra_link_deps))
(...skipping 28 matching lines...) Expand all
882 if self.flavor == 'mac': 887 if self.flavor == 'mac':
883 libraries = self.xcode_settings.AdjustLibraries(libraries) 888 libraries = self.xcode_settings.AdjustLibraries(libraries)
884 elif self.flavor == 'win': 889 elif self.flavor == 'win':
885 libraries = self.msvs_settings.AdjustLibraries(libraries) 890 libraries = self.msvs_settings.AdjustLibraries(libraries)
886 self.WriteVariableList('libs', libraries) 891 self.WriteVariableList('libs', libraries)
887 892
888 self.target.binary = output 893 self.target.binary = output
889 894
890 if command in ('solink', 'solink_module'): 895 if command in ('solink', 'solink_module'):
891 extra_bindings.append(('soname', os.path.split(output)[1])) 896 extra_bindings.append(('soname', os.path.split(output)[1]))
892 extra_bindings.append(('lib', output)) 897 extra_bindings.append(('lib',
898 gyp.common.EncodePOSIXShellArgument(output)))
893 if self.flavor == 'win': 899 if self.flavor == 'win':
894 self.target.import_lib = output + '.lib' 900 self.target.import_lib = output + '.lib'
895 extra_bindings.append(('dll', output)) 901 extra_bindings.append(('dll', output))
896 extra_bindings.append(('implib', self.target.import_lib)) 902 extra_bindings.append(('implib', self.target.import_lib))
897 output = [output, self.target.import_lib] 903 output = [output, self.target.import_lib]
898 elif self.flavor != 'mac': 904 else:
899 output = [output, output + '.TOC'] 905 output = [output, output + '.TOC']
900 906
901 if len(solibs): 907 if len(solibs):
902 extra_bindings.append(('solibs', ' '.join(solibs))) 908 extra_bindings.append(('solibs', gyp.common.EncodePOSIXShellList(solibs)))
903 909
904 self.ninja.build(output, command, link_deps, 910 self.ninja.build(output, command, link_deps,
905 implicit=list(implicit_deps), 911 implicit=list(implicit_deps),
906 variables=extra_bindings) 912 variables=extra_bindings)
907 913
908 def WriteTarget(self, spec, config_name, config, link_deps, compile_deps): 914 def WriteTarget(self, spec, config_name, config, link_deps, compile_deps):
909 if spec['type'] == 'none': 915 if spec['type'] == 'none':
910 # TODO(evan): don't call this function for 'none' target types, as 916 # 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. 917 # it doesn't do anything, and we fake out a 'binary' with a stamp file.
912 self.target.binary = compile_deps 918 self.target.binary = compile_deps
(...skipping 556 matching lines...) Expand 10 before | Expand all | Expand 10 after
1469 description='OBJCXX $out', 1475 description='OBJCXX $out',
1470 command=('$cxx -MMD -MF $out.d $defines $includes $cflags $cflags_objcc ' 1476 command=('$cxx -MMD -MF $out.d $defines $includes $cflags $cflags_objcc '
1471 '$cflags_pch_objcc -c $in -o $out'), 1477 '$cflags_pch_objcc -c $in -o $out'),
1472 depfile='$out.d') 1478 depfile='$out.d')
1473 master_ninja.rule( 1479 master_ninja.rule(
1474 'alink', 1480 'alink',
1475 description='LIBTOOL-STATIC $out, POSTBUILDS', 1481 description='LIBTOOL-STATIC $out, POSTBUILDS',
1476 command='rm -f $out && ' 1482 command='rm -f $out && '
1477 './gyp-mac-tool filter-libtool libtool -static -o $out $in' 1483 './gyp-mac-tool filter-libtool libtool -static -o $out $in'
1478 '$postbuilds') 1484 '$postbuilds')
1485
1486 # Record the public interface of $lib in $lib.TOC. See the corresponding
1487 # comment in the posix section above for details.
1488 mtime_preserving_solink_base = (
Ami GONE FROM CHROMIUM 2012/07/01 03:51:25 IWBN to dedup this with the posix version above.
Nico 2012/07/01 16:33:22 It's likely I'll move this into mac-tool soon (onc
1489 'if [ ! -e $lib -o ! -e ${lib}.TOC ] || '
1490 # Always force dependent libraries to relink if this library
Ami GONE FROM CHROMIUM 2012/07/01 03:51:25 s/libraries/targets/
Nico 2012/07/01 16:33:22 Done.
1491 # reexports something. Handling this correctly would require
1492 # recursive TOC dumping but this is rare in practice, so punt.
1493 'otool -l $lib | grep -q LC_REEXPORT_DYLIB ; then '
1494 '%(solink)s && %(extract_toc)s > ${lib}.TOC; '
1495 'else '
1496 '%(solink)s && %(extract_toc)s > ${lib}.tmp && '
1497 'if ! cmp -s ${lib}.tmp ${lib}.TOC; then '
1498 'mv ${lib}.tmp ${lib}.TOC ; '
1499 'fi; '
1500 'fi'
1501 % { 'solink': '$ld -shared $ldflags -o $lib %(suffix)s',
1502 'extract_toc':
1503 '{ otool -l $lib | grep LC_ID_DYLIB -A 2; '
Mark Mentovai 2012/07/01 03:50:42 This should be -A 5. You want to catch the version
Nico 2012/07/01 16:33:22 Done.
1504 'nm -gP $lib |cut -f1-2 -d\' \' |grep \'[ATDBCSI]$$\'; true; }'})
Mark Mentovai 2012/07/01 03:50:42 2. Why not grep -v U$? Seems less fragile in case
Mark Mentovai 2012/07/01 03:50:42 1. Does this work for Objective-C too? (There ough
Nico 2012/07/01 16:33:22 Done. This is a leftover from me using -UP earlier
Nico 2012/07/01 16:33:22 As far as I understand, Objective-C functions alwa
1505
1479 # TODO(thakis): The solink_module rule is likely wrong. Xcode seems to pass 1506 # TODO(thakis): The solink_module rule is likely wrong. Xcode seems to pass
1480 # -bundle -single_module here (for osmesa.so). 1507 # -bundle -single_module here (for osmesa.so).
1481 master_ninja.rule( 1508 master_ninja.rule(
1482 'solink', 1509 'solink',
1483 description='SOLINK $out, POSTBUILDS', 1510 description='SOLINK $lib, POSTBUILDS',
1484 command=('$ld -shared $ldflags -o $out ' 1511 restat=True,
1485 '$in $libs$postbuilds')) 1512 command=(mtime_preserving_solink_base % {
1513 'suffix': '$in $solibs $libs$postbuilds'}))
1486 master_ninja.rule( 1514 master_ninja.rule(
1487 'solink_module', 1515 'solink_module',
1488 description='SOLINK(module) $out, POSTBUILDS', 1516 description='SOLINK(module) $lib, POSTBUILDS',
1489 command=('$ld -shared $ldflags -o $out ' 1517 restat=True,
1490 '$in $libs$postbuilds')) 1518 command=(mtime_preserving_solink_base % {
1519 'suffix': '$in $solibs $libs$postbuilds'}))
1520
1491 master_ninja.rule( 1521 master_ninja.rule(
1492 'link', 1522 'link',
1493 description='LINK $out, POSTBUILDS', 1523 description='LINK $out, POSTBUILDS',
1494 command=('$ld $ldflags -o $out ' 1524 command=('$ld $ldflags -o $out '
1495 '$in $libs$postbuilds')) 1525 '$in $solibs $libs$postbuilds'))
1496 master_ninja.rule( 1526 master_ninja.rule(
1497 'infoplist', 1527 'infoplist',
1498 description='INFOPLIST $out', 1528 description='INFOPLIST $out',
1499 command=('$cc -E -P -Wno-trigraphs -x c $defines $in -o $out && ' 1529 command=('$cc -E -P -Wno-trigraphs -x c $defines $in -o $out && '
1500 'plutil -convert xml1 $out $out')) 1530 'plutil -convert xml1 $out $out'))
1501 master_ninja.rule( 1531 master_ninja.rule(
1502 'mac_tool', 1532 'mac_tool',
1503 description='MACTOOL $mactool_cmd $in', 1533 description='MACTOOL $mactool_cmd $in',
1504 command='$env $mac_tool $mactool_cmd $in $out') 1534 command='$env $mac_tool $mactool_cmd $in $out')
1505 master_ninja.rule( 1535 master_ninja.rule(
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
1597 1627
1598 user_config = params.get('generator_flags', {}).get('config', None) 1628 user_config = params.get('generator_flags', {}).get('config', None)
1599 if user_config: 1629 if user_config:
1600 GenerateOutputForConfig(target_list, target_dicts, data, params, 1630 GenerateOutputForConfig(target_list, target_dicts, data, params,
1601 user_config) 1631 user_config)
1602 else: 1632 else:
1603 config_names = target_dicts[target_list[0]]['configurations'].keys() 1633 config_names = target_dicts[target_list[0]]['configurations'].keys()
1604 for config_name in config_names: 1634 for config_name in config_names:
1605 GenerateOutputForConfig(target_list, target_dicts, data, params, 1635 GenerateOutputForConfig(target_list, target_dicts, data, params,
1606 config_name) 1636 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