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

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

Powered by Google App Engine
This is Rietveld 408576698