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

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

Issue 9121011: ninja/mac: Don't choke on bundles that have no 'sources'. (Closed) Base URL: http://gyp.googlecode.com/svn/trunk/
Patch Set: comment Created 8 years, 11 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
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 gyp 5 import gyp
6 import gyp.common 6 import gyp.common
7 import gyp.system_test 7 import gyp.system_test
8 import gyp.xcode_emulation 8 import gyp.xcode_emulation
9 import os.path 9 import os.path
10 import re 10 import re
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after
272 config_name, config, sources, compile_depends, 272 config_name, config, sources, compile_depends,
273 gyp.xcode_emulation.MacPrefixHeader( 273 gyp.xcode_emulation.MacPrefixHeader(
274 self.xcode_settings, self.GypPathToNinja, 274 self.xcode_settings, self.GypPathToNinja,
275 lambda path, lang: self.GypPathToUniqueOutput(path + '-' + lang))) 275 lambda path, lang: self.GypPathToUniqueOutput(path + '-' + lang)))
276 # Some actions/rules output 'sources' that are already object files. 276 # Some actions/rules output 'sources' that are already object files.
277 link_deps += [self.GypPathToNinja(f) for f in sources if f.endswith('.o')] 277 link_deps += [self.GypPathToNinja(f) for f in sources if f.endswith('.o')]
278 278
279 # The final output of our target depends on the last output of the 279 # The final output of our target depends on the last output of the
280 # above steps. 280 # above steps.
281 output = output_binary = None 281 output = output_binary = None
282 final_deps = link_deps or sources_depends or actions_depends 282 if link_deps or sources_depends or actions_depends:
283 if final_deps:
284 output, output_binary = self.WriteTarget( 283 output, output_binary = self.WriteTarget(
285 spec, config_name, config, final_deps, mac_bundle_depends, 284 spec, config_name, config, link_deps,
285 sources_depends or actions_depends, mac_bundle_depends,
286 order_only=actions_depends) 286 order_only=actions_depends)
287 if self.name != output and self.toolset == 'target': 287 if self.name != output and self.toolset == 'target':
288 # Write a short name to build this target. This benefits both the 288 # Write a short name to build this target. This benefits both the
289 # "build chrome" case as well as the gyp tests, which expect to be 289 # "build chrome" case as well as the gyp tests, which expect to be
290 # able to run actions and build libraries by their short name. 290 # able to run actions and build libraries by their short name.
291 self.ninja.build(self.name, 'phony', output) 291 self.ninja.build(self.name, 'phony', output)
Evan Martin 2012/01/07 21:29:00 Hm, now I'm confused. Won't this write out this p
Nico 2012/01/07 21:32:33 Yes, that's the point of this change :-) output wi
292 return output, output_binary, compile_depends 292 return output, output_binary, compile_depends
293 293
294 def WriteActionsRulesCopies(self, spec, extra_sources, prebuild, 294 def WriteActionsRulesCopies(self, spec, extra_sources, prebuild,
295 mac_bundle_depends): 295 mac_bundle_depends):
296 """Write out the Actions, Rules, and Copies steps. Return any outputs 296 """Write out the Actions, Rules, and Copies steps. Return any outputs
297 of these steps (or a stamp file if there are lots of outputs).""" 297 of these steps (or a stamp file if there are lots of outputs)."""
298 outputs = [] 298 outputs = []
299 extra_mac_bundle_resources = [] 299 extra_mac_bundle_resources = []
300 300
301 if 'actions' in spec: 301 if 'actions' in spec:
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after
565 var_name = { 565 var_name = {
566 'c': 'cflags_pch_c', 566 'c': 'cflags_pch_c',
567 'cc': 'cflags_pch_cc', 567 'cc': 'cflags_pch_cc',
568 'm': 'cflags_pch_objc', 568 'm': 'cflags_pch_objc',
569 'mm': 'cflags_pch_objcc', 569 'mm': 'cflags_pch_objcc',
570 }[lang] 570 }[lang]
571 571
572 cmd = { 'c': 'cc', 'cc': 'cxx', 'm': 'objc', 'mm': 'objcxx', }.get(lang) 572 cmd = { 'c': 'cc', 'cc': 'cxx', 'm': 'objc', 'mm': 'objcxx', }.get(lang)
573 self.ninja.build(gch, cmd, input, variables=[(var_name, lang_flag)]) 573 self.ninja.build(gch, cmd, input, variables=[(var_name, lang_flag)])
574 574
575 def WriteTarget(self, spec, config_name, config, final_deps, 575 def WriteTarget(self, spec, config_name, config, link_deps, final_deps,
576 mac_bundle_depends, order_only): 576 mac_bundle_depends, order_only):
577 if spec['type'] == 'none': 577 if spec['type'] == 'none':
578 # This target doesn't have any explicit final output, but is instead 578 # This target doesn't have any explicit final output, but is instead
579 # used for its effects before the final output (e.g. copies steps). 579 # used for its effects before the final output (e.g. copies steps).
580 # Reuse the existing output if it's easy. 580 # Reuse the existing output if it's easy.
581 if len(final_deps) == 1: 581 if len(final_deps) == 1:
582 return final_deps[0], final_deps[0] 582 return final_deps[0], final_deps[0]
583 # Otherwise, fall through to writing out a stamp file. 583 # Otherwise, fall through to writing out a stamp file.
584 584
585 if self.is_mac_bundle:
586 output = self.ComputeMacBundleOutput(spec)
587 output_binary = self.ComputeMacBundleBinaryOutput(spec)
588 mac_bundle_depends.append(output_binary)
589 else:
590 output = output_binary = self.ComputeOutput(spec)
591
592 output_uses_linker = spec['type'] in ('executable', 'loadable_module', 585 output_uses_linker = spec['type'] in ('executable', 'loadable_module',
593 'shared_library') 586 'shared_library')
594 587
595 implicit_deps = set() 588 implicit_deps = set()
596 if 'dependencies' in spec: 589 if 'dependencies' in spec:
597 # Two kinds of dependencies: 590 # Two kinds of dependencies:
598 # - Linkable dependencies (like a .a or a .so): add them to the link line. 591 # - Linkable dependencies (like a .a or a .so): add them to the link line.
599 # - Non-linkable dependencies (like a rule that generates a file 592 # - Non-linkable dependencies (like a rule that generates a file
600 # and writes a stamp file): add them to implicit_deps 593 # and writes a stamp file): add them to implicit_deps
601 if output_uses_linker: 594 if output_uses_linker:
602 extra_deps = set() 595 extra_deps = set()
603 for dep in spec['dependencies']: 596 for dep in spec['dependencies']:
604 input, _, linkable = self.target_outputs.get(dep, (None, [], False)) 597 input, _, linkable = self.target_outputs.get(dep, (None, [], False))
605 if not input: 598 if not input:
606 continue 599 continue
607 if linkable: 600 if linkable:
608 extra_deps.add(input) 601 extra_deps.add(input)
609 else: 602 else:
610 # TODO: Chrome-specific HACK. Chrome runs this lastchange rule on 603 # TODO: Chrome-specific HACK. Chrome runs this lastchange rule on
611 # every build, but we don't want to rebuild when it runs. 604 # every build, but we don't want to rebuild when it runs.
612 if 'lastchange' not in input: 605 if 'lastchange' not in input:
613 implicit_deps.add(input) 606 implicit_deps.add(input)
614 final_deps.extend(list(extra_deps)) 607 link_deps.extend(list(extra_deps))
608
609 if self.is_mac_bundle:
610 output = self.ComputeMacBundleOutput(spec)
611 output_binary = self.ComputeMacBundleBinaryOutput(spec)
612 if not link_deps:
613 output_binary = self.ComputeOutput(spec, type='none')
614 mac_bundle_depends.append(output_binary)
615 else:
616 output = output_binary = self.ComputeOutput(spec)
617
615 command_map = { 618 command_map = {
616 'executable': 'link', 619 'executable': 'link',
617 'static_library': 'alink', 620 'static_library': 'alink',
618 'loadable_module': 'solink_module', 621 'loadable_module': 'solink_module',
619 'shared_library': 'solink', 622 'shared_library': 'solink',
620 'none': 'stamp', 623 'none': 'stamp',
621 } 624 }
622 command = command_map[spec['type']] 625 command = command_map[spec['type']]
623 626
627 if link_deps:
628 final_deps = link_deps
629 else:
630 command = 'stamp'
631 order_only += final_deps
632 final_deps = []
633
624 if output_uses_linker: 634 if output_uses_linker:
625 if self.flavor == 'mac': 635 if self.flavor == 'mac':
626 ldflags = self.xcode_settings.GetLdflags(config_name, 636 ldflags = self.xcode_settings.GetLdflags(config_name,
627 self.ExpandSpecial(generator_default_variables['PRODUCT_DIR']), 637 self.ExpandSpecial(generator_default_variables['PRODUCT_DIR']),
628 self.GypPathToNinja) 638 self.GypPathToNinja)
629 else: 639 else:
630 ldflags = config.get('ldflags', []) 640 ldflags = config.get('ldflags', [])
631 self.WriteVariableList('ldflags', 641 self.WriteVariableList('ldflags',
632 gyp.common.uniquer(map(self.ExpandSpecial, 642 gyp.common.uniquer(map(self.ExpandSpecial,
633 ldflags))) 643 ldflags)))
(...skipping 28 matching lines...) Expand all
662 assert self.is_mac_bundle 672 assert self.is_mac_bundle
663 path = self.ExpandSpecial(generator_default_variables['PRODUCT_DIR']) 673 path = self.ExpandSpecial(generator_default_variables['PRODUCT_DIR'])
664 return os.path.join(path, self.xcode_settings.GetWrapperName()) 674 return os.path.join(path, self.xcode_settings.GetWrapperName())
665 675
666 def ComputeMacBundleBinaryOutput(self, spec): 676 def ComputeMacBundleBinaryOutput(self, spec):
667 """Return the 'output' (full output path) to the binary in a bundle.""" 677 """Return the 'output' (full output path) to the binary in a bundle."""
668 assert self.is_mac_bundle 678 assert self.is_mac_bundle
669 path = self.ExpandSpecial(generator_default_variables['PRODUCT_DIR']) 679 path = self.ExpandSpecial(generator_default_variables['PRODUCT_DIR'])
670 return os.path.join(path, self.xcode_settings.GetExecutablePath()) 680 return os.path.join(path, self.xcode_settings.GetExecutablePath())
671 681
672 def ComputeOutputFileName(self, spec): 682 def ComputeOutputFileName(self, spec, type=None):
673 """Compute the filename of the final output for the current target.""" 683 """Compute the filename of the final output for the current target."""
684 if not type:
685 type = spec['type']
674 686
675 # Compute filename prefix: the product prefix, or a default for 687 # Compute filename prefix: the product prefix, or a default for
676 # the product type. 688 # the product type.
677 DEFAULT_PREFIX = { 689 DEFAULT_PREFIX = {
678 'loadable_module': 'lib', 690 'loadable_module': 'lib',
679 'shared_library': 'lib', 691 'shared_library': 'lib',
680 'static_library': 'lib', 692 'static_library': 'lib',
681 } 693 }
682 prefix = spec.get('product_prefix', DEFAULT_PREFIX.get(spec['type'], '')) 694 prefix = spec.get('product_prefix', DEFAULT_PREFIX.get(type, ''))
683 695
684 # Compute filename extension: the product extension, or a default 696 # Compute filename extension: the product extension, or a default
685 # for the product type. 697 # for the product type.
686 DEFAULT_EXTENSION = { 698 DEFAULT_EXTENSION = {
687 'static_library': 'a', 699 'static_library': 'a',
688 'loadable_module': 'so', 700 'loadable_module': 'so',
689 'shared_library': 'so', 701 'shared_library': 'so',
690 } 702 }
691 extension = spec.get('product_extension', 703 extension = spec.get('product_extension',
692 DEFAULT_EXTENSION.get(spec['type'], '')) 704 DEFAULT_EXTENSION.get(type, ''))
693 if extension: 705 if extension:
694 extension = '.' + extension 706 extension = '.' + extension
695 707
696 if 'product_name' in spec: 708 if 'product_name' in spec:
697 # If we were given an explicit name, use that. 709 # If we were given an explicit name, use that.
698 target = spec['product_name'] 710 target = spec['product_name']
699 else: 711 else:
700 # Otherwise, derive a name from the target name. 712 # Otherwise, derive a name from the target name.
701 target = spec['target_name'] 713 target = spec['target_name']
702 if prefix == 'lib': 714 if prefix == 'lib':
703 # Snip out an extra 'lib' from libs if appropriate. 715 # Snip out an extra 'lib' from libs if appropriate.
704 target = StripPrefix(target, 'lib') 716 target = StripPrefix(target, 'lib')
705 717
706 if spec['type'] in ('static_library', 'loadable_module', 'shared_library', 718 if type in ('static_library', 'loadable_module', 'shared_library',
707 'executable'): 719 'executable'):
708 return '%s%s%s' % (prefix, target, extension) 720 return '%s%s%s' % (prefix, target, extension)
709 elif spec['type'] == 'none': 721 elif type == 'none':
710 return '%s.stamp' % target 722 return '%s.stamp' % target
711 else: 723 else:
712 raise 'Unhandled output type', spec['type'] 724 raise 'Unhandled output type', type
713 725
714 def ComputeOutput(self, spec): 726 def ComputeOutput(self, spec, type=None):
715 """Compute the path for the final output of the spec.""" 727 """Compute the path for the final output of the spec."""
728 assert not self.is_mac_bundle or type
716 729
717 assert not self.is_mac_bundle 730 if not type:
731 type = spec['type']
718 732
719 if self.flavor == 'mac' and spec['type'] in ( 733 if self.flavor == 'mac' and type in (
720 'static_library', 'executable', 'shared_library', 'loadable_module'): 734 'static_library', 'executable', 'shared_library', 'loadable_module'):
721 filename = self.xcode_settings.GetExecutablePath() 735 filename = self.xcode_settings.GetExecutablePath()
722 else: 736 else:
723 filename = self.ComputeOutputFileName(spec) 737 filename = self.ComputeOutputFileName(spec, type)
724 738
725 if 'product_dir' in spec: 739 if 'product_dir' in spec:
726 path = os.path.join(spec['product_dir'], filename) 740 path = os.path.join(spec['product_dir'], filename)
727 return self.ExpandSpecial(path) 741 return self.ExpandSpecial(path)
728 742
729 # Some products go into the output root, libraries go into shared library 743 # Some products go into the output root, libraries go into shared library
730 # dir, and everything else goes into the normal place. 744 # dir, and everything else goes into the normal place.
731 type_in_output_root = ['executable', 'loadable_module'] 745 type_in_output_root = ['executable', 'loadable_module']
732 if self.flavor == 'mac' and self.toolset == 'target': 746 if self.flavor == 'mac' and self.toolset == 'target':
733 type_in_output_root += ['shared_library', 'static_library'] 747 type_in_output_root += ['shared_library', 'static_library']
734 748
735 if spec['type'] in type_in_output_root: 749 if type in type_in_output_root:
736 return filename 750 return filename
737 elif spec['type'] == 'shared_library': 751 elif type == 'shared_library':
738 libdir = 'lib' 752 libdir = 'lib'
739 if self.toolset != 'target': 753 if self.toolset != 'target':
740 libdir = 'lib/%s' % self.toolset 754 libdir = 'lib/%s' % self.toolset
741 return os.path.join(libdir, filename) 755 return os.path.join(libdir, filename)
742 else: 756 else:
743 return self.GypPathToUniqueOutput(filename, qualified=False) 757 return self.GypPathToUniqueOutput(filename, qualified=False)
744 758
745 def WriteVariableList(self, var, values): 759 def WriteVariableList(self, var, values):
746 if values is None: 760 if values is None:
747 values = [] 761 values = []
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after
994 # For bundles, the binary in the bundle is the right answer. 1008 # For bundles, the binary in the bundle is the right answer.
995 target_outputs[qualified_target] = ( 1009 target_outputs[qualified_target] = (
996 output_binary, compile_depends, linkable) 1010 output_binary, compile_depends, linkable)
997 1011
998 # But for all_outputs, the bundle is the interesting bit. 1012 # But for all_outputs, the bundle is the interesting bit.
999 if qualified_target in all_targets: 1013 if qualified_target in all_targets:
1000 all_outputs.add(output) 1014 all_outputs.add(output)
1001 1015
1002 if all_outputs: 1016 if all_outputs:
1003 master_ninja.build('all', 'phony', list(all_outputs)) 1017 master_ninja.build('all', 'phony', list(all_outputs))
OLDNEW
« no previous file with comments | « no previous file | test/mac/gyptest-sourceless-module.gyp » ('j') | test/mac/gyptest-sourceless-module.gyp » ('J')

Powered by Google App Engine
This is Rietveld 408576698