Chromium Code Reviews| Index: pylib/gyp/generator/ninja.py |
| =================================================================== |
| --- pylib/gyp/generator/ninja.py (revision 1425) |
| +++ pylib/gyp/generator/ninja.py (working copy) |
| @@ -153,14 +153,20 @@ |
| """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 UsesToc(self, flavor): |
| + """Return true if the target should produce a restat rule based on a TOC |
| + file.""" |
| + # 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.UsesToc(flavor): |
| return self.FinalOutput() + '.TOC' |
| return self.FinalOutput() or self.preaction_stamp |
| @@ -840,7 +846,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.UsesToc(self.flavor): |
| solibs.add(target.binary) |
| implicit_deps.add(target.binary + '.TOC') |
| else: |
| @@ -889,17 +895,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 +1483,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 = ( |
| + 'if [ ! -e $lib -o ! -e ${lib}.TOC ] || ' |
| + # Always force dependent targets to relink if this library |
| + # 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 5; ' |
| + '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.
|
| + |
| # 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', |