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

Unified 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, 6 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | test/ninja/solibs_avoid_relinking/gyptest-solibs-avoid-relinking.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pylib/gyp/generator/ninja.py
===================================================================
--- pylib/gyp/generator/ninja.py (revision 1425)
+++ pylib/gyp/generator/ninja.py (working copy)
@@ -153,14 +153,19 @@
"""Return true if this is a target that can be linked against."""
return self.type in ('static_library', 'shared_library')
- def SharedLinkable(self):
- """Return true if this is a shared library/module."""
+ 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.
+ """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.
+ # For bundles, the .TOC should be produced for the binary, not for
+ # FinalOutput(). But the naive approach would put the TOC file into the
+ # bundle, so don't do this for bundles for now.
+ if flavor == 'win' or self.bundle:
+ return False
return self.type in ('shared_library', 'loadable_module')
def PreActionInput(self, flavor):
"""Return the path, if any, that should be used as a dependency of
any dependent action step."""
- if self.SharedLinkable() and flavor not in ['mac', 'win']:
+ if self.WriteToc(flavor):
return self.FinalOutput() + '.TOC'
return self.FinalOutput() or self.preaction_stamp
@@ -840,7 +845,7 @@
extra_link_deps |= set(target.component_objs)
elif self.flavor == 'win' and target.import_lib:
extra_link_deps.add(target.import_lib)
- elif target.SharedLinkable() and self.flavor not in ['mac', 'win']:
+ elif target.WriteToc(self.flavor):
solibs.add(target.binary)
implicit_deps.add(target.binary + '.TOC')
else:
@@ -889,17 +894,18 @@
if command in ('solink', 'solink_module'):
extra_bindings.append(('soname', os.path.split(output)[1]))
- extra_bindings.append(('lib', output))
+ extra_bindings.append(('lib',
+ gyp.common.EncodePOSIXShellArgument(output)))
if self.flavor == 'win':
self.target.import_lib = output + '.lib'
extra_bindings.append(('dll', output))
extra_bindings.append(('implib', self.target.import_lib))
output = [output, self.target.import_lib]
- elif self.flavor != 'mac':
+ else:
output = [output, output + '.TOC']
if len(solibs):
- extra_bindings.append(('solibs', ' '.join(solibs)))
+ extra_bindings.append(('solibs', gyp.common.EncodePOSIXShellList(solibs)))
self.ninja.build(output, command, link_deps,
implicit=list(implicit_deps),
@@ -1476,23 +1482,47 @@
command='rm -f $out && '
'./gyp-mac-tool filter-libtool libtool -static -o $out $in'
'$postbuilds')
+
+ # Record the public interface of $lib in $lib.TOC. See the corresponding
+ # comment in the posix section above for details.
+ 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
+ 'if [ ! -e $lib -o ! -e ${lib}.TOC ] || '
+ # 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.
+ # reexports something. Handling this correctly would require
+ # recursive TOC dumping but this is rare in practice, so punt.
+ 'otool -l $lib | grep -q LC_REEXPORT_DYLIB ; then '
+ '%(solink)s && %(extract_toc)s > ${lib}.TOC; '
+ 'else '
+ '%(solink)s && %(extract_toc)s > ${lib}.tmp && '
+ 'if ! cmp -s ${lib}.tmp ${lib}.TOC; then '
+ 'mv ${lib}.tmp ${lib}.TOC ; '
+ 'fi; '
+ 'fi'
+ % { 'solink': '$ld -shared $ldflags -o $lib %(suffix)s',
+ 'extract_toc':
+ '{ 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.
+ '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
+
# TODO(thakis): The solink_module rule is likely wrong. Xcode seems to pass
# -bundle -single_module here (for osmesa.so).
master_ninja.rule(
'solink',
- description='SOLINK $out, POSTBUILDS',
- command=('$ld -shared $ldflags -o $out '
- '$in $libs$postbuilds'))
+ description='SOLINK $lib, POSTBUILDS',
+ restat=True,
+ command=(mtime_preserving_solink_base % {
+ 'suffix': '$in $solibs $libs$postbuilds'}))
master_ninja.rule(
'solink_module',
- description='SOLINK(module) $out, POSTBUILDS',
- command=('$ld -shared $ldflags -o $out '
- '$in $libs$postbuilds'))
+ description='SOLINK(module) $lib, POSTBUILDS',
+ restat=True,
+ command=(mtime_preserving_solink_base % {
+ 'suffix': '$in $solibs $libs$postbuilds'}))
+
master_ninja.rule(
'link',
description='LINK $out, POSTBUILDS',
command=('$ld $ldflags -o $out '
- '$in $libs$postbuilds'))
+ '$in $solibs $libs$postbuilds'))
master_ninja.rule(
'infoplist',
description='INFOPLIST $out',
« 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