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

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

Issue 271019: Adding cross-compile ability to the make build (Closed) Base URL: http://gyp.googlecode.com/svn/trunk/
Patch Set: '' Created 11 years, 2 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 | « pylib/gyp/generator/gypd.py ('k') | pylib/gyp/generator/msvs.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 #!/usr/bin/python 1 #!/usr/bin/python
2 2
3 # Notes: 3 # Notes:
4 # 4 #
5 # This is all roughly based on the Makefile system used by the Linux 5 # This is all roughly based on the Makefile system used by the Linux
6 # kernel, but is a non-recursive make -- we put the entire dependency 6 # kernel, but is a non-recursive make -- we put the entire dependency
7 # graph in front of make and let it figure it out. 7 # graph in front of make and let it figure it out.
8 # 8 #
9 # The code below generates a separate .mk file for each target, but 9 # The code below generates a separate .mk file for each target, but
10 # all are sourced by the top-level Makefile. This means that all 10 # all are sourced by the top-level Makefile. This means that all
(...skipping 17 matching lines...) Expand all
28 import pprint 28 import pprint
29 29
30 generator_default_variables = { 30 generator_default_variables = {
31 'EXECUTABLE_PREFIX': '', 31 'EXECUTABLE_PREFIX': '',
32 'EXECUTABLE_SUFFIX': '', 32 'EXECUTABLE_SUFFIX': '',
33 'OS': 'linux', 33 'OS': 'linux',
34 'STATIC_LIB_PREFIX': 'lib', 34 'STATIC_LIB_PREFIX': 'lib',
35 'SHARED_LIB_PREFIX': 'lib', 35 'SHARED_LIB_PREFIX': 'lib',
36 'STATIC_LIB_SUFFIX': '.a', 36 'STATIC_LIB_SUFFIX': '.a',
37 'SHARED_LIB_SUFFIX': '.so', 37 'SHARED_LIB_SUFFIX': '.so',
38 'INTERMEDIATE_DIR': '$(obj)/geni', 38 'INTERMEDIATE_DIR': '$(obj).$(TOOLSET)/geni',
39 'SHARED_INTERMEDIATE_DIR': '$(obj)/gen', 39 'SHARED_INTERMEDIATE_DIR': '$(obj)/gen',
40 'PRODUCT_DIR': '$(builddir)', 40 'PRODUCT_DIR': '$(builddir)',
41 'LIB_DIR': '$(obj)', 41 'LIB_DIR': '$(obj)',
42 'RULE_INPUT_ROOT': '%(INPUT_ROOT)s', # This gets expanded by Python. 42 'RULE_INPUT_ROOT': '%(INPUT_ROOT)s', # This gets expanded by Python.
43 'RULE_INPUT_PATH': '$(abspath $<)', 43 'RULE_INPUT_PATH': '$(abspath $<)',
44 44
45 # These appear unused -- ??? 45 # These appear unused -- ???
46 'RULE_INPUT_EXT': 'XXXEXT$(suffix $^)', 46 'RULE_INPUT_EXT': 'XXXEXT$(suffix $^)',
47 'RULE_INPUT_NAME': 'XXXNAME$(notdir $(basename $^)0', 47 'RULE_INPUT_NAME': 'XXXNAME$(notdir $(basename $^)0',
48 'CONFIGURATION_NAME': '$(BUILDTYPE)', 48 'CONFIGURATION_NAME': '$(BUILDTYPE)',
49 } 49 }
50 50
51 # Make supports multiple toolsets
52 generator_supports_multiple_toolsets = True
51 53
52 def ensure_directory_exists(path): 54 def ensure_directory_exists(path):
53 dir = os.path.dirname(path) 55 dir = os.path.dirname(path)
54 if dir and not os.path.exists(dir): 56 if dir and not os.path.exists(dir):
55 os.makedirs(dir) 57 os.makedirs(dir)
56 58
57 # Header of toplevel Makefile. 59 # Header of toplevel Makefile.
58 # This should go into the build tree, but it's easier to keep it here for now. 60 # This should go into the build tree, but it's easier to keep it here for now.
59 SHARED_HEADER = ("""\ 61 SHARED_HEADER = ("""\
60 # We borrow heavily from the kernel build setup, though we are simpler since 62 # We borrow heavily from the kernel build setup, though we are simpler since
(...skipping 23 matching lines...) Expand all
84 # Object output directory. 86 # Object output directory.
85 obj := $(builddir)/obj 87 obj := $(builddir)/obj
86 abs_obj := $(abspath $(obj)) 88 abs_obj := $(abspath $(obj))
87 89
88 # We build up a list of all targets so we can slurp in the generated 90 # We build up a list of all targets so we can slurp in the generated
89 # dependency rule Makefiles in one pass. 91 # dependency rule Makefiles in one pass.
90 all_targets := 92 all_targets :=
91 93
92 # C++ apps need to be linked with g++. Not sure what's appropriate. 94 # C++ apps need to be linked with g++. Not sure what's appropriate.
93 LINK := $(CXX) 95 LINK := $(CXX)
94 RANLIB ?= ranlib 96
97 CC.target ?= $(CC)
98 CXX.target ?= $(CXX)
99 LINK.target ?= $(LINK)
100 AR.target ?= $(AR)
101 RANLIB.target ?= ranlib
102
103 CC.host ?= gcc
104 CXX.host ?= g++
105 LINK.host ?= g++
106 AR.host ?= ar
107 RANLIB.host ?= ranlib
95 108
96 # Flags to make gcc output dependency info. Note that you need to be 109 # Flags to make gcc output dependency info. Note that you need to be
97 # careful here to use the flags that ccache and distcc can understand. 110 # careful here to use the flags that ccache and distcc can understand.
98 # We write to a temporary dep file first and then rename at the end 111 # We write to a temporary dep file first and then rename at the end
99 # so we can't end up with a broken dep file. 112 # so we can't end up with a broken dep file.
100 depfile = $@.d 113 depfile = $@.d
101 DEPFLAGS = -MMD -MF $(depfile).tmp 114 DEPFLAGS = -MMD -MF $(depfile).tmp
102 115
103 # We have to fixup the deps output in a few ways. 116 # We have to fixup the deps output in a few ways.
104 # First, the file output should to mention the proper .o file. 117 # First, the file output should to mention the proper .o file.
(...skipping 19 matching lines...) Expand all
124 -e "/./s|$$|:|" $(depfile).tmp >> $(depfile).tmp 137 -e "/./s|$$|:|" $(depfile).tmp >> $(depfile).tmp
125 cat $(depfile).tmp >> $(depfile) 138 cat $(depfile).tmp >> $(depfile)
126 rm -f $(depfile).tmp 139 rm -f $(depfile).tmp
127 endef 140 endef
128 """ 141 """
129 """ 142 """
130 # Command definitions: 143 # Command definitions:
131 # - cmd_foo is the actual command to run; 144 # - cmd_foo is the actual command to run;
132 # - quiet_cmd_foo is the brief-output summary of the command. 145 # - quiet_cmd_foo is the brief-output summary of the command.
133 146
134 quiet_cmd_cc = CC $@ 147 quiet_cmd_cc = CC($(TOOLSET)) $@
135 cmd_cc = $(CC) $(CFLAGS) $(DEPFLAGS) -c -o $@ $< 148 cmd_cc = $(CC.$(TOOLSET)) $(CFLAGS) $(DEPFLAGS) -c -o $@ $<
136 149
137 quiet_cmd_cxx = CXX $@ 150 quiet_cmd_cxx = CXX($(TOOLSET)) $@
138 cmd_cxx = $(CXX) $(CXXFLAGS) $(DEPFLAGS) -c -o $@ $< 151 cmd_cxx = $(CXX.$(TOOLSET)) $(CXXFLAGS) $(DEPFLAGS) -c -o $@ $<
139 152
140 quiet_cmd_alink = AR+RANLIB $@ 153 quiet_cmd_alink = AR+RANLIB($(TOOLSET)) $@
141 cmd_alink = rm -f $@ && $(AR) rc $@ $(filter %.o,$^) && $(RANLIB) $@ 154 cmd_alink = rm -f $@ && $(AR.$(TOOLSET)) rc $@ $(filter %.o,$^) && $(RANLIB.$(TO OLSET)) $@
142 155
143 quiet_cmd_touch = TOUCH $@ 156 quiet_cmd_touch = TOUCH $@
144 cmd_touch = touch $@ 157 cmd_touch = touch $@
145 158
146 quiet_cmd_copy = COPY $@ 159 quiet_cmd_copy = COPY $@
147 cmd_copy = ln -f $< $@ || cp -af $< $@ 160 cmd_copy = ln -f $< $@ || cp -af $< $@
148 161
149 # Due to circular dependencies between libraries :(, we wrap the 162 # Due to circular dependencies between libraries :(, we wrap the
150 # special "figure out circular dependencies" flags around the entire 163 # special "figure out circular dependencies" flags around the entire
151 # input list during linking. 164 # input list during linking.
152 quiet_cmd_link = LINK $@ 165 quiet_cmd_link = LINK($(TOOLSET)) $@
153 cmd_link = $(LINK) $(LDFLAGS) -o $@ -Wl,--start-group $(filter-out FORCE_DO_CMD, $^) -Wl,--end-group $(LIBS) 166 cmd_link = $(LINK.$(TOOLSET)) $(LDFLAGS) -o $@ -Wl,--start-group $(filter-out FO RCE_DO_CMD, $^) -Wl,--end-group $(LIBS)
154 167
155 # Shared-object link (for generating .so). 168 # Shared-object link (for generating .so).
156 # Set SONAME to the library filename so our binaries don't reference the local, 169 # Set SONAME to the library filename so our binaries don't reference the local,
157 # absolute paths used on the link command-line. 170 # absolute paths used on the link command-line.
158 # TODO: perhaps this can share with the LINK command above? 171 # TODO: perhaps this can share with the LINK command above?
159 quiet_cmd_solink = SOLINK $@ 172 quiet_cmd_solink = SOLINK($(TOOLSET)) $@
160 cmd_solink = $(LINK) -shared $(LDFLAGS) -Wl,-soname=$(@F) -o $@ -Wl,--start-grou p $(filter-out FORCE_DO_CMD, $^) -Wl,--end-group $(LIBS) 173 cmd_solink = $(LINK.$(TOOLSET)) -shared $(LDFLAGS) -Wl,-soname=$(@F) -o $@ -Wl,- -start-group $(filter-out FORCE_DO_CMD, $^) -Wl,--end-group $(LIBS)
161 """ 174 """
162 r""" 175 r"""
163 # Define an escape_quotes function to escape single quotes. 176 # Define an escape_quotes function to escape single quotes.
164 # This allows us to handle quotes properly as long as we always use 177 # This allows us to handle quotes properly as long as we always use
165 # use single quotes and escape_quotes. 178 # use single quotes and escape_quotes.
166 escape_quotes = $(subst ','\'',$(1)) 179 escape_quotes = $(subst ','\'',$(1))
167 # This comment is here just to include a ' to unconfuse syntax highlighting. 180 # This comment is here just to include a ' to unconfuse syntax highlighting.
168 # Define an escape_vars function to escape '$' variable syntax. 181 # Define an escape_vars function to escape '$' variable syntax.
169 # This allows us to read/write command lines wth shell variables (e.g. 182 # This allows us to read/write command lines wth shell variables (e.g.
170 # $LD_LIBRARY_PATH), without triggering make substitution. 183 # $LD_LIBRARY_PATH), without triggering make substitution.
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
207 # Declare "all" target first so it is the default, even though we don't have the 220 # Declare "all" target first so it is the default, even though we don't have the
208 # deps yet. 221 # deps yet.
209 .PHONY: all 222 .PHONY: all
210 all: 223 all:
211 224
212 # Use FORCE_DO_CMD to force a target to run. Should be coupled with 225 # Use FORCE_DO_CMD to force a target to run. Should be coupled with
213 # do_cmd. 226 # do_cmd.
214 .PHONY: FORCE_DO_CMD 227 .PHONY: FORCE_DO_CMD
215 FORCE_DO_CMD: 228 FORCE_DO_CMD:
216 229
230 """)
231
232 SHARED_HEADER_SUFFIX_RULES = ("""\
217 # Suffix rules, putting all outputs into $(obj). 233 # Suffix rules, putting all outputs into $(obj).
218 $(obj)/%.o: $(srcdir)/%.c FORCE_DO_CMD 234 $(obj).$(TOOLSET)/%.o: $(srcdir)/%.c FORCE_DO_CMD
219 @$(call do_cmd,cc,1) 235 @$(call do_cmd,cc,1)
220 236 $(obj).$(TOOLSET)/%.o: $(srcdir)/%.s FORCE_DO_CMD
221 $(obj)/%.o: $(srcdir)/%.s FORCE_DO_CMD
222 @$(call do_cmd,cc) 237 @$(call do_cmd,cc)
223 238 $(obj).$(TOOLSET)/%.o: $(srcdir)/%.S FORCE_DO_CMD
224 $(obj)/%.o: $(srcdir)/%.S FORCE_DO_CMD
225 @$(call do_cmd,cc) 239 @$(call do_cmd,cc)
226 240 $(obj).$(TOOLSET)/%.o: $(srcdir)/%.cpp FORCE_DO_CMD
227 $(obj)/%.o: $(srcdir)/%.cpp FORCE_DO_CMD
228 @$(call do_cmd,cxx,1) 241 @$(call do_cmd,cxx,1)
229 $(obj)/%.o: $(srcdir)/%.cc FORCE_DO_CMD 242 $(obj).$(TOOLSET)/%.o: $(srcdir)/%.cc FORCE_DO_CMD
230 @$(call do_cmd,cxx,1) 243 @$(call do_cmd,cxx,1)
231 $(obj)/%.o: $(srcdir)/%.cxx FORCE_DO_CMD 244 $(obj).$(TOOLSET)/%.o: $(srcdir)/%.cxx FORCE_DO_CMD
232 @$(call do_cmd,cxx,1) 245 @$(call do_cmd,cxx,1)
233 246
234 # Try building from generated source, too. 247 # Try building from generated source, too.
235 $(obj)/%.o: $(obj)/%.c FORCE_DO_CMD 248 $(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.c FORCE_DO_CMD
236 @$(call do_cmd,cc,1) 249 @$(call do_cmd,cc,1)
237 $(obj)/%.o: $(obj)/%.cc FORCE_DO_CMD 250 $(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.cc FORCE_DO_CMD
238 @$(call do_cmd,cxx,1) 251 @$(call do_cmd,cxx,1)
239 $(obj)/%.o: $(obj)/%.cpp FORCE_DO_CMD 252 $(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.cpp FORCE_DO_CMD
253 » @$(call do_cmd,cxx,1)
254
255 $(obj).$(TOOLSET)/%.o: $(obj)/%.c FORCE_DO_CMD
256 » @$(call do_cmd,cc,1)
257 $(obj).$(TOOLSET)/%.o: $(obj)/%.cc FORCE_DO_CMD
258 » @$(call do_cmd,cxx,1)
259 $(obj).$(TOOLSET)/%.o: $(obj)/%.cpp FORCE_DO_CMD
240 @$(call do_cmd,cxx,1) 260 @$(call do_cmd,cxx,1)
241 """) 261 """)
242 262
243 # This gets added to the very beginning of the Makefile. 263 # This gets added to the very beginning of the Makefile.
244 SHARED_HEADER_SRCDIR = ("""\ 264 SHARED_HEADER_SRCDIR = ("""\
245 # The source directory tree. 265 # The source directory tree.
246 srcdir := %s 266 srcdir := %s
247 267
248 """) 268 """)
249 269
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
286 """Translate a compilable filename to its .o target.""" 306 """Translate a compilable filename to its .o target."""
287 return os.path.splitext(filename)[0] + '.o' 307 return os.path.splitext(filename)[0] + '.o'
288 308
289 309
290 def QuoteIfNecessary(string): 310 def QuoteIfNecessary(string):
291 if '"' in string: 311 if '"' in string:
292 string = '"' + string.replace('"', '\\"') + '"' 312 string = '"' + string.replace('"', '\\"') + '"'
293 return string 313 return string
294 314
295 315
296 def Objectify(path):
297 """Convert a path to its output directory form."""
298 if '$(' in path:
299 return path
300 return '$(obj)/' + path
301
302 srcdir_prefix = '' 316 srcdir_prefix = ''
303 def Sourceify(path): 317 def Sourceify(path):
304 """Convert a path to its source directory form.""" 318 """Convert a path to its source directory form."""
305 if '$(' in path: 319 if '$(' in path:
306 return path 320 return path
307 return srcdir_prefix + path 321 return srcdir_prefix + path
308 322
309 323
310 # Map from qualified target to path to output. 324 # Map from qualified target to path to output.
311 target_outputs = {} 325 target_outputs = {}
(...skipping 23 matching lines...) Expand all
335 349
336 ensure_directory_exists(output_filename) 350 ensure_directory_exists(output_filename)
337 351
338 self.fp = open(output_filename, 'w') 352 self.fp = open(output_filename, 'w')
339 353
340 self.fp.write(header) 354 self.fp.write(header)
341 355
342 self.path = base_path 356 self.path = base_path
343 self.target = spec['target_name'] 357 self.target = spec['target_name']
344 self.type = spec['type'] 358 self.type = spec['type']
359 self.toolset = spec['toolset']
345 360
346 deps, link_deps = self.ComputeDeps(spec) 361 deps, link_deps = self.ComputeDeps(spec)
347 362
348 # Some of the generation below can add extra output, sources, or 363 # Some of the generation below can add extra output, sources, or
349 # link dependencies. All of the out params of the functions that 364 # link dependencies. All of the out params of the functions that
350 # follow use names like extra_foo. 365 # follow use names like extra_foo.
351 extra_outputs = [] 366 extra_outputs = []
352 extra_sources = [] 367 extra_sources = []
353 extra_link_deps = [] 368 extra_link_deps = []
354 369
355 self.output = self.ComputeOutput(spec) 370 self.output = self.ComputeOutput(spec)
356 self._INSTALLABLE_TARGETS = ('executable', 'loadable_module', 371 self._INSTALLABLE_TARGETS = ('executable', 'loadable_module',
357 'shared_library') 372 'shared_library')
358 if self.type in self._INSTALLABLE_TARGETS: 373 if self.type in self._INSTALLABLE_TARGETS:
359 self.alias = os.path.basename(self.output) 374 self.alias = os.path.basename(self.output)
360 else: 375 else:
361 self.alias = self.output 376 self.alias = self.output
362 377
378 self.WriteLn("TOOLSET := " + self.toolset)
379
363 # Actions must come first, since they can generate more OBJs for use below. 380 # Actions must come first, since they can generate more OBJs for use below.
364 if 'actions' in spec: 381 if 'actions' in spec:
365 self.WriteActions(spec['actions'], extra_sources, extra_outputs) 382 self.WriteActions(spec['actions'], extra_sources, extra_outputs)
366 383
367 # Rules must be early like actions. 384 # Rules must be early like actions.
368 if 'rules' in spec: 385 if 'rules' in spec:
369 self.WriteRules(spec['rules'], extra_sources, extra_outputs) 386 self.WriteRules(spec['rules'], extra_sources, extra_outputs)
370 387
371 if 'copies' in spec: 388 if 'copies' in spec:
372 self.WriteCopies(spec['copies'], extra_outputs) 389 self.WriteCopies(spec['copies'], extra_outputs)
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
580 self.WriteLn("# Flags passed to only C (and not C++) files."); 597 self.WriteLn("# Flags passed to only C (and not C++) files.");
581 self.WriteList(config.get('cflags_c'), 'CFLAGS_C_%s' % configname) 598 self.WriteList(config.get('cflags_c'), 'CFLAGS_C_%s' % configname)
582 self.WriteLn("# Flags passed to only C++ (and not C) files."); 599 self.WriteLn("# Flags passed to only C++ (and not C) files.");
583 self.WriteList(config.get('cflags_cc'), 'CFLAGS_CC_%s' % configname) 600 self.WriteList(config.get('cflags_cc'), 'CFLAGS_CC_%s' % configname)
584 includes = config.get('include_dirs') 601 includes = config.get('include_dirs')
585 if includes: 602 if includes:
586 includes = map(Sourceify, map(self.Absolutify, includes)) 603 includes = map(Sourceify, map(self.Absolutify, includes))
587 self.WriteList(includes, 'INCS_%s' % configname, prefix='-I') 604 self.WriteList(includes, 'INCS_%s' % configname, prefix='-I')
588 605
589 sources = filter(Compilable, sources) 606 sources = filter(Compilable, sources)
590 objs = map(Objectify, map(self.Absolutify, map(Target, sources))) 607 objs = map(self.Objectify, map(self.Absolutify, map(Target, sources)))
591 self.WriteList(objs, 'OBJS') 608 self.WriteList(objs, 'OBJS')
592 609
593 self.WriteLn('# Add to the list of files we specially track ' 610 self.WriteLn('# Add to the list of files we specially track '
594 'dependencies for.') 611 'dependencies for.')
595 self.WriteLn('all_targets += $(OBJS)') 612 self.WriteLn('all_targets += $(OBJS)')
596 self.WriteLn() 613 self.WriteLn()
597 614
598 # Make sure our dependencies are built first. 615 # Make sure our dependencies are built first.
599 if deps: 616 if deps:
600 self.WriteMakeRule(['$(OBJS)'], deps, 617 self.WriteMakeRule(['$(OBJS)'], deps,
601 comment = 'Make sure our dependencies are built ' 618 comment = 'Make sure our dependencies are built '
602 'before any of us.', 619 'before any of us.',
603 order_only = True) 620 order_only = True)
604 621
605 # Make sure the actions and rules run first. 622 # Make sure the actions and rules run first.
606 # If they generate any extra headers etc., the per-.o file dep tracking 623 # If they generate any extra headers etc., the per-.o file dep tracking
607 # will catch the proper rebuilds, so order only is still ok here. 624 # will catch the proper rebuilds, so order only is still ok here.
608 if extra_outputs: 625 if extra_outputs:
609 self.WriteMakeRule(['$(OBJS)'], extra_outputs, 626 self.WriteMakeRule(['$(OBJS)'], extra_outputs,
610 comment = 'Make sure our actions/rules run ' 627 comment = 'Make sure our actions/rules run '
611 'before any of us.', 628 'before any of us.',
612 order_only = True) 629 order_only = True)
613 630
614 if objs: 631 if objs:
615 extra_link_deps.append('$(OBJS)') 632 extra_link_deps.append('$(OBJS)')
616 self.WriteLn("""\ 633 self.WriteLn("""\
617 # CFLAGS et al overrides must be target-local. 634 # CFLAGS et al overrides must be target-local.
618 # See "Target-specific Variable Values" in the GNU Make manual.""") 635 # See "Target-specific Variable Values" in the GNU Make manual.""")
636 self.WriteLn("$(OBJS): TOOLSET := $(TOOLSET)")
619 self.WriteLn("$(OBJS): CFLAGS := $(CFLAGS_$(BUILDTYPE)) " 637 self.WriteLn("$(OBJS): CFLAGS := $(CFLAGS_$(BUILDTYPE)) "
620 "$(CFLAGS_C_$(BUILDTYPE)) " 638 "$(CFLAGS_C_$(BUILDTYPE)) "
621 "$(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE))") 639 "$(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE))")
622 self.WriteLn("$(OBJS): CXXFLAGS := $(CFLAGS_$(BUILDTYPE)) " 640 self.WriteLn("$(OBJS): CXXFLAGS := $(CFLAGS_$(BUILDTYPE)) "
623 "$(CFLAGS_CC_$(BUILDTYPE)) " 641 "$(CFLAGS_CC_$(BUILDTYPE)) "
624 "$(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE))") 642 "$(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE))")
625 643
626 self.WriteLn() 644 self.WriteLn()
627 645
628 646
(...skipping 12 matching lines...) Expand all
641 elif self.type == 'none': 659 elif self.type == 'none':
642 target = '%s.stamp' % target 660 target = '%s.stamp' % target
643 elif self.type == 'settings': 661 elif self.type == 'settings':
644 return None 662 return None
645 elif self.type == 'executable': 663 elif self.type == 'executable':
646 target = spec.get('product_name', target) 664 target = spec.get('product_name', target)
647 else: 665 else:
648 print ("ERROR: What output file should be generated?", 666 print ("ERROR: What output file should be generated?",
649 "typ", self.type, "target", target) 667 "typ", self.type, "target", target)
650 668
651 path = spec.get('product_dir', os.path.join('$(obj)', self.path)) 669 path = spec.get('product_dir', os.path.join('$(obj).' + self.toolset,
670 self.path))
652 return os.path.join(path, target) 671 return os.path.join(path, target)
653 672
654 673
655 def ComputeDeps(self, spec): 674 def ComputeDeps(self, spec):
656 """Compute the dependencies of a gyp spec. 675 """Compute the dependencies of a gyp spec.
657 676
658 Returns a tuple (deps, link_deps), where each is a list of 677 Returns a tuple (deps, link_deps), where each is a list of
659 filenames that will need to be put in front of make for either 678 filenames that will need to be put in front of make for either
660 building (deps) or linking (link_deps). 679 building (deps) or linking (link_deps).
661 """ 680 """
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
782 phony: if true, the rule does not actually generate the named output, the 801 phony: if true, the rule does not actually generate the named output, the
783 output is just a name to run the rule 802 output is just a name to run the rule
784 """ 803 """
785 if comment: 804 if comment:
786 self.WriteLn('# ' + comment) 805 self.WriteLn('# ' + comment)
787 if phony: 806 if phony:
788 self.WriteLn('.PHONY: ' + ' '.join(outputs)) 807 self.WriteLn('.PHONY: ' + ' '.join(outputs))
789 # TODO(evanm): just make order_only a list of deps instead of these hacks. 808 # TODO(evanm): just make order_only a list of deps instead of these hacks.
790 order_insert = '| ' if order_only else '' 809 order_insert = '| ' if order_only else ''
791 force_append = ' FORCE_DO_CMD' if force else '' 810 force_append = ' FORCE_DO_CMD' if force else ''
811 if actions:
812 self.WriteLn("%s: TOOLSET := $(TOOLSET)" % outputs[0])
792 self.WriteLn('%s: %s%s%s' % (outputs[0], order_insert, ' '.join(inputs), 813 self.WriteLn('%s: %s%s%s' % (outputs[0], order_insert, ' '.join(inputs),
793 force_append)) 814 force_append))
794 if actions: 815 if actions:
795 for action in actions: 816 for action in actions:
796 self.WriteLn('\t%s' % action) 817 self.WriteLn('\t%s' % action)
797 if len(outputs) > 1: 818 if len(outputs) > 1:
798 # If we have more than one output, a rule like 819 # If we have more than one output, a rule like
799 # foo bar: baz 820 # foo bar: baz
800 # that for *each* output we must run the action, potentially 821 # that for *each* output we must run the action, potentially
801 # in parallel. That is not what we're trying to write -- what 822 # in parallel. That is not what we're trying to write -- what
802 # we want is that we run the action once and it generates all 823 # we want is that we run the action once and it generates all
803 # the files. 824 # the files.
804 # http://www.gnu.org/software/hello/manual/automake/Multiple-Outputs.html 825 # http://www.gnu.org/software/hello/manual/automake/Multiple-Outputs.html
805 # discusses this problem and has this solution: 826 # discusses this problem and has this solution:
806 # 1) Write the naive rule that would produce parallel runs of 827 # 1) Write the naive rule that would produce parallel runs of
807 # the action. 828 # the action.
808 # 2) Make the outputs seralized on each other, so we won't start 829 # 2) Make the outputs seralized on each other, so we won't start
809 # a a parallel run until the first run finishes, at which point 830 # a a parallel run until the first run finishes, at which point
810 # we'll have generated all the outputs and we're done. 831 # we'll have generated all the outputs and we're done.
811 self.WriteLn('%s: %s' % (' '.join(outputs[1:]), outputs[0])) 832 self.WriteLn('%s: %s' % (' '.join(outputs[1:]), outputs[0]))
812 self.WriteLn() 833 self.WriteLn()
813 834
814 835
815 def WriteLn(self, text=''): 836 def WriteLn(self, text=''):
816 self.fp.write(text + '\n') 837 self.fp.write(text + '\n')
817 838
818 839
840 def Objectify(self, path):
841 """Convert a path to its output directory form."""
842 if '$(' in path:
843 path = path.replace('$(obj)/', '$(obj).%s/' % self.toolset)
844 return path
845 return '$(obj).%s/%s' % (self.toolset, path)
846
819 def Absolutify(self, path): 847 def Absolutify(self, path):
820 """Convert a subdirectory-relative path into a base-relative path. 848 """Convert a subdirectory-relative path into a base-relative path.
821 Skips over paths that contain variables.""" 849 Skips over paths that contain variables."""
822 if '$(' in path: 850 if '$(' in path:
823 return path 851 return path
824 return os.path.normpath(os.path.join(self.path, path)) 852 return os.path.normpath(os.path.join(self.path, path))
825 853
826 854
827 def FixupArgPath(self, arg): 855 def FixupArgPath(self, arg):
828 if '/' in arg or '.h.' in arg: 856 if '/' in arg or '.h.' in arg:
(...skipping 14 matching lines...) Expand all
843 871
844 def GenerateOutput(target_list, target_dicts, data, params): 872 def GenerateOutput(target_list, target_dicts, data, params):
845 options = params['options'] 873 options = params['options']
846 generator_flags = params.get('generator_flags', {}) 874 generator_flags = params.get('generator_flags', {})
847 builddir_name = generator_flags.get('output_dir', 'out') 875 builddir_name = generator_flags.get('output_dir', 'out')
848 876
849 # TODO: search for the first non-'Default' target. This can go 877 # TODO: search for the first non-'Default' target. This can go
850 # away when we add verification that all targets have the 878 # away when we add verification that all targets have the
851 # necessary configurations. 879 # necessary configurations.
852 default_configuration = None 880 default_configuration = None
881 toolsets = set([target_dicts[target]['toolset'] for target in target_list])
853 for target in target_list: 882 for target in target_list:
854 spec = target_dicts[target] 883 spec = target_dicts[target]
855 if spec['default_configuration'] != 'Default': 884 if spec['default_configuration'] != 'Default':
856 default_configuration = spec['default_configuration'] 885 default_configuration = spec['default_configuration']
857 break 886 break
858 if not default_configuration: 887 if not default_configuration:
859 default_configuration = 'Default' 888 default_configuration = 'Default'
860 889
861 srcdir = '.' 890 srcdir = '.'
862 makefile_name = 'Makefile' + options.suffix 891 makefile_name = 'Makefile' + options.suffix
863 makefile_path = os.path.join(options.depth, makefile_name) 892 makefile_path = os.path.join(options.depth, makefile_name)
864 if options.generator_output: 893 if options.generator_output:
865 global srcdir_prefix 894 global srcdir_prefix
866 makefile_path = os.path.join(options.generator_output, makefile_path) 895 makefile_path = os.path.join(options.generator_output, makefile_path)
867 srcdir = gyp.common.RelativePath('.', options.generator_output) 896 srcdir = gyp.common.RelativePath('.', options.generator_output)
868 srcdir_prefix = '$(srcdir)/' 897 srcdir_prefix = '$(srcdir)/'
869 ensure_directory_exists(makefile_path) 898 ensure_directory_exists(makefile_path)
870 root_makefile = open(makefile_path, 'w') 899 root_makefile = open(makefile_path, 'w')
871 root_makefile.write(SHARED_HEADER_SRCDIR % srcdir) 900 root_makefile.write(SHARED_HEADER_SRCDIR % srcdir)
872 root_makefile.write(SHARED_HEADER_BUILDDIR_NAME % builddir_name) 901 root_makefile.write(SHARED_HEADER_BUILDDIR_NAME % builddir_name)
873 root_makefile.write(SHARED_HEADER.replace('__default_configuration__', 902 root_makefile.write(SHARED_HEADER.replace('__default_configuration__',
874 default_configuration)) 903 default_configuration))
904 for toolset in toolsets:
905 root_makefile.write('TOOLSET := %s\n' % toolset)
906 root_makefile.write(SHARED_HEADER_SUFFIX_RULES)
875 907
876 # Find the list of targets that derive from the gyp file(s) being built. 908 # Find the list of targets that derive from the gyp file(s) being built.
877 needed_targets = set() 909 needed_targets = set()
878 for build_file in params['build_files']: 910 for build_file in params['build_files']:
879 for target in gyp.common.AllTargets(target_list, target_dicts, build_file): 911 for target in gyp.common.AllTargets(target_list, target_dicts, build_file):
880 needed_targets.add(target) 912 needed_targets.add(target)
881 913
882 build_files = set() 914 build_files = set()
883 for qualified_target in target_list: 915 for qualified_target in target_list:
884 # target_list is all the targets defined in all referenced gyp files, so 916 # target_list is all the targets defined in all referenced gyp files, so
885 # weed out the ones that aren't actually needed for this build. We could 917 # weed out the ones that aren't actually needed for this build. We could
886 # generate the .mk even for unneeded targets, as long as we don't 918 # generate the .mk even for unneeded targets, as long as we don't
887 # reference them in the top-level Makefile, but skipping them entirely 919 # reference them in the top-level Makefile, but skipping them entirely
888 # should work too. 920 # should work too.
889 if qualified_target not in needed_targets: 921 if qualified_target not in needed_targets:
890 continue 922 continue
891 build_file, target = gyp.common.BuildFileAndTarget('', qualified_target)[:2] 923 build_file, target, toolset = gyp.common.ParseQualifiedTarget(
924 qualified_target)
892 build_files.add(gyp.common.RelativePath(build_file, options.depth)) 925 build_files.add(gyp.common.RelativePath(build_file, options.depth))
893 included_files = data[build_file]['included_files'] 926 included_files = data[build_file]['included_files']
894 for included_file in included_files: 927 for included_file in included_files:
895 # The included_files entries are relative to the dir of the build file 928 # The included_files entries are relative to the dir of the build file
896 # that included them, so we have to undo that and then make them relative 929 # that included them, so we have to undo that and then make them relative
897 # to the root dir. 930 # to the root dir.
898 build_files.add(gyp.common.RelativePath( 931 build_files.add(gyp.common.RelativePath(
899 gyp.common.UnrelativePath(included_file, build_file), options.depth)) 932 gyp.common.UnrelativePath(included_file, build_file), options.depth))
900 933
901 # Paths in gyp files are relative to the .gyp file, but we want 934 # Paths in gyp files are relative to the .gyp file, but we want
902 # paths relative to the source root for the master makefile. Grab 935 # paths relative to the source root for the master makefile. Grab
903 # the path of the .gyp file as the base to relativize against. 936 # the path of the .gyp file as the base to relativize against.
904 # E.g. "foo/bar" when we're constructing targets found "foo/bar/baz.gyp". 937 # E.g. "foo/bar" when we're constructing targets found "foo/bar/baz.gyp".
905 base_path = gyp.common.RelativePath(os.path.dirname(build_file), 938 base_path = gyp.common.RelativePath(os.path.dirname(build_file),
906 options.depth) 939 options.depth)
907 # We write the .mk file in the base_path directory. 940 # We write the .mk file in the base_path directory.
908 output_file = os.path.join(options.depth, 941 output_file = os.path.join(options.depth,
909 base_path, 942 base_path,
910 target + options.suffix + '.mk') 943 target + '.' + toolset + options.suffix + '.mk')
911 944
912 if options.generator_output: 945 if options.generator_output:
913 output_file = os.path.join(options.generator_output, output_file) 946 output_file = os.path.join(options.generator_output, output_file)
914 947
915 spec = target_dicts[qualified_target] 948 spec = target_dicts[qualified_target]
916 configs = spec['configurations'] 949 configs = spec['configurations']
917 950
918 writer = MakefileWriter() 951 writer = MakefileWriter()
919 writer.Write(qualified_target, base_path, output_file, spec, configs) 952 writer.Write(qualified_target, base_path, output_file, spec, configs)
920 953
(...skipping 11 matching lines...) Expand all
932 ' '.join(map(Sourceify, build_files)), 965 ' '.join(map(Sourceify, build_files)),
933 gyp.common.EncodePOSIXShellList( 966 gyp.common.EncodePOSIXShellList(
934 [gyp.common.FixIfRelativePath(params['gyp_binary'], options.depth), 967 [gyp.common.FixIfRelativePath(params['gyp_binary'], options.depth),
935 '-fmake'] + 968 '-fmake'] +
936 gyp.RegenerateFlags(options) + 969 gyp.RegenerateFlags(options) +
937 build_files_args))) 970 build_files_args)))
938 971
939 root_makefile.write(SHARED_FOOTER) 972 root_makefile.write(SHARED_FOOTER)
940 973
941 root_makefile.close() 974 root_makefile.close()
OLDNEW
« no previous file with comments | « pylib/gyp/generator/gypd.py ('k') | pylib/gyp/generator/msvs.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698