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

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

Issue 10368006: Remove the hack to concat .d files into a single deps file. (Closed) Base URL: http://gyp.googlecode.com/svn/trunk/
Patch Set: Created 8 years, 7 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/make/gyptest-dependencies.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 # Notes: 5 # Notes:
6 # 6 #
7 # This is all roughly based on the Makefile system used by the Linux 7 # This is all roughly based on the Makefile system used by the Linux
8 # kernel, but is a non-recursive make -- we put the entire dependency 8 # kernel, but is a non-recursive make -- we put the entire dependency
9 # graph in front of make and let it figure it out. 9 # graph in front of make and let it figure it out.
10 # 10 #
(...skipping 420 matching lines...) Expand 10 before | Expand all | Expand 10 after
431 $(call do_postbuilds) 431 $(call do_postbuilds)
432 ) 432 )
433 ) 433 )
434 endef 434 endef
435 435
436 # Declare the "%(default_target)s" target first so it is the default, 436 # Declare the "%(default_target)s" target first so it is the default,
437 # even though we don't have the deps yet. 437 # even though we don't have the deps yet.
438 .PHONY: %(default_target)s 438 .PHONY: %(default_target)s
439 %(default_target)s: 439 %(default_target)s:
440 440
441 # make looks for ways to re-generate included makefiles, but in our case, we
442 # don't have a direct way. Explicitly telling make that it has nothing to do
443 # for them makes it go faster.
444 %%.d: ;
445
441 # Use FORCE_DO_CMD to force a target to run. Should be coupled with 446 # Use FORCE_DO_CMD to force a target to run. Should be coupled with
442 # do_cmd. 447 # do_cmd.
443 .PHONY: FORCE_DO_CMD 448 .PHONY: FORCE_DO_CMD
444 FORCE_DO_CMD: 449 FORCE_DO_CMD:
445 450
446 """) 451 """)
447 452
448 SHARED_HEADER_MAC_COMMANDS = """ 453 SHARED_HEADER_MAC_COMMANDS = """
449 quiet_cmd_objc = CXX($(TOOLSET)) $@ 454 quiet_cmd_objc = CXX($(TOOLSET)) $@
450 cmd_objc = $(CC.$(TOOLSET)) $(GYP_OBJCFLAGS) $(DEPFLAGS) -c -o $@ $< 455 cmd_objc = $(CC.$(TOOLSET)) $(GYP_OBJCFLAGS) $(DEPFLAGS) -c -o $@ $<
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
516 521
517 SHARED_FOOTER = """\ 522 SHARED_FOOTER = """\
518 # "all" is a concatenation of the "all" targets from all the included 523 # "all" is a concatenation of the "all" targets from all the included
519 # sub-makefiles. This is just here to clarify. 524 # sub-makefiles. This is just here to clarify.
520 all: 525 all:
521 526
522 # Add in dependency-tracking rules. $(all_deps) is the list of every single 527 # Add in dependency-tracking rules. $(all_deps) is the list of every single
523 # target in our tree. Only consider the ones with .d (dependency) info: 528 # target in our tree. Only consider the ones with .d (dependency) info:
524 d_files := $(wildcard $(foreach f,$(all_deps),$(depsdir)/$(f).d)) 529 d_files := $(wildcard $(foreach f,$(all_deps),$(depsdir)/$(f).d))
525 ifneq ($(d_files),) 530 ifneq ($(d_files),)
526 # Rather than include each individual .d file, concatenate them into a 531 include $(d_files)
527 # single file which make is able to load faster. We split this into
528 # commands that take 1000 files at a time to avoid overflowing the
529 # command line.
530 $(shell cat $(wordlist 1,1000,$(d_files)) > $(depsdir)/all.deps)
531 %(generate_all_deps)s
532 # make looks for ways to re-generate included makefiles, but in our case, we
533 # don't have a direct way. Explicitly telling make that it has nothing to do
534 # for them makes it go faster.
535 $(depsdir)/all.deps: ;
536
537 include $(depsdir)/all.deps
538 endif 532 endif
539 """ 533 """
540 534
541 header = """\ 535 header = """\
542 # This file is generated by gyp; do not edit. 536 # This file is generated by gyp; do not edit.
543 537
544 """ 538 """
545 539
546 # Maps every compilable file extension to the do_cmd that compiles it. 540 # Maps every compilable file extension to the do_cmd that compiles it.
547 COMPILABLE_EXTENSIONS = { 541 COMPILABLE_EXTENSIONS = {
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
646 640
647 class MakefileWriter: 641 class MakefileWriter:
648 """MakefileWriter packages up the writing of one target-specific foobar.mk. 642 """MakefileWriter packages up the writing of one target-specific foobar.mk.
649 643
650 Its only real entry point is Write(), and is mostly used for namespacing. 644 Its only real entry point is Write(), and is mostly used for namespacing.
651 """ 645 """
652 646
653 def __init__(self, generator_flags, flavor): 647 def __init__(self, generator_flags, flavor):
654 self.generator_flags = generator_flags 648 self.generator_flags = generator_flags
655 self.flavor = flavor 649 self.flavor = flavor
656 # Keep track of the total number of outputs for this makefile.
657 self._num_outputs = 0
658 650
659 self.suffix_rules_srcdir = {} 651 self.suffix_rules_srcdir = {}
660 self.suffix_rules_objdir1 = {} 652 self.suffix_rules_objdir1 = {}
661 self.suffix_rules_objdir2 = {} 653 self.suffix_rules_objdir2 = {}
662 654
663 # Generate suffix rules for all compilable extensions. 655 # Generate suffix rules for all compilable extensions.
664 for ext in COMPILABLE_EXTENSIONS.keys(): 656 for ext in COMPILABLE_EXTENSIONS.keys():
665 # Suffix rules for source folder. 657 # Suffix rules for source folder.
666 self.suffix_rules_srcdir.update({ext: ("""\ 658 self.suffix_rules_srcdir.update({ext: ("""\
667 $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(srcdir)/%%%s FORCE_DO_CMD 659 $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(srcdir)/%%%s FORCE_DO_CMD
668 @$(call do_cmd,%s,1) 660 @$(call do_cmd,%s,1)
669 """ % (ext, COMPILABLE_EXTENSIONS[ext]))}) 661 """ % (ext, COMPILABLE_EXTENSIONS[ext]))})
670 662
671 # Suffix rules for generated source files. 663 # Suffix rules for generated source files.
672 self.suffix_rules_objdir1.update({ext: ("""\ 664 self.suffix_rules_objdir1.update({ext: ("""\
673 $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj).$(TOOLSET)/%%%s FORCE_DO_CMD 665 $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj).$(TOOLSET)/%%%s FORCE_DO_CMD
674 @$(call do_cmd,%s,1) 666 @$(call do_cmd,%s,1)
675 """ % (ext, COMPILABLE_EXTENSIONS[ext]))}) 667 """ % (ext, COMPILABLE_EXTENSIONS[ext]))})
676 self.suffix_rules_objdir2.update({ext: ("""\ 668 self.suffix_rules_objdir2.update({ext: ("""\
677 $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD 669 $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD
678 @$(call do_cmd,%s,1) 670 @$(call do_cmd,%s,1)
679 """ % (ext, COMPILABLE_EXTENSIONS[ext]))}) 671 """ % (ext, COMPILABLE_EXTENSIONS[ext]))})
680 672
681 673
682 def NumOutputs(self):
683 return self._num_outputs
684
685
686 def Write(self, qualified_target, base_path, output_filename, spec, configs, 674 def Write(self, qualified_target, base_path, output_filename, spec, configs,
687 part_of_all): 675 part_of_all):
688 """The main entry point: writes a .mk file for a single target. 676 """The main entry point: writes a .mk file for a single target.
689 677
690 Arguments: 678 Arguments:
691 qualified_target: target we're generating 679 qualified_target: target we're generating
692 base_path: path relative to source root we're building in, used to resolve 680 base_path: path relative to source root we're building in, used to resolve
693 target-relative paths 681 target-relative paths
694 output_filename: output .mk file name to write 682 output_filename: output .mk file name to write
695 spec, configs: gyp info 683 spec, configs: gyp info
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after
988 # Only write the 'obj' and 'builddir' rules for the "primary" output 976 # Only write the 'obj' and 'builddir' rules for the "primary" output
989 # (:1); it's superfluous for the "extra outputs", and this avoids 977 # (:1); it's superfluous for the "extra outputs", and this avoids
990 # accidentally writing duplicate dummy rules for those outputs. 978 # accidentally writing duplicate dummy rules for those outputs.
991 self.WriteLn('%s: obj := $(abs_obj)' % outputs[0]) 979 self.WriteLn('%s: obj := $(abs_obj)' % outputs[0])
992 self.WriteLn('%s: builddir := $(abs_builddir)' % outputs[0]) 980 self.WriteLn('%s: builddir := $(abs_builddir)' % outputs[0])
993 self.WriteMakeRule(outputs, inputs + ['FORCE_DO_CMD'], actions) 981 self.WriteMakeRule(outputs, inputs + ['FORCE_DO_CMD'], actions)
994 for output in outputs: 982 for output in outputs:
995 assert ' ' not in output, ( 983 assert ' ' not in output, (
996 "Spaces in rule filenames not yet supported (%s)" % output) 984 "Spaces in rule filenames not yet supported (%s)" % output)
997 self.WriteLn('all_deps += %s' % ' '.join(outputs)) 985 self.WriteLn('all_deps += %s' % ' '.join(outputs))
998 self._num_outputs += len(outputs)
999 986
1000 action = [self.ExpandInputRoot(ac, rule_source_root, 987 action = [self.ExpandInputRoot(ac, rule_source_root,
1001 rule_source_dirname) 988 rule_source_dirname)
1002 for ac in rule['action']] 989 for ac in rule['action']]
1003 mkdirs = '' 990 mkdirs = ''
1004 if len(dirs) > 0: 991 if len(dirs) > 0:
1005 mkdirs = 'mkdir -p %s; ' % ' '.join(dirs) 992 mkdirs = 'mkdir -p %s; ' % ' '.join(dirs)
1006 cd_action = 'cd %s; ' % Sourceify(self.path or '.') 993 cd_action = 'cd %s; ' % Sourceify(self.path or '.')
1007 994
1008 # action, cd_action, and mkdirs get written to a toplevel variable 995 # action, cd_action, and mkdirs get written to a toplevel variable
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
1174 compilable = filter(Compilable, sources) 1161 compilable = filter(Compilable, sources)
1175 objs = map(self.Objectify, map(self.Absolutify, map(Target, compilable))) 1162 objs = map(self.Objectify, map(self.Absolutify, map(Target, compilable)))
1176 self.WriteList(objs, 'OBJS') 1163 self.WriteList(objs, 'OBJS')
1177 1164
1178 for obj in objs: 1165 for obj in objs:
1179 assert ' ' not in obj, ( 1166 assert ' ' not in obj, (
1180 "Spaces in object filenames not supported (%s)" % obj) 1167 "Spaces in object filenames not supported (%s)" % obj)
1181 self.WriteLn('# Add to the list of files we specially track ' 1168 self.WriteLn('# Add to the list of files we specially track '
1182 'dependencies for.') 1169 'dependencies for.')
1183 self.WriteLn('all_deps += $(OBJS)') 1170 self.WriteLn('all_deps += $(OBJS)')
1184 self._num_outputs += len(objs)
1185 self.WriteLn() 1171 self.WriteLn()
1186 1172
1187 # Make sure our dependencies are built first. 1173 # Make sure our dependencies are built first.
1188 if deps: 1174 if deps:
1189 self.WriteMakeRule(['$(OBJS)'], deps, 1175 self.WriteMakeRule(['$(OBJS)'], deps,
1190 comment = 'Make sure our dependencies are built ' 1176 comment = 'Make sure our dependencies are built '
1191 'before any of us.', 1177 'before any of us.',
1192 order_only = True) 1178 order_only = True)
1193 1179
1194 # Make sure the actions and rules run first. 1180 # Make sure the actions and rules run first.
(...skipping 436 matching lines...) Expand 10 before | Expand all | Expand 10 after
1631 self.WriteMakeRule(outputs, inputs, 1617 self.WriteMakeRule(outputs, inputs,
1632 actions = ['$(call do_cmd,%s%s)' % (command, suffix)], 1618 actions = ['$(call do_cmd,%s%s)' % (command, suffix)],
1633 comment = comment, 1619 comment = comment,
1634 force = True) 1620 force = True)
1635 # Add our outputs to the list of targets we read depfiles from. 1621 # Add our outputs to the list of targets we read depfiles from.
1636 # all_deps is only used for deps file reading, and for deps files we replace 1622 # all_deps is only used for deps file reading, and for deps files we replace
1637 # spaces with ? because escaping doesn't work with make's $(sort) and 1623 # spaces with ? because escaping doesn't work with make's $(sort) and
1638 # other functions. 1624 # other functions.
1639 outputs = [QuoteSpaces(o, SPACE_REPLACEMENT) for o in outputs] 1625 outputs = [QuoteSpaces(o, SPACE_REPLACEMENT) for o in outputs]
1640 self.WriteLn('all_deps += %s' % ' '.join(outputs)) 1626 self.WriteLn('all_deps += %s' % ' '.join(outputs))
1641 self._num_outputs += len(outputs)
1642 1627
1643 1628
1644 def WriteMakeRule(self, outputs, inputs, actions=None, comment=None, 1629 def WriteMakeRule(self, outputs, inputs, actions=None, comment=None,
1645 order_only=False, force=False, phony=False, 1630 order_only=False, force=False, phony=False,
1646 multiple_output_trick=True): 1631 multiple_output_trick=True):
1647 """Write a Makefile rule, with some extra tricks. 1632 """Write a Makefile rule, with some extra tricks.
1648 1633
1649 outputs: a list of outputs for the rule (note: this is not directly 1634 outputs: a list of outputs for the rule (note: this is not directly
1650 supported by make; see comments below) 1635 supported by make; see comments below)
1651 inputs: a list of inputs for the rule 1636 inputs: a list of inputs for the rule
(...skipping 402 matching lines...) Expand 10 before | Expand all | Expand 10 after
2054 # Put build-time support tools next to the root Makefile. 2039 # Put build-time support tools next to the root Makefile.
2055 dest_path = os.path.dirname(makefile_path) 2040 dest_path = os.path.dirname(makefile_path)
2056 gyp.common.CopyTool(flavor, dest_path) 2041 gyp.common.CopyTool(flavor, dest_path)
2057 2042
2058 # Find the list of targets that derive from the gyp file(s) being built. 2043 # Find the list of targets that derive from the gyp file(s) being built.
2059 needed_targets = set() 2044 needed_targets = set()
2060 for build_file in params['build_files']: 2045 for build_file in params['build_files']:
2061 for target in gyp.common.AllTargets(target_list, target_dicts, build_file): 2046 for target in gyp.common.AllTargets(target_list, target_dicts, build_file):
2062 needed_targets.add(target) 2047 needed_targets.add(target)
2063 2048
2064 num_outputs = 0
2065 build_files = set() 2049 build_files = set()
2066 include_list = set() 2050 include_list = set()
2067 for qualified_target in target_list: 2051 for qualified_target in target_list:
2068 build_file, target, toolset = gyp.common.ParseQualifiedTarget( 2052 build_file, target, toolset = gyp.common.ParseQualifiedTarget(
2069 qualified_target) 2053 qualified_target)
2070 2054
2071 this_make_global_settings = data[build_file].get('make_global_settings', {}) 2055 this_make_global_settings = data[build_file].get('make_global_settings', {})
2072 assert make_global_settings_dict == this_make_global_settings, ( 2056 assert make_global_settings_dict == this_make_global_settings, (
2073 "make_global_settings needs to be the same for all targets.") 2057 "make_global_settings needs to be the same for all targets.")
2074 2058
(...skipping 20 matching lines...) Expand all
2095 2079
2096 spec = target_dicts[qualified_target] 2080 spec = target_dicts[qualified_target]
2097 configs = spec['configurations'] 2081 configs = spec['configurations']
2098 2082
2099 if flavor == 'mac': 2083 if flavor == 'mac':
2100 gyp.xcode_emulation.MergeGlobalXcodeSettingsToSpec(data[build_file], spec) 2084 gyp.xcode_emulation.MergeGlobalXcodeSettingsToSpec(data[build_file], spec)
2101 2085
2102 writer = MakefileWriter(generator_flags, flavor) 2086 writer = MakefileWriter(generator_flags, flavor)
2103 writer.Write(qualified_target, base_path, output_file, spec, configs, 2087 writer.Write(qualified_target, base_path, output_file, spec, configs,
2104 part_of_all=qualified_target in needed_targets) 2088 part_of_all=qualified_target in needed_targets)
2105 num_outputs += writer.NumOutputs()
2106 2089
2107 # Our root_makefile lives at the source root. Compute the relative path 2090 # Our root_makefile lives at the source root. Compute the relative path
2108 # from there to the output_file for including. 2091 # from there to the output_file for including.
2109 mkfile_rel_path = gyp.common.RelativePath(output_file, 2092 mkfile_rel_path = gyp.common.RelativePath(output_file,
2110 os.path.dirname(makefile_path)) 2093 os.path.dirname(makefile_path))
2111 include_list.add(mkfile_rel_path) 2094 include_list.add(mkfile_rel_path)
2112 2095
2113 # Write out per-gyp (sub-project) Makefiles. 2096 # Write out per-gyp (sub-project) Makefiles.
2114 depth_rel_path = gyp.common.RelativePath(options.depth, os.getcwd()) 2097 depth_rel_path = gyp.common.RelativePath(options.depth, os.getcwd())
2115 for build_file in build_files: 2098 for build_file in build_files:
(...skipping 26 matching lines...) Expand all
2142 "ifeq ($(strip $(foreach prefix,$(NO_LOAD),\\\n" 2125 "ifeq ($(strip $(foreach prefix,$(NO_LOAD),\\\n"
2143 " $(findstring $(join ^,$(prefix)),\\\n" 2126 " $(findstring $(join ^,$(prefix)),\\\n"
2144 " $(join ^," + include_file + ")))),)\n") 2127 " $(join ^," + include_file + ")))),)\n")
2145 root_makefile.write(" include " + include_file + "\n") 2128 root_makefile.write(" include " + include_file + "\n")
2146 root_makefile.write("endif\n") 2129 root_makefile.write("endif\n")
2147 root_makefile.write('\n') 2130 root_makefile.write('\n')
2148 2131
2149 if generator_flags.get('auto_regeneration', True): 2132 if generator_flags.get('auto_regeneration', True):
2150 WriteAutoRegenerationRule(params, root_makefile, makefile_name, build_files) 2133 WriteAutoRegenerationRule(params, root_makefile, makefile_name, build_files)
2151 2134
2152 # Write the rule to load dependencies. We batch 1000 files at a time to 2135 root_makefile.write(SHARED_FOOTER)
2153 # avoid overflowing the command line.
2154 all_deps = ""
2155 for i in range(1001, num_outputs, 1000):
2156 all_deps += ("""
2157 ifneq ($(word %(start)d,$(d_files)),)
2158 $(shell cat $(wordlist %(start)d,%(end)d,$(d_files)) >> $(depsdir)/all.deps)
2159 endif""" % { 'start': i, 'end': i + 999 })
2160
2161 # Add a check to make sure we tried to process all the .d files.
2162 all_deps += """
2163 ifneq ($(word %(last)d,$(d_files)),)
2164 $(error Found unprocessed dependency files (gyp didn't generate enough rules !))
2165 endif
2166 """ % { 'last': ((num_outputs / 1000) + 1) * 1000 + 1 }
2167
2168 root_makefile.write(SHARED_FOOTER % { 'generate_all_deps': all_deps })
2169 2136
2170 root_makefile.close() 2137 root_makefile.close()
OLDNEW
« no previous file with comments | « no previous file | test/make/gyptest-dependencies.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698