gyp: update to 78b26f7
[platform/upstream/nodejs.git] / tools / gyp / pylib / gyp / generator / make.py
1 # Copyright (c) 2013 Google Inc. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file.
4
5 # Notes:
6 #
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
9 # graph in front of make and let it figure it out.
10 #
11 # The code below generates a separate .mk file for each target, but
12 # all are sourced by the top-level Makefile.  This means that all
13 # variables in .mk-files clobber one another.  Be careful to use :=
14 # where appropriate for immediate evaluation, and similarly to watch
15 # that you're not relying on a variable value to last beween different
16 # .mk files.
17 #
18 # TODOs:
19 #
20 # Global settings and utility functions are currently stuffed in the
21 # toplevel Makefile.  It may make sense to generate some .mk files on
22 # the side to keep the the files readable.
23
24 import os
25 import re
26 import sys
27 import subprocess
28 import gyp
29 import gyp.common
30 import gyp.xcode_emulation
31 from gyp.common import GetEnvironFallback
32
33 generator_default_variables = {
34   'EXECUTABLE_PREFIX': '',
35   'EXECUTABLE_SUFFIX': '',
36   'STATIC_LIB_PREFIX': 'lib',
37   'SHARED_LIB_PREFIX': 'lib',
38   'STATIC_LIB_SUFFIX': '.a',
39   'INTERMEDIATE_DIR': '$(obj).$(TOOLSET)/$(TARGET)/geni',
40   'SHARED_INTERMEDIATE_DIR': '$(obj)/gen',
41   'PRODUCT_DIR': '$(builddir)',
42   'RULE_INPUT_ROOT': '%(INPUT_ROOT)s',  # This gets expanded by Python.
43   'RULE_INPUT_DIRNAME': '%(INPUT_DIRNAME)s',  # This gets expanded by Python.
44   'RULE_INPUT_PATH': '$(abspath $<)',
45   'RULE_INPUT_EXT': '$(suffix $<)',
46   'RULE_INPUT_NAME': '$(notdir $<)',
47   'CONFIGURATION_NAME': '$(BUILDTYPE)',
48 }
49
50 # Make supports multiple toolsets
51 generator_supports_multiple_toolsets = True
52
53 # Request sorted dependencies in the order from dependents to dependencies.
54 generator_wants_sorted_dependencies = False
55
56 # Placates pylint.
57 generator_additional_non_configuration_keys = []
58 generator_additional_path_sections = []
59 generator_extra_sources_for_rules = []
60 generator_filelist_paths = None
61
62
63 def CalculateVariables(default_variables, params):
64   """Calculate additional variables for use in the build (called by gyp)."""
65   flavor = gyp.common.GetFlavor(params)
66   if flavor == 'mac':
67     default_variables.setdefault('OS', 'mac')
68     default_variables.setdefault('SHARED_LIB_SUFFIX', '.dylib')
69     default_variables.setdefault('SHARED_LIB_DIR',
70                                  generator_default_variables['PRODUCT_DIR'])
71     default_variables.setdefault('LIB_DIR',
72                                  generator_default_variables['PRODUCT_DIR'])
73
74     # Copy additional generator configuration data from Xcode, which is shared
75     # by the Mac Make generator.
76     import gyp.generator.xcode as xcode_generator
77     global generator_additional_non_configuration_keys
78     generator_additional_non_configuration_keys = getattr(xcode_generator,
79         'generator_additional_non_configuration_keys', [])
80     global generator_additional_path_sections
81     generator_additional_path_sections = getattr(xcode_generator,
82         'generator_additional_path_sections', [])
83     global generator_extra_sources_for_rules
84     generator_extra_sources_for_rules = getattr(xcode_generator,
85         'generator_extra_sources_for_rules', [])
86     COMPILABLE_EXTENSIONS.update({'.m': 'objc', '.mm' : 'objcxx'})
87   else:
88     operating_system = flavor
89     if flavor == 'android':
90       operating_system = 'linux'  # Keep this legacy behavior for now.
91     default_variables.setdefault('OS', operating_system)
92     default_variables.setdefault('SHARED_LIB_SUFFIX', '.so')
93     default_variables.setdefault('SHARED_LIB_DIR','$(builddir)/lib.$(TOOLSET)')
94     default_variables.setdefault('LIB_DIR', '$(obj).$(TOOLSET)')
95
96
97 def CalculateGeneratorInputInfo(params):
98   """Calculate the generator specific info that gets fed to input (called by
99   gyp)."""
100   generator_flags = params.get('generator_flags', {})
101   android_ndk_version = generator_flags.get('android_ndk_version', None)
102   # Android NDK requires a strict link order.
103   if android_ndk_version:
104     global generator_wants_sorted_dependencies
105     generator_wants_sorted_dependencies = True
106
107   output_dir = params['options'].generator_output or \
108                params['options'].toplevel_dir
109   builddir_name = generator_flags.get('output_dir', 'out')
110   qualified_out_dir = os.path.normpath(os.path.join(
111     output_dir, builddir_name, 'gypfiles'))
112
113   global generator_filelist_paths
114   generator_filelist_paths = {
115     'toplevel': params['options'].toplevel_dir,
116     'qualified_out_dir': qualified_out_dir,
117   }
118
119
120 def ensure_directory_exists(path):
121   dir = os.path.dirname(path)
122   if dir and not os.path.exists(dir):
123     os.makedirs(dir)
124
125
126 # The .d checking code below uses these functions:
127 # wildcard, sort, foreach, shell, wordlist
128 # wildcard can handle spaces, the rest can't.
129 # Since I could find no way to make foreach work with spaces in filenames
130 # correctly, the .d files have spaces replaced with another character. The .d
131 # file for
132 #     Chromium\ Framework.framework/foo
133 # is for example
134 #     out/Release/.deps/out/Release/Chromium?Framework.framework/foo
135 # This is the replacement character.
136 SPACE_REPLACEMENT = '?'
137
138
139 LINK_COMMANDS_LINUX = """\
140 quiet_cmd_alink = AR($(TOOLSET)) $@
141 cmd_alink = rm -f $@ && $(AR.$(TOOLSET)) crs $@ $(filter %.o,$^)
142
143 quiet_cmd_alink_thin = AR($(TOOLSET)) $@
144 cmd_alink_thin = rm -f $@ && $(AR.$(TOOLSET)) crsT $@ $(filter %.o,$^)
145
146 # Due to circular dependencies between libraries :(, we wrap the
147 # special "figure out circular dependencies" flags around the entire
148 # input list during linking.
149 quiet_cmd_link = LINK($(TOOLSET)) $@
150 cmd_link = $(LINK.$(TOOLSET)) $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o $@ -Wl,--start-group $(LD_INPUTS) -Wl,--end-group $(LIBS)
151
152 # We support two kinds of shared objects (.so):
153 # 1) shared_library, which is just bundling together many dependent libraries
154 # into a link line.
155 # 2) loadable_module, which is generating a module intended for dlopen().
156 #
157 # They differ only slightly:
158 # In the former case, we want to package all dependent code into the .so.
159 # In the latter case, we want to package just the API exposed by the
160 # outermost module.
161 # This means shared_library uses --whole-archive, while loadable_module doesn't.
162 # (Note that --whole-archive is incompatible with the --start-group used in
163 # normal linking.)
164
165 # Other shared-object link notes:
166 # - Set SONAME to the library filename so our binaries don't reference
167 # the local, absolute paths used on the link command-line.
168 quiet_cmd_solink = SOLINK($(TOOLSET)) $@
169 cmd_solink = $(LINK.$(TOOLSET)) -shared $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -Wl,-soname=$(@F) -o $@ -Wl,--whole-archive $(LD_INPUTS) -Wl,--no-whole-archive $(LIBS)
170
171 quiet_cmd_solink_module = SOLINK_MODULE($(TOOLSET)) $@
172 cmd_solink_module = $(LINK.$(TOOLSET)) -shared $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -Wl,-soname=$(@F) -o $@ -Wl,--start-group $(filter-out FORCE_DO_CMD, $^) -Wl,--end-group $(LIBS)
173 """
174
175 LINK_COMMANDS_MAC = """\
176 quiet_cmd_alink = LIBTOOL-STATIC $@
177 cmd_alink = rm -f $@ && ./gyp-mac-tool filter-libtool libtool $(GYP_LIBTOOLFLAGS) -static -o $@ $(filter %.o,$^)
178
179 quiet_cmd_link = LINK($(TOOLSET)) $@
180 cmd_link = $(LINK.$(TOOLSET)) $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o "$@" $(LD_INPUTS) $(LIBS)
181
182 quiet_cmd_solink = SOLINK($(TOOLSET)) $@
183 cmd_solink = $(LINK.$(TOOLSET)) -shared $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o "$@" $(LD_INPUTS) $(LIBS)
184
185 quiet_cmd_solink_module = SOLINK_MODULE($(TOOLSET)) $@
186 cmd_solink_module = $(LINK.$(TOOLSET)) -bundle $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o $@ $(filter-out FORCE_DO_CMD, $^) $(LIBS)
187 """
188
189 LINK_COMMANDS_ANDROID = """\
190 quiet_cmd_alink = AR($(TOOLSET)) $@
191 cmd_alink = rm -f $@ && $(AR.$(TOOLSET)) crs $@ $(filter %.o,$^)
192
193 quiet_cmd_alink_thin = AR($(TOOLSET)) $@
194 cmd_alink_thin = rm -f $@ && $(AR.$(TOOLSET)) crsT $@ $(filter %.o,$^)
195
196 # Due to circular dependencies between libraries :(, we wrap the
197 # special "figure out circular dependencies" flags around the entire
198 # input list during linking.
199 quiet_cmd_link = LINK($(TOOLSET)) $@
200 quiet_cmd_link_host = LINK($(TOOLSET)) $@
201 cmd_link = $(LINK.$(TOOLSET)) $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o $@ -Wl,--start-group $(LD_INPUTS) -Wl,--end-group $(LIBS)
202 cmd_link_host = $(LINK.$(TOOLSET)) $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o $@ $(LD_INPUTS) $(LIBS)
203
204 # Other shared-object link notes:
205 # - Set SONAME to the library filename so our binaries don't reference
206 # the local, absolute paths used on the link command-line.
207 quiet_cmd_solink = SOLINK($(TOOLSET)) $@
208 cmd_solink = $(LINK.$(TOOLSET)) -shared $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -Wl,-soname=$(@F) -o $@ -Wl,--whole-archive $(LD_INPUTS) -Wl,--no-whole-archive $(LIBS)
209
210 quiet_cmd_solink_module = SOLINK_MODULE($(TOOLSET)) $@
211 cmd_solink_module = $(LINK.$(TOOLSET)) -shared $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -Wl,-soname=$(@F) -o $@ -Wl,--start-group $(filter-out FORCE_DO_CMD, $^) -Wl,--end-group $(LIBS)
212 quiet_cmd_solink_module_host = SOLINK_MODULE($(TOOLSET)) $@
213 cmd_solink_module_host = $(LINK.$(TOOLSET)) -shared $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -Wl,-soname=$(@F) -o $@ $(filter-out FORCE_DO_CMD, $^) $(LIBS)
214 """
215
216
217 LINK_COMMANDS_AIX = """\
218 quiet_cmd_alink = AR($(TOOLSET)) $@
219 cmd_alink = rm -f $@ && $(AR.$(TOOLSET)) crs $@ $(filter %.o,$^)
220
221 quiet_cmd_alink_thin = AR($(TOOLSET)) $@
222 cmd_alink_thin = rm -f $@ && $(AR.$(TOOLSET)) crs $@ $(filter %.o,$^)
223
224 quiet_cmd_link = LINK($(TOOLSET)) $@
225 cmd_link = $(LINK.$(TOOLSET)) $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o $@ $(LD_INPUTS) $(LIBS)
226
227 quiet_cmd_solink = SOLINK($(TOOLSET)) $@
228 cmd_solink = $(LINK.$(TOOLSET)) -shared $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o $@ $(LD_INPUTS) $(LIBS)
229
230 quiet_cmd_solink_module = SOLINK_MODULE($(TOOLSET)) $@
231 cmd_solink_module = $(LINK.$(TOOLSET)) -shared $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o $@ $(filter-out FORCE_DO_CMD, $^) $(LIBS)
232 """
233
234
235 # Header of toplevel Makefile.
236 # This should go into the build tree, but it's easier to keep it here for now.
237 SHARED_HEADER = ("""\
238 # We borrow heavily from the kernel build setup, though we are simpler since
239 # we don't have Kconfig tweaking settings on us.
240
241 # The implicit make rules have it looking for RCS files, among other things.
242 # We instead explicitly write all the rules we care about.
243 # It's even quicker (saves ~200ms) to pass -r on the command line.
244 MAKEFLAGS=-r
245
246 # The source directory tree.
247 srcdir := %(srcdir)s
248 abs_srcdir := $(abspath $(srcdir))
249
250 # The name of the builddir.
251 builddir_name ?= %(builddir)s
252
253 # The V=1 flag on command line makes us verbosely print command lines.
254 ifdef V
255   quiet=
256 else
257   quiet=quiet_
258 endif
259
260 # Specify BUILDTYPE=Release on the command line for a release build.
261 BUILDTYPE ?= %(default_configuration)s
262
263 # Directory all our build output goes into.
264 # Note that this must be two directories beneath src/ for unit tests to pass,
265 # as they reach into the src/ directory for data with relative paths.
266 builddir ?= $(builddir_name)/$(BUILDTYPE)
267 abs_builddir := $(abspath $(builddir))
268 depsdir := $(builddir)/.deps
269
270 # Object output directory.
271 obj := $(builddir)/obj
272 abs_obj := $(abspath $(obj))
273
274 # We build up a list of every single one of the targets so we can slurp in the
275 # generated dependency rule Makefiles in one pass.
276 all_deps :=
277
278 %(make_global_settings)s
279
280 CC.target ?= %(CC.target)s
281 CFLAGS.target ?= $(CFLAGS)
282 CXX.target ?= %(CXX.target)s
283 CXXFLAGS.target ?= $(CXXFLAGS)
284 LINK.target ?= %(LINK.target)s
285 LDFLAGS.target ?= $(LDFLAGS)
286 AR.target ?= $(AR)
287
288 # C++ apps need to be linked with g++.
289 #
290 # Note: flock is used to seralize linking. Linking is a memory-intensive
291 # process so running parallel links can often lead to thrashing.  To disable
292 # the serialization, override LINK via an envrionment variable as follows:
293 #
294 #   export LINK=g++
295 #
296 # This will allow make to invoke N linker processes as specified in -jN.
297 LINK ?= %(flock)s $(builddir)/linker.lock $(CXX.target)
298
299 # TODO(evan): move all cross-compilation logic to gyp-time so we don't need
300 # to replicate this environment fallback in make as well.
301 CC.host ?= %(CC.host)s
302 CFLAGS.host ?=
303 CXX.host ?= %(CXX.host)s
304 CXXFLAGS.host ?=
305 LINK.host ?= %(LINK.host)s
306 LDFLAGS.host ?=
307 AR.host ?= %(AR.host)s
308
309 # Define a dir function that can handle spaces.
310 # http://www.gnu.org/software/make/manual/make.html#Syntax-of-Functions
311 # "leading spaces cannot appear in the text of the first argument as written.
312 # These characters can be put into the argument value by variable substitution."
313 empty :=
314 space := $(empty) $(empty)
315
316 # http://stackoverflow.com/questions/1189781/using-make-dir-or-notdir-on-a-path-with-spaces
317 replace_spaces = $(subst $(space),""" + SPACE_REPLACEMENT + """,$1)
318 unreplace_spaces = $(subst """ + SPACE_REPLACEMENT + """,$(space),$1)
319 dirx = $(call unreplace_spaces,$(dir $(call replace_spaces,$1)))
320
321 # Flags to make gcc output dependency info.  Note that you need to be
322 # careful here to use the flags that ccache and distcc can understand.
323 # We write to a dep file on the side first and then rename at the end
324 # so we can't end up with a broken dep file.
325 depfile = $(depsdir)/$(call replace_spaces,$@).d
326 DEPFLAGS = -MMD -MF $(depfile).raw
327
328 # We have to fixup the deps output in a few ways.
329 # (1) the file output should mention the proper .o file.
330 # ccache or distcc lose the path to the target, so we convert a rule of
331 # the form:
332 #   foobar.o: DEP1 DEP2
333 # into
334 #   path/to/foobar.o: DEP1 DEP2
335 # (2) we want missing files not to cause us to fail to build.
336 # We want to rewrite
337 #   foobar.o: DEP1 DEP2 \\
338 #               DEP3
339 # to
340 #   DEP1:
341 #   DEP2:
342 #   DEP3:
343 # so if the files are missing, they're just considered phony rules.
344 # We have to do some pretty insane escaping to get those backslashes
345 # and dollar signs past make, the shell, and sed at the same time.
346 # Doesn't work with spaces, but that's fine: .d files have spaces in
347 # their names replaced with other characters."""
348 r"""
349 define fixup_dep
350 # The depfile may not exist if the input file didn't have any #includes.
351 touch $(depfile).raw
352 # Fixup path as in (1).
353 sed -e "s|^$(notdir $@)|$@|" $(depfile).raw >> $(depfile)
354 # Add extra rules as in (2).
355 # We remove slashes and replace spaces with new lines;
356 # remove blank lines;
357 # delete the first line and append a colon to the remaining lines.
358 sed -e 's|\\||' -e 'y| |\n|' $(depfile).raw |\
359   grep -v '^$$'                             |\
360   sed -e 1d -e 's|$$|:|'                     \
361     >> $(depfile)
362 rm $(depfile).raw
363 endef
364 """
365 """
366 # Command definitions:
367 # - cmd_foo is the actual command to run;
368 # - quiet_cmd_foo is the brief-output summary of the command.
369
370 quiet_cmd_cc = CC($(TOOLSET)) $@
371 cmd_cc = $(CC.$(TOOLSET)) $(GYP_CFLAGS) $(DEPFLAGS) $(CFLAGS.$(TOOLSET)) -c -o $@ $<
372
373 quiet_cmd_cxx = CXX($(TOOLSET)) $@
374 cmd_cxx = $(CXX.$(TOOLSET)) $(GYP_CXXFLAGS) $(DEPFLAGS) $(CXXFLAGS.$(TOOLSET)) -c -o $@ $<
375 %(extra_commands)s
376 quiet_cmd_touch = TOUCH $@
377 cmd_touch = touch $@
378
379 quiet_cmd_copy = COPY $@
380 # send stderr to /dev/null to ignore messages when linking directories.
381 cmd_copy = ln -f "$<" "$@" 2>/dev/null || (rm -rf "$@" && cp -af "$<" "$@")
382
383 %(link_commands)s
384 """
385
386 r"""
387 # Define an escape_quotes function to escape single quotes.
388 # This allows us to handle quotes properly as long as we always use
389 # use single quotes and escape_quotes.
390 escape_quotes = $(subst ','\'',$(1))
391 # This comment is here just to include a ' to unconfuse syntax highlighting.
392 # Define an escape_vars function to escape '$' variable syntax.
393 # This allows us to read/write command lines with shell variables (e.g.
394 # $LD_LIBRARY_PATH), without triggering make substitution.
395 escape_vars = $(subst $$,$$$$,$(1))
396 # Helper that expands to a shell command to echo a string exactly as it is in
397 # make. This uses printf instead of echo because printf's behaviour with respect
398 # to escape sequences is more portable than echo's across different shells
399 # (e.g., dash, bash).
400 exact_echo = printf '%%s\n' '$(call escape_quotes,$(1))'
401 """
402 """
403 # Helper to compare the command we're about to run against the command
404 # we logged the last time we ran the command.  Produces an empty
405 # string (false) when the commands match.
406 # Tricky point: Make has no string-equality test function.
407 # The kernel uses the following, but it seems like it would have false
408 # positives, where one string reordered its arguments.
409 #   arg_check = $(strip $(filter-out $(cmd_$(1)), $(cmd_$@)) \\
410 #                       $(filter-out $(cmd_$@), $(cmd_$(1))))
411 # We instead substitute each for the empty string into the other, and
412 # say they're equal if both substitutions produce the empty string.
413 # .d files contain """ + SPACE_REPLACEMENT + \
414                    """ instead of spaces, take that into account.
415 command_changed = $(or $(subst $(cmd_$(1)),,$(cmd_$(call replace_spaces,$@))),\\
416                        $(subst $(cmd_$(call replace_spaces,$@)),,$(cmd_$(1))))
417
418 # Helper that is non-empty when a prerequisite changes.
419 # Normally make does this implicitly, but we force rules to always run
420 # so we can check their command lines.
421 #   $? -- new prerequisites
422 #   $| -- order-only dependencies
423 prereq_changed = $(filter-out FORCE_DO_CMD,$(filter-out $|,$?))
424
425 # Helper that executes all postbuilds until one fails.
426 define do_postbuilds
427   @E=0;\\
428   for p in $(POSTBUILDS); do\\
429     eval $$p;\\
430     E=$$?;\\
431     if [ $$E -ne 0 ]; then\\
432       break;\\
433     fi;\\
434   done;\\
435   if [ $$E -ne 0 ]; then\\
436     rm -rf "$@";\\
437     exit $$E;\\
438   fi
439 endef
440
441 # do_cmd: run a command via the above cmd_foo names, if necessary.
442 # Should always run for a given target to handle command-line changes.
443 # Second argument, if non-zero, makes it do asm/C/C++ dependency munging.
444 # Third argument, if non-zero, makes it do POSTBUILDS processing.
445 # Note: We intentionally do NOT call dirx for depfile, since it contains """ + \
446                                                      SPACE_REPLACEMENT + """ for
447 # spaces already and dirx strips the """ + SPACE_REPLACEMENT + \
448                                      """ characters.
449 define do_cmd
450 $(if $(or $(command_changed),$(prereq_changed)),
451   @$(call exact_echo,  $($(quiet)cmd_$(1)))
452   @mkdir -p "$(call dirx,$@)" "$(dir $(depfile))"
453   $(if $(findstring flock,$(word %(flock_index)d,$(cmd_$1))),
454     @$(cmd_$(1))
455     @echo "  $(quiet_cmd_$(1)): Finished",
456     @$(cmd_$(1))
457   )
458   @$(call exact_echo,$(call escape_vars,cmd_$(call replace_spaces,$@) := $(cmd_$(1)))) > $(depfile)
459   @$(if $(2),$(fixup_dep))
460   $(if $(and $(3), $(POSTBUILDS)),
461     $(call do_postbuilds)
462   )
463 )
464 endef
465
466 # Declare the "%(default_target)s" target first so it is the default,
467 # even though we don't have the deps yet.
468 .PHONY: %(default_target)s
469 %(default_target)s:
470
471 # make looks for ways to re-generate included makefiles, but in our case, we
472 # don't have a direct way. Explicitly telling make that it has nothing to do
473 # for them makes it go faster.
474 %%.d: ;
475
476 # Use FORCE_DO_CMD to force a target to run.  Should be coupled with
477 # do_cmd.
478 .PHONY: FORCE_DO_CMD
479 FORCE_DO_CMD:
480
481 """)
482
483 SHARED_HEADER_MAC_COMMANDS = """
484 quiet_cmd_objc = CXX($(TOOLSET)) $@
485 cmd_objc = $(CC.$(TOOLSET)) $(GYP_OBJCFLAGS) $(DEPFLAGS) -c -o $@ $<
486
487 quiet_cmd_objcxx = CXX($(TOOLSET)) $@
488 cmd_objcxx = $(CXX.$(TOOLSET)) $(GYP_OBJCXXFLAGS) $(DEPFLAGS) -c -o $@ $<
489
490 # Commands for precompiled header files.
491 quiet_cmd_pch_c = CXX($(TOOLSET)) $@
492 cmd_pch_c = $(CC.$(TOOLSET)) $(GYP_PCH_CFLAGS) $(DEPFLAGS) $(CXXFLAGS.$(TOOLSET)) -c -o $@ $<
493 quiet_cmd_pch_cc = CXX($(TOOLSET)) $@
494 cmd_pch_cc = $(CC.$(TOOLSET)) $(GYP_PCH_CXXFLAGS) $(DEPFLAGS) $(CXXFLAGS.$(TOOLSET)) -c -o $@ $<
495 quiet_cmd_pch_m = CXX($(TOOLSET)) $@
496 cmd_pch_m = $(CC.$(TOOLSET)) $(GYP_PCH_OBJCFLAGS) $(DEPFLAGS) -c -o $@ $<
497 quiet_cmd_pch_mm = CXX($(TOOLSET)) $@
498 cmd_pch_mm = $(CC.$(TOOLSET)) $(GYP_PCH_OBJCXXFLAGS) $(DEPFLAGS) -c -o $@ $<
499
500 # gyp-mac-tool is written next to the root Makefile by gyp.
501 # Use $(4) for the command, since $(2) and $(3) are used as flag by do_cmd
502 # already.
503 quiet_cmd_mac_tool = MACTOOL $(4) $<
504 cmd_mac_tool = ./gyp-mac-tool $(4) $< "$@"
505
506 quiet_cmd_mac_package_framework = PACKAGE FRAMEWORK $@
507 cmd_mac_package_framework = ./gyp-mac-tool package-framework "$@" $(4)
508
509 quiet_cmd_infoplist = INFOPLIST $@
510 cmd_infoplist = $(CC.$(TOOLSET)) -E -P -Wno-trigraphs -x c $(INFOPLIST_DEFINES) "$<" -o "$@"
511 """
512
513
514 def WriteRootHeaderSuffixRules(writer):
515   extensions = sorted(COMPILABLE_EXTENSIONS.keys(), key=str.lower)
516
517   writer.write('# Suffix rules, putting all outputs into $(obj).\n')
518   for ext in extensions:
519     writer.write('$(obj).$(TOOLSET)/%%.o: $(srcdir)/%%%s FORCE_DO_CMD\n' % ext)
520     writer.write('\t@$(call do_cmd,%s,1)\n' % COMPILABLE_EXTENSIONS[ext])
521
522   writer.write('\n# Try building from generated source, too.\n')
523   for ext in extensions:
524     writer.write(
525         '$(obj).$(TOOLSET)/%%.o: $(obj).$(TOOLSET)/%%%s FORCE_DO_CMD\n' % ext)
526     writer.write('\t@$(call do_cmd,%s,1)\n' % COMPILABLE_EXTENSIONS[ext])
527   writer.write('\n')
528   for ext in extensions:
529     writer.write('$(obj).$(TOOLSET)/%%.o: $(obj)/%%%s FORCE_DO_CMD\n' % ext)
530     writer.write('\t@$(call do_cmd,%s,1)\n' % COMPILABLE_EXTENSIONS[ext])
531   writer.write('\n')
532
533
534 SHARED_HEADER_SUFFIX_RULES_COMMENT1 = ("""\
535 # Suffix rules, putting all outputs into $(obj).
536 """)
537
538
539 SHARED_HEADER_SUFFIX_RULES_COMMENT2 = ("""\
540 # Try building from generated source, too.
541 """)
542
543
544 SHARED_FOOTER = """\
545 # "all" is a concatenation of the "all" targets from all the included
546 # sub-makefiles. This is just here to clarify.
547 all:
548
549 # Add in dependency-tracking rules.  $(all_deps) is the list of every single
550 # target in our tree. Only consider the ones with .d (dependency) info:
551 d_files := $(wildcard $(foreach f,$(all_deps),$(depsdir)/$(f).d))
552 ifneq ($(d_files),)
553   include $(d_files)
554 endif
555 """
556
557 header = """\
558 # This file is generated by gyp; do not edit.
559
560 """
561
562 # Maps every compilable file extension to the do_cmd that compiles it.
563 COMPILABLE_EXTENSIONS = {
564   '.c': 'cc',
565   '.cc': 'cxx',
566   '.cpp': 'cxx',
567   '.cxx': 'cxx',
568   '.s': 'cc',
569   '.S': 'cc',
570 }
571
572 def Compilable(filename):
573   """Return true if the file is compilable (should be in OBJS)."""
574   for res in (filename.endswith(e) for e in COMPILABLE_EXTENSIONS):
575     if res:
576       return True
577   return False
578
579
580 def Linkable(filename):
581   """Return true if the file is linkable (should be on the link line)."""
582   return filename.endswith('.o')
583
584
585 def Target(filename):
586   """Translate a compilable filename to its .o target."""
587   return os.path.splitext(filename)[0] + '.o'
588
589
590 def EscapeShellArgument(s):
591   """Quotes an argument so that it will be interpreted literally by a POSIX
592      shell. Taken from
593      http://stackoverflow.com/questions/35817/whats-the-best-way-to-escape-ossystem-calls-in-python
594      """
595   return "'" + s.replace("'", "'\\''") + "'"
596
597
598 def EscapeMakeVariableExpansion(s):
599   """Make has its own variable expansion syntax using $. We must escape it for
600      string to be interpreted literally."""
601   return s.replace('$', '$$')
602
603
604 def EscapeCppDefine(s):
605   """Escapes a CPP define so that it will reach the compiler unaltered."""
606   s = EscapeShellArgument(s)
607   s = EscapeMakeVariableExpansion(s)
608   # '#' characters must be escaped even embedded in a string, else Make will
609   # treat it as the start of a comment.
610   return s.replace('#', r'\#')
611
612
613 def QuoteIfNecessary(string):
614   """TODO: Should this ideally be replaced with one or more of the above
615      functions?"""
616   if '"' in string:
617     string = '"' + string.replace('"', '\\"') + '"'
618   return string
619
620
621 def StringToMakefileVariable(string):
622   """Convert a string to a value that is acceptable as a make variable name."""
623   return re.sub('[^a-zA-Z0-9_]', '_', string)
624
625
626 srcdir_prefix = ''
627 def Sourceify(path):
628   """Convert a path to its source directory form."""
629   if '$(' in path:
630     return path
631   if os.path.isabs(path):
632     return path
633   return srcdir_prefix + path
634
635
636 def QuoteSpaces(s, quote=r'\ '):
637   return s.replace(' ', quote)
638
639
640 # Map from qualified target to path to output.
641 target_outputs = {}
642 # Map from qualified target to any linkable output.  A subset
643 # of target_outputs.  E.g. when mybinary depends on liba, we want to
644 # include liba in the linker line; when otherbinary depends on
645 # mybinary, we just want to build mybinary first.
646 target_link_deps = {}
647
648
649 class MakefileWriter:
650   """MakefileWriter packages up the writing of one target-specific foobar.mk.
651
652   Its only real entry point is Write(), and is mostly used for namespacing.
653   """
654
655   def __init__(self, generator_flags, flavor):
656     self.generator_flags = generator_flags
657     self.flavor = flavor
658
659     self.suffix_rules_srcdir = {}
660     self.suffix_rules_objdir1 = {}
661     self.suffix_rules_objdir2 = {}
662
663     # Generate suffix rules for all compilable extensions.
664     for ext in COMPILABLE_EXTENSIONS.keys():
665       # Suffix rules for source folder.
666       self.suffix_rules_srcdir.update({ext: ("""\
667 $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(srcdir)/%%%s FORCE_DO_CMD
668         @$(call do_cmd,%s,1)
669 """ % (ext, COMPILABLE_EXTENSIONS[ext]))})
670
671       # Suffix rules for generated source files.
672       self.suffix_rules_objdir1.update({ext: ("""\
673 $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj).$(TOOLSET)/%%%s FORCE_DO_CMD
674         @$(call do_cmd,%s,1)
675 """ % (ext, COMPILABLE_EXTENSIONS[ext]))})
676       self.suffix_rules_objdir2.update({ext: ("""\
677 $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD
678         @$(call do_cmd,%s,1)
679 """ % (ext, COMPILABLE_EXTENSIONS[ext]))})
680
681
682   def Write(self, qualified_target, base_path, output_filename, spec, configs,
683             part_of_all):
684     """The main entry point: writes a .mk file for a single target.
685
686     Arguments:
687       qualified_target: target we're generating
688       base_path: path relative to source root we're building in, used to resolve
689                  target-relative paths
690       output_filename: output .mk file name to write
691       spec, configs: gyp info
692       part_of_all: flag indicating this target is part of 'all'
693     """
694     ensure_directory_exists(output_filename)
695
696     self.fp = open(output_filename, 'w')
697
698     self.fp.write(header)
699
700     self.qualified_target = qualified_target
701     self.path = base_path
702     self.target = spec['target_name']
703     self.type = spec['type']
704     self.toolset = spec['toolset']
705
706     self.is_mac_bundle = gyp.xcode_emulation.IsMacBundle(self.flavor, spec)
707     if self.flavor == 'mac':
708       self.xcode_settings = gyp.xcode_emulation.XcodeSettings(spec)
709     else:
710       self.xcode_settings = None
711
712     deps, link_deps = self.ComputeDeps(spec)
713
714     # Some of the generation below can add extra output, sources, or
715     # link dependencies.  All of the out params of the functions that
716     # follow use names like extra_foo.
717     extra_outputs = []
718     extra_sources = []
719     extra_link_deps = []
720     extra_mac_bundle_resources = []
721     mac_bundle_deps = []
722
723     if self.is_mac_bundle:
724       self.output = self.ComputeMacBundleOutput(spec)
725       self.output_binary = self.ComputeMacBundleBinaryOutput(spec)
726     else:
727       self.output = self.output_binary = self.ComputeOutput(spec)
728
729     self.is_standalone_static_library = bool(
730         spec.get('standalone_static_library', 0))
731     self._INSTALLABLE_TARGETS = ('executable', 'loadable_module',
732                                  'shared_library')
733     if (self.is_standalone_static_library or
734         self.type in self._INSTALLABLE_TARGETS):
735       self.alias = os.path.basename(self.output)
736       install_path = self._InstallableTargetInstallPath()
737     else:
738       self.alias = self.output
739       install_path = self.output
740
741     self.WriteLn("TOOLSET := " + self.toolset)
742     self.WriteLn("TARGET := " + self.target)
743
744     # Actions must come first, since they can generate more OBJs for use below.
745     if 'actions' in spec:
746       self.WriteActions(spec['actions'], extra_sources, extra_outputs,
747                         extra_mac_bundle_resources, part_of_all)
748
749     # Rules must be early like actions.
750     if 'rules' in spec:
751       self.WriteRules(spec['rules'], extra_sources, extra_outputs,
752                       extra_mac_bundle_resources, part_of_all)
753
754     if 'copies' in spec:
755       self.WriteCopies(spec['copies'], extra_outputs, part_of_all)
756
757     # Bundle resources.
758     if self.is_mac_bundle:
759       all_mac_bundle_resources = (
760           spec.get('mac_bundle_resources', []) + extra_mac_bundle_resources)
761       self.WriteMacBundleResources(all_mac_bundle_resources, mac_bundle_deps)
762       self.WriteMacInfoPlist(mac_bundle_deps)
763
764     # Sources.
765     all_sources = spec.get('sources', []) + extra_sources
766     if all_sources:
767       self.WriteSources(
768           configs, deps, all_sources, extra_outputs,
769           extra_link_deps, part_of_all,
770           gyp.xcode_emulation.MacPrefixHeader(
771               self.xcode_settings, lambda p: Sourceify(self.Absolutify(p)),
772               self.Pchify))
773       sources = filter(Compilable, all_sources)
774       if sources:
775         self.WriteLn(SHARED_HEADER_SUFFIX_RULES_COMMENT1)
776         extensions = set([os.path.splitext(s)[1] for s in sources])
777         for ext in extensions:
778           if ext in self.suffix_rules_srcdir:
779             self.WriteLn(self.suffix_rules_srcdir[ext])
780         self.WriteLn(SHARED_HEADER_SUFFIX_RULES_COMMENT2)
781         for ext in extensions:
782           if ext in self.suffix_rules_objdir1:
783             self.WriteLn(self.suffix_rules_objdir1[ext])
784         for ext in extensions:
785           if ext in self.suffix_rules_objdir2:
786             self.WriteLn(self.suffix_rules_objdir2[ext])
787         self.WriteLn('# End of this set of suffix rules')
788
789         # Add dependency from bundle to bundle binary.
790         if self.is_mac_bundle:
791           mac_bundle_deps.append(self.output_binary)
792
793     self.WriteTarget(spec, configs, deps, extra_link_deps + link_deps,
794                      mac_bundle_deps, extra_outputs, part_of_all)
795
796     # Update global list of target outputs, used in dependency tracking.
797     target_outputs[qualified_target] = install_path
798
799     # Update global list of link dependencies.
800     if self.type in ('static_library', 'shared_library'):
801       target_link_deps[qualified_target] = self.output_binary
802
803     # Currently any versions have the same effect, but in future the behavior
804     # could be different.
805     if self.generator_flags.get('android_ndk_version', None):
806       self.WriteAndroidNdkModuleRule(self.target, all_sources, link_deps)
807
808     self.fp.close()
809
810
811   def WriteSubMake(self, output_filename, makefile_path, targets, build_dir):
812     """Write a "sub-project" Makefile.
813
814     This is a small, wrapper Makefile that calls the top-level Makefile to build
815     the targets from a single gyp file (i.e. a sub-project).
816
817     Arguments:
818       output_filename: sub-project Makefile name to write
819       makefile_path: path to the top-level Makefile
820       targets: list of "all" targets for this sub-project
821       build_dir: build output directory, relative to the sub-project
822     """
823     ensure_directory_exists(output_filename)
824     self.fp = open(output_filename, 'w')
825     self.fp.write(header)
826     # For consistency with other builders, put sub-project build output in the
827     # sub-project dir (see test/subdirectory/gyptest-subdir-all.py).
828     self.WriteLn('export builddir_name ?= %s' %
829                  os.path.join(os.path.dirname(output_filename), build_dir))
830     self.WriteLn('.PHONY: all')
831     self.WriteLn('all:')
832     if makefile_path:
833       makefile_path = ' -C ' + makefile_path
834     self.WriteLn('\t$(MAKE)%s %s' % (makefile_path, ' '.join(targets)))
835     self.fp.close()
836
837
838   def WriteActions(self, actions, extra_sources, extra_outputs,
839                    extra_mac_bundle_resources, part_of_all):
840     """Write Makefile code for any 'actions' from the gyp input.
841
842     extra_sources: a list that will be filled in with newly generated source
843                    files, if any
844     extra_outputs: a list that will be filled in with any outputs of these
845                    actions (used to make other pieces dependent on these
846                    actions)
847     part_of_all: flag indicating this target is part of 'all'
848     """
849     env = self.GetSortedXcodeEnv()
850     for action in actions:
851       name = StringToMakefileVariable('%s_%s' % (self.qualified_target,
852                                                  action['action_name']))
853       self.WriteLn('### Rules for action "%s":' % action['action_name'])
854       inputs = action['inputs']
855       outputs = action['outputs']
856
857       # Build up a list of outputs.
858       # Collect the output dirs we'll need.
859       dirs = set()
860       for out in outputs:
861         dir = os.path.split(out)[0]
862         if dir:
863           dirs.add(dir)
864       if int(action.get('process_outputs_as_sources', False)):
865         extra_sources += outputs
866       if int(action.get('process_outputs_as_mac_bundle_resources', False)):
867         extra_mac_bundle_resources += outputs
868
869       # Write the actual command.
870       action_commands = action['action']
871       if self.flavor == 'mac':
872         action_commands = [gyp.xcode_emulation.ExpandEnvVars(command, env)
873                           for command in action_commands]
874       command = gyp.common.EncodePOSIXShellList(action_commands)
875       if 'message' in action:
876         self.WriteLn('quiet_cmd_%s = ACTION %s $@' % (name, action['message']))
877       else:
878         self.WriteLn('quiet_cmd_%s = ACTION %s $@' % (name, name))
879       if len(dirs) > 0:
880         command = 'mkdir -p %s' % ' '.join(dirs) + '; ' + command
881
882       cd_action = 'cd %s; ' % Sourceify(self.path or '.')
883
884       # command and cd_action get written to a toplevel variable called
885       # cmd_foo. Toplevel variables can't handle things that change per
886       # makefile like $(TARGET), so hardcode the target.
887       command = command.replace('$(TARGET)', self.target)
888       cd_action = cd_action.replace('$(TARGET)', self.target)
889
890       # Set LD_LIBRARY_PATH in case the action runs an executable from this
891       # build which links to shared libs from this build.
892       # actions run on the host, so they should in theory only use host
893       # libraries, but until everything is made cross-compile safe, also use
894       # target libraries.
895       # TODO(piman): when everything is cross-compile safe, remove lib.target
896       self.WriteLn('cmd_%s = LD_LIBRARY_PATH=$(builddir)/lib.host:'
897                    '$(builddir)/lib.target:$$LD_LIBRARY_PATH; '
898                    'export LD_LIBRARY_PATH; '
899                    '%s%s'
900                    % (name, cd_action, command))
901       self.WriteLn()
902       outputs = map(self.Absolutify, outputs)
903       # The makefile rules are all relative to the top dir, but the gyp actions
904       # are defined relative to their containing dir.  This replaces the obj
905       # variable for the action rule with an absolute version so that the output
906       # goes in the right place.
907       # Only write the 'obj' and 'builddir' rules for the "primary" output (:1);
908       # it's superfluous for the "extra outputs", and this avoids accidentally
909       # writing duplicate dummy rules for those outputs.
910       # Same for environment.
911       self.WriteLn("%s: obj := $(abs_obj)" % QuoteSpaces(outputs[0]))
912       self.WriteLn("%s: builddir := $(abs_builddir)" % QuoteSpaces(outputs[0]))
913       self.WriteSortedXcodeEnv(outputs[0], self.GetSortedXcodeEnv())
914
915       for input in inputs:
916         assert ' ' not in input, (
917             "Spaces in action input filenames not supported (%s)"  % input)
918       for output in outputs:
919         assert ' ' not in output, (
920             "Spaces in action output filenames not supported (%s)"  % output)
921
922       # See the comment in WriteCopies about expanding env vars.
923       outputs = [gyp.xcode_emulation.ExpandEnvVars(o, env) for o in outputs]
924       inputs = [gyp.xcode_emulation.ExpandEnvVars(i, env) for i in inputs]
925
926       self.WriteDoCmd(outputs, map(Sourceify, map(self.Absolutify, inputs)),
927                       part_of_all=part_of_all, command=name)
928
929       # Stuff the outputs in a variable so we can refer to them later.
930       outputs_variable = 'action_%s_outputs' % name
931       self.WriteLn('%s := %s' % (outputs_variable, ' '.join(outputs)))
932       extra_outputs.append('$(%s)' % outputs_variable)
933       self.WriteLn()
934
935     self.WriteLn()
936
937
938   def WriteRules(self, rules, extra_sources, extra_outputs,
939                  extra_mac_bundle_resources, part_of_all):
940     """Write Makefile code for any 'rules' from the gyp input.
941
942     extra_sources: a list that will be filled in with newly generated source
943                    files, if any
944     extra_outputs: a list that will be filled in with any outputs of these
945                    rules (used to make other pieces dependent on these rules)
946     part_of_all: flag indicating this target is part of 'all'
947     """
948     env = self.GetSortedXcodeEnv()
949     for rule in rules:
950       name = StringToMakefileVariable('%s_%s' % (self.qualified_target,
951                                                  rule['rule_name']))
952       count = 0
953       self.WriteLn('### Generated for rule %s:' % name)
954
955       all_outputs = []
956
957       for rule_source in rule.get('rule_sources', []):
958         dirs = set()
959         (rule_source_dirname, rule_source_basename) = os.path.split(rule_source)
960         (rule_source_root, rule_source_ext) = \
961             os.path.splitext(rule_source_basename)
962
963         outputs = [self.ExpandInputRoot(out, rule_source_root,
964                                         rule_source_dirname)
965                    for out in rule['outputs']]
966
967         for out in outputs:
968           dir = os.path.dirname(out)
969           if dir:
970             dirs.add(dir)
971         if int(rule.get('process_outputs_as_sources', False)):
972           extra_sources += outputs
973         if int(rule.get('process_outputs_as_mac_bundle_resources', False)):
974           extra_mac_bundle_resources += outputs
975         inputs = map(Sourceify, map(self.Absolutify, [rule_source] +
976                                     rule.get('inputs', [])))
977         actions = ['$(call do_cmd,%s_%d)' % (name, count)]
978
979         if name == 'resources_grit':
980           # HACK: This is ugly.  Grit intentionally doesn't touch the
981           # timestamp of its output file when the file doesn't change,
982           # which is fine in hash-based dependency systems like scons
983           # and forge, but not kosher in the make world.  After some
984           # discussion, hacking around it here seems like the least
985           # amount of pain.
986           actions += ['@touch --no-create $@']
987
988         # See the comment in WriteCopies about expanding env vars.
989         outputs = [gyp.xcode_emulation.ExpandEnvVars(o, env) for o in outputs]
990         inputs = [gyp.xcode_emulation.ExpandEnvVars(i, env) for i in inputs]
991
992         outputs = map(self.Absolutify, outputs)
993         all_outputs += outputs
994         # Only write the 'obj' and 'builddir' rules for the "primary" output
995         # (:1); it's superfluous for the "extra outputs", and this avoids
996         # accidentally writing duplicate dummy rules for those outputs.
997         self.WriteLn('%s: obj := $(abs_obj)' % outputs[0])
998         self.WriteLn('%s: builddir := $(abs_builddir)' % outputs[0])
999         self.WriteMakeRule(outputs, inputs + ['FORCE_DO_CMD'], actions)
1000         # Spaces in rule filenames are not supported, but rule variables have
1001         # spaces in them (e.g. RULE_INPUT_PATH expands to '$(abspath $<)').
1002         # The spaces within the variables are valid, so remove the variables
1003         # before checking.
1004         variables_with_spaces = re.compile(r'\$\([^ ]* \$<\)')
1005         for output in outputs:
1006           output = re.sub(variables_with_spaces, '', output)
1007           assert ' ' not in output, (
1008               "Spaces in rule filenames not yet supported (%s)"  % output)
1009         self.WriteLn('all_deps += %s' % ' '.join(outputs))
1010
1011         action = [self.ExpandInputRoot(ac, rule_source_root,
1012                                        rule_source_dirname)
1013                   for ac in rule['action']]
1014         mkdirs = ''
1015         if len(dirs) > 0:
1016           mkdirs = 'mkdir -p %s; ' % ' '.join(dirs)
1017         cd_action = 'cd %s; ' % Sourceify(self.path or '.')
1018
1019         # action, cd_action, and mkdirs get written to a toplevel variable
1020         # called cmd_foo. Toplevel variables can't handle things that change
1021         # per makefile like $(TARGET), so hardcode the target.
1022         if self.flavor == 'mac':
1023           action = [gyp.xcode_emulation.ExpandEnvVars(command, env)
1024                     for command in action]
1025         action = gyp.common.EncodePOSIXShellList(action)
1026         action = action.replace('$(TARGET)', self.target)
1027         cd_action = cd_action.replace('$(TARGET)', self.target)
1028         mkdirs = mkdirs.replace('$(TARGET)', self.target)
1029
1030         # Set LD_LIBRARY_PATH in case the rule runs an executable from this
1031         # build which links to shared libs from this build.
1032         # rules run on the host, so they should in theory only use host
1033         # libraries, but until everything is made cross-compile safe, also use
1034         # target libraries.
1035         # TODO(piman): when everything is cross-compile safe, remove lib.target
1036         self.WriteLn(
1037             "cmd_%(name)s_%(count)d = LD_LIBRARY_PATH="
1038               "$(builddir)/lib.host:$(builddir)/lib.target:$$LD_LIBRARY_PATH; "
1039               "export LD_LIBRARY_PATH; "
1040               "%(cd_action)s%(mkdirs)s%(action)s" % {
1041           'action': action,
1042           'cd_action': cd_action,
1043           'count': count,
1044           'mkdirs': mkdirs,
1045           'name': name,
1046         })
1047         self.WriteLn(
1048             'quiet_cmd_%(name)s_%(count)d = RULE %(name)s_%(count)d $@' % {
1049           'count': count,
1050           'name': name,
1051         })
1052         self.WriteLn()
1053         count += 1
1054
1055       outputs_variable = 'rule_%s_outputs' % name
1056       self.WriteList(all_outputs, outputs_variable)
1057       extra_outputs.append('$(%s)' % outputs_variable)
1058
1059       self.WriteLn('### Finished generating for rule: %s' % name)
1060       self.WriteLn()
1061     self.WriteLn('### Finished generating for all rules')
1062     self.WriteLn('')
1063
1064
1065   def WriteCopies(self, copies, extra_outputs, part_of_all):
1066     """Write Makefile code for any 'copies' from the gyp input.
1067
1068     extra_outputs: a list that will be filled in with any outputs of this action
1069                    (used to make other pieces dependent on this action)
1070     part_of_all: flag indicating this target is part of 'all'
1071     """
1072     self.WriteLn('### Generated for copy rule.')
1073
1074     variable = StringToMakefileVariable(self.qualified_target + '_copies')
1075     outputs = []
1076     for copy in copies:
1077       for path in copy['files']:
1078         # Absolutify() may call normpath, and will strip trailing slashes.
1079         path = Sourceify(self.Absolutify(path))
1080         filename = os.path.split(path)[1]
1081         output = Sourceify(self.Absolutify(os.path.join(copy['destination'],
1082                                                         filename)))
1083
1084         # If the output path has variables in it, which happens in practice for
1085         # 'copies', writing the environment as target-local doesn't work,
1086         # because the variables are already needed for the target name.
1087         # Copying the environment variables into global make variables doesn't
1088         # work either, because then the .d files will potentially contain spaces
1089         # after variable expansion, and .d file handling cannot handle spaces.
1090         # As a workaround, manually expand variables at gyp time. Since 'copies'
1091         # can't run scripts, there's no need to write the env then.
1092         # WriteDoCmd() will escape spaces for .d files.
1093         env = self.GetSortedXcodeEnv()
1094         output = gyp.xcode_emulation.ExpandEnvVars(output, env)
1095         path = gyp.xcode_emulation.ExpandEnvVars(path, env)
1096         self.WriteDoCmd([output], [path], 'copy', part_of_all)
1097         outputs.append(output)
1098     self.WriteLn('%s = %s' % (variable, ' '.join(map(QuoteSpaces, outputs))))
1099     extra_outputs.append('$(%s)' % variable)
1100     self.WriteLn()
1101
1102
1103   def WriteMacBundleResources(self, resources, bundle_deps):
1104     """Writes Makefile code for 'mac_bundle_resources'."""
1105     self.WriteLn('### Generated for mac_bundle_resources')
1106
1107     for output, res in gyp.xcode_emulation.GetMacBundleResources(
1108         generator_default_variables['PRODUCT_DIR'], self.xcode_settings,
1109         map(Sourceify, map(self.Absolutify, resources))):
1110       self.WriteDoCmd([output], [res], 'mac_tool,,,copy-bundle-resource',
1111                       part_of_all=True)
1112       bundle_deps.append(output)
1113
1114
1115   def WriteMacInfoPlist(self, bundle_deps):
1116     """Write Makefile code for bundle Info.plist files."""
1117     info_plist, out, defines, extra_env = gyp.xcode_emulation.GetMacInfoPlist(
1118         generator_default_variables['PRODUCT_DIR'], self.xcode_settings,
1119         lambda p: Sourceify(self.Absolutify(p)))
1120     if not info_plist:
1121       return
1122     if defines:
1123       # Create an intermediate file to store preprocessed results.
1124       intermediate_plist = ('$(obj).$(TOOLSET)/$(TARGET)/' +
1125           os.path.basename(info_plist))
1126       self.WriteList(defines, intermediate_plist + ': INFOPLIST_DEFINES', '-D',
1127           quoter=EscapeCppDefine)
1128       self.WriteMakeRule([intermediate_plist], [info_plist],
1129           ['$(call do_cmd,infoplist)',
1130            # "Convert" the plist so that any weird whitespace changes from the
1131            # preprocessor do not affect the XML parser in mac_tool.
1132            '@plutil -convert xml1 $@ $@'])
1133       info_plist = intermediate_plist
1134     # plists can contain envvars and substitute them into the file.
1135     self.WriteSortedXcodeEnv(
1136         out, self.GetSortedXcodeEnv(additional_settings=extra_env))
1137     self.WriteDoCmd([out], [info_plist], 'mac_tool,,,copy-info-plist',
1138                     part_of_all=True)
1139     bundle_deps.append(out)
1140
1141
1142   def WriteSources(self, configs, deps, sources,
1143                    extra_outputs, extra_link_deps,
1144                    part_of_all, precompiled_header):
1145     """Write Makefile code for any 'sources' from the gyp input.
1146     These are source files necessary to build the current target.
1147
1148     configs, deps, sources: input from gyp.
1149     extra_outputs: a list of extra outputs this action should be dependent on;
1150                    used to serialize action/rules before compilation
1151     extra_link_deps: a list that will be filled in with any outputs of
1152                      compilation (to be used in link lines)
1153     part_of_all: flag indicating this target is part of 'all'
1154     """
1155
1156     # Write configuration-specific variables for CFLAGS, etc.
1157     for configname in sorted(configs.keys()):
1158       config = configs[configname]
1159       self.WriteList(config.get('defines'), 'DEFS_%s' % configname, prefix='-D',
1160           quoter=EscapeCppDefine)
1161
1162       if self.flavor == 'mac':
1163         cflags = self.xcode_settings.GetCflags(configname)
1164         cflags_c = self.xcode_settings.GetCflagsC(configname)
1165         cflags_cc = self.xcode_settings.GetCflagsCC(configname)
1166         cflags_objc = self.xcode_settings.GetCflagsObjC(configname)
1167         cflags_objcc = self.xcode_settings.GetCflagsObjCC(configname)
1168       else:
1169         cflags = config.get('cflags')
1170         cflags_c = config.get('cflags_c')
1171         cflags_cc = config.get('cflags_cc')
1172
1173       self.WriteLn("# Flags passed to all source files.");
1174       self.WriteList(cflags, 'CFLAGS_%s' % configname)
1175       self.WriteLn("# Flags passed to only C files.");
1176       self.WriteList(cflags_c, 'CFLAGS_C_%s' % configname)
1177       self.WriteLn("# Flags passed to only C++ files.");
1178       self.WriteList(cflags_cc, 'CFLAGS_CC_%s' % configname)
1179       if self.flavor == 'mac':
1180         self.WriteLn("# Flags passed to only ObjC files.");
1181         self.WriteList(cflags_objc, 'CFLAGS_OBJC_%s' % configname)
1182         self.WriteLn("# Flags passed to only ObjC++ files.");
1183         self.WriteList(cflags_objcc, 'CFLAGS_OBJCC_%s' % configname)
1184       includes = config.get('include_dirs')
1185       if includes:
1186         includes = map(Sourceify, map(self.Absolutify, includes))
1187       self.WriteList(includes, 'INCS_%s' % configname, prefix='-I')
1188
1189     compilable = filter(Compilable, sources)
1190     objs = map(self.Objectify, map(self.Absolutify, map(Target, compilable)))
1191     self.WriteList(objs, 'OBJS')
1192
1193     for obj in objs:
1194       assert ' ' not in obj, (
1195           "Spaces in object filenames not supported (%s)"  % obj)
1196     self.WriteLn('# Add to the list of files we specially track '
1197                  'dependencies for.')
1198     self.WriteLn('all_deps += $(OBJS)')
1199     self.WriteLn()
1200
1201     # Make sure our dependencies are built first.
1202     if deps:
1203       self.WriteMakeRule(['$(OBJS)'], deps,
1204                          comment = 'Make sure our dependencies are built '
1205                                    'before any of us.',
1206                          order_only = True)
1207
1208     # Make sure the actions and rules run first.
1209     # If they generate any extra headers etc., the per-.o file dep tracking
1210     # will catch the proper rebuilds, so order only is still ok here.
1211     if extra_outputs:
1212       self.WriteMakeRule(['$(OBJS)'], extra_outputs,
1213                          comment = 'Make sure our actions/rules run '
1214                                    'before any of us.',
1215                          order_only = True)
1216
1217     pchdeps = precompiled_header.GetObjDependencies(compilable, objs )
1218     if pchdeps:
1219       self.WriteLn('# Dependencies from obj files to their precompiled headers')
1220       for source, obj, gch in pchdeps:
1221         self.WriteLn('%s: %s' % (obj, gch))
1222       self.WriteLn('# End precompiled header dependencies')
1223
1224     if objs:
1225       extra_link_deps.append('$(OBJS)')
1226       self.WriteLn("""\
1227 # CFLAGS et al overrides must be target-local.
1228 # See "Target-specific Variable Values" in the GNU Make manual.""")
1229       self.WriteLn("$(OBJS): TOOLSET := $(TOOLSET)")
1230       self.WriteLn("$(OBJS): GYP_CFLAGS := "
1231                    "$(DEFS_$(BUILDTYPE)) "
1232                    "$(INCS_$(BUILDTYPE)) "
1233                    "%s " % precompiled_header.GetInclude('c') +
1234                    "$(CFLAGS_$(BUILDTYPE)) "
1235                    "$(CFLAGS_C_$(BUILDTYPE))")
1236       self.WriteLn("$(OBJS): GYP_CXXFLAGS := "
1237                    "$(DEFS_$(BUILDTYPE)) "
1238                    "$(INCS_$(BUILDTYPE)) "
1239                    "%s " % precompiled_header.GetInclude('cc') +
1240                    "$(CFLAGS_$(BUILDTYPE)) "
1241                    "$(CFLAGS_CC_$(BUILDTYPE))")
1242       if self.flavor == 'mac':
1243         self.WriteLn("$(OBJS): GYP_OBJCFLAGS := "
1244                      "$(DEFS_$(BUILDTYPE)) "
1245                      "$(INCS_$(BUILDTYPE)) "
1246                      "%s " % precompiled_header.GetInclude('m') +
1247                      "$(CFLAGS_$(BUILDTYPE)) "
1248                      "$(CFLAGS_C_$(BUILDTYPE)) "
1249                      "$(CFLAGS_OBJC_$(BUILDTYPE))")
1250         self.WriteLn("$(OBJS): GYP_OBJCXXFLAGS := "
1251                      "$(DEFS_$(BUILDTYPE)) "
1252                      "$(INCS_$(BUILDTYPE)) "
1253                      "%s " % precompiled_header.GetInclude('mm') +
1254                      "$(CFLAGS_$(BUILDTYPE)) "
1255                      "$(CFLAGS_CC_$(BUILDTYPE)) "
1256                      "$(CFLAGS_OBJCC_$(BUILDTYPE))")
1257
1258     self.WritePchTargets(precompiled_header.GetPchBuildCommands())
1259
1260     # If there are any object files in our input file list, link them into our
1261     # output.
1262     extra_link_deps += filter(Linkable, sources)
1263
1264     self.WriteLn()
1265
1266   def WritePchTargets(self, pch_commands):
1267     """Writes make rules to compile prefix headers."""
1268     if not pch_commands:
1269       return
1270
1271     for gch, lang_flag, lang, input in pch_commands:
1272       extra_flags = {
1273         'c': '$(CFLAGS_C_$(BUILDTYPE))',
1274         'cc': '$(CFLAGS_CC_$(BUILDTYPE))',
1275         'm': '$(CFLAGS_C_$(BUILDTYPE)) $(CFLAGS_OBJC_$(BUILDTYPE))',
1276         'mm': '$(CFLAGS_CC_$(BUILDTYPE)) $(CFLAGS_OBJCC_$(BUILDTYPE))',
1277       }[lang]
1278       var_name = {
1279         'c': 'GYP_PCH_CFLAGS',
1280         'cc': 'GYP_PCH_CXXFLAGS',
1281         'm': 'GYP_PCH_OBJCFLAGS',
1282         'mm': 'GYP_PCH_OBJCXXFLAGS',
1283       }[lang]
1284       self.WriteLn("%s: %s := %s " % (gch, var_name, lang_flag) +
1285                    "$(DEFS_$(BUILDTYPE)) "
1286                    "$(INCS_$(BUILDTYPE)) "
1287                    "$(CFLAGS_$(BUILDTYPE)) " +
1288                    extra_flags)
1289
1290       self.WriteLn('%s: %s FORCE_DO_CMD' % (gch, input))
1291       self.WriteLn('\t@$(call do_cmd,pch_%s,1)' % lang)
1292       self.WriteLn('')
1293       assert ' ' not in gch, (
1294           "Spaces in gch filenames not supported (%s)"  % gch)
1295       self.WriteLn('all_deps += %s' % gch)
1296       self.WriteLn('')
1297
1298
1299   def ComputeOutputBasename(self, spec):
1300     """Return the 'output basename' of a gyp spec.
1301
1302     E.g., the loadable module 'foobar' in directory 'baz' will produce
1303       'libfoobar.so'
1304     """
1305     assert not self.is_mac_bundle
1306
1307     if self.flavor == 'mac' and self.type in (
1308         'static_library', 'executable', 'shared_library', 'loadable_module'):
1309       return self.xcode_settings.GetExecutablePath()
1310
1311     target = spec['target_name']
1312     target_prefix = ''
1313     target_ext = ''
1314     if self.type == 'static_library':
1315       if target[:3] == 'lib':
1316         target = target[3:]
1317       target_prefix = 'lib'
1318       target_ext = '.a'
1319     elif self.type in ('loadable_module', 'shared_library'):
1320       if target[:3] == 'lib':
1321         target = target[3:]
1322       target_prefix = 'lib'
1323       target_ext = '.so'
1324     elif self.type == 'none':
1325       target = '%s.stamp' % target
1326     elif self.type != 'executable':
1327       print ("ERROR: What output file should be generated?",
1328              "type", self.type, "target", target)
1329
1330     target_prefix = spec.get('product_prefix', target_prefix)
1331     target = spec.get('product_name', target)
1332     product_ext = spec.get('product_extension')
1333     if product_ext:
1334       target_ext = '.' + product_ext
1335
1336     return target_prefix + target + target_ext
1337
1338
1339   def _InstallImmediately(self):
1340     return self.toolset == 'target' and self.flavor == 'mac' and self.type in (
1341           'static_library', 'executable', 'shared_library', 'loadable_module')
1342
1343
1344   def ComputeOutput(self, spec):
1345     """Return the 'output' (full output path) of a gyp spec.
1346
1347     E.g., the loadable module 'foobar' in directory 'baz' will produce
1348       '$(obj)/baz/libfoobar.so'
1349     """
1350     assert not self.is_mac_bundle
1351
1352     path = os.path.join('$(obj).' + self.toolset, self.path)
1353     if self.type == 'executable' or self._InstallImmediately():
1354       path = '$(builddir)'
1355     path = spec.get('product_dir', path)
1356     return os.path.join(path, self.ComputeOutputBasename(spec))
1357
1358
1359   def ComputeMacBundleOutput(self, spec):
1360     """Return the 'output' (full output path) to a bundle output directory."""
1361     assert self.is_mac_bundle
1362     path = generator_default_variables['PRODUCT_DIR']
1363     return os.path.join(path, self.xcode_settings.GetWrapperName())
1364
1365
1366   def ComputeMacBundleBinaryOutput(self, spec):
1367     """Return the 'output' (full output path) to the binary in a bundle."""
1368     path = generator_default_variables['PRODUCT_DIR']
1369     return os.path.join(path, self.xcode_settings.GetExecutablePath())
1370
1371
1372   def ComputeDeps(self, spec):
1373     """Compute the dependencies of a gyp spec.
1374
1375     Returns a tuple (deps, link_deps), where each is a list of
1376     filenames that will need to be put in front of make for either
1377     building (deps) or linking (link_deps).
1378     """
1379     deps = []
1380     link_deps = []
1381     if 'dependencies' in spec:
1382       deps.extend([target_outputs[dep] for dep in spec['dependencies']
1383                    if target_outputs[dep]])
1384       for dep in spec['dependencies']:
1385         if dep in target_link_deps:
1386           link_deps.append(target_link_deps[dep])
1387       deps.extend(link_deps)
1388       # TODO: It seems we need to transitively link in libraries (e.g. -lfoo)?
1389       # This hack makes it work:
1390       # link_deps.extend(spec.get('libraries', []))
1391     return (gyp.common.uniquer(deps), gyp.common.uniquer(link_deps))
1392
1393
1394   def WriteDependencyOnExtraOutputs(self, target, extra_outputs):
1395     self.WriteMakeRule([self.output_binary], extra_outputs,
1396                        comment = 'Build our special outputs first.',
1397                        order_only = True)
1398
1399
1400   def WriteTarget(self, spec, configs, deps, link_deps, bundle_deps,
1401                   extra_outputs, part_of_all):
1402     """Write Makefile code to produce the final target of the gyp spec.
1403
1404     spec, configs: input from gyp.
1405     deps, link_deps: dependency lists; see ComputeDeps()
1406     extra_outputs: any extra outputs that our target should depend on
1407     part_of_all: flag indicating this target is part of 'all'
1408     """
1409
1410     self.WriteLn('### Rules for final target.')
1411
1412     if extra_outputs:
1413       self.WriteDependencyOnExtraOutputs(self.output_binary, extra_outputs)
1414       self.WriteMakeRule(extra_outputs, deps,
1415                          comment=('Preserve order dependency of '
1416                                   'special output on deps.'),
1417                          order_only = True)
1418
1419     target_postbuilds = {}
1420     if self.type != 'none':
1421       for configname in sorted(configs.keys()):
1422         config = configs[configname]
1423         if self.flavor == 'mac':
1424           ldflags = self.xcode_settings.GetLdflags(configname,
1425               generator_default_variables['PRODUCT_DIR'],
1426               lambda p: Sourceify(self.Absolutify(p)))
1427
1428           # TARGET_POSTBUILDS_$(BUILDTYPE) is added to postbuilds later on.
1429           gyp_to_build = gyp.common.InvertRelativePath(self.path)
1430           target_postbuild = self.xcode_settings.AddImplicitPostbuilds(
1431               configname,
1432               QuoteSpaces(os.path.normpath(os.path.join(gyp_to_build,
1433                                                         self.output))),
1434               QuoteSpaces(os.path.normpath(os.path.join(gyp_to_build,
1435                                                         self.output_binary))))
1436           if target_postbuild:
1437             target_postbuilds[configname] = target_postbuild
1438         else:
1439           ldflags = config.get('ldflags', [])
1440           # Compute an rpath for this output if needed.
1441           if any(dep.endswith('.so') or '.so.' in dep for dep in deps):
1442             # We want to get the literal string "$ORIGIN" into the link command,
1443             # so we need lots of escaping.
1444             ldflags.append(r'-Wl,-rpath=\$$ORIGIN/lib.%s/' % self.toolset)
1445             ldflags.append(r'-Wl,-rpath-link=\$(builddir)/lib.%s/' %
1446                            self.toolset)
1447         library_dirs = config.get('library_dirs', [])
1448         ldflags += [('-L%s' % library_dir) for library_dir in library_dirs]
1449         self.WriteList(ldflags, 'LDFLAGS_%s' % configname)
1450         if self.flavor == 'mac':
1451           self.WriteList(self.xcode_settings.GetLibtoolflags(configname),
1452                          'LIBTOOLFLAGS_%s' % configname)
1453       libraries = spec.get('libraries')
1454       if libraries:
1455         # Remove duplicate entries
1456         libraries = gyp.common.uniquer(libraries)
1457         if self.flavor == 'mac':
1458           libraries = self.xcode_settings.AdjustLibraries(libraries)
1459       self.WriteList(libraries, 'LIBS')
1460       self.WriteLn('%s: GYP_LDFLAGS := $(LDFLAGS_$(BUILDTYPE))' %
1461           QuoteSpaces(self.output_binary))
1462       self.WriteLn('%s: LIBS := $(LIBS)' % QuoteSpaces(self.output_binary))
1463
1464       if self.flavor == 'mac':
1465         self.WriteLn('%s: GYP_LIBTOOLFLAGS := $(LIBTOOLFLAGS_$(BUILDTYPE))' %
1466             QuoteSpaces(self.output_binary))
1467
1468     # Postbuild actions. Like actions, but implicitly depend on the target's
1469     # output.
1470     postbuilds = []
1471     if self.flavor == 'mac':
1472       if target_postbuilds:
1473         postbuilds.append('$(TARGET_POSTBUILDS_$(BUILDTYPE))')
1474       postbuilds.extend(
1475           gyp.xcode_emulation.GetSpecPostbuildCommands(spec))
1476
1477     if postbuilds:
1478       # Envvars may be referenced by TARGET_POSTBUILDS_$(BUILDTYPE),
1479       # so we must output its definition first, since we declare variables
1480       # using ":=".
1481       self.WriteSortedXcodeEnv(self.output, self.GetSortedXcodePostbuildEnv())
1482
1483       for configname in target_postbuilds:
1484         self.WriteLn('%s: TARGET_POSTBUILDS_%s := %s' %
1485             (QuoteSpaces(self.output),
1486              configname,
1487              gyp.common.EncodePOSIXShellList(target_postbuilds[configname])))
1488
1489       # Postbuilds expect to be run in the gyp file's directory, so insert an
1490       # implicit postbuild to cd to there.
1491       postbuilds.insert(0, gyp.common.EncodePOSIXShellList(['cd', self.path]))
1492       for i in xrange(len(postbuilds)):
1493         if not postbuilds[i].startswith('$'):
1494           postbuilds[i] = EscapeShellArgument(postbuilds[i])
1495       self.WriteLn('%s: builddir := $(abs_builddir)' % QuoteSpaces(self.output))
1496       self.WriteLn('%s: POSTBUILDS := %s' % (
1497           QuoteSpaces(self.output), ' '.join(postbuilds)))
1498
1499     # A bundle directory depends on its dependencies such as bundle resources
1500     # and bundle binary. When all dependencies have been built, the bundle
1501     # needs to be packaged.
1502     if self.is_mac_bundle:
1503       # If the framework doesn't contain a binary, then nothing depends
1504       # on the actions -- make the framework depend on them directly too.
1505       self.WriteDependencyOnExtraOutputs(self.output, extra_outputs)
1506
1507       # Bundle dependencies. Note that the code below adds actions to this
1508       # target, so if you move these two lines, move the lines below as well.
1509       self.WriteList(map(QuoteSpaces, bundle_deps), 'BUNDLE_DEPS')
1510       self.WriteLn('%s: $(BUNDLE_DEPS)' % QuoteSpaces(self.output))
1511
1512       # After the framework is built, package it. Needs to happen before
1513       # postbuilds, since postbuilds depend on this.
1514       if self.type in ('shared_library', 'loadable_module'):
1515         self.WriteLn('\t@$(call do_cmd,mac_package_framework,,,%s)' %
1516             self.xcode_settings.GetFrameworkVersion())
1517
1518       # Bundle postbuilds can depend on the whole bundle, so run them after
1519       # the bundle is packaged, not already after the bundle binary is done.
1520       if postbuilds:
1521         self.WriteLn('\t@$(call do_postbuilds)')
1522       postbuilds = []  # Don't write postbuilds for target's output.
1523
1524       # Needed by test/mac/gyptest-rebuild.py.
1525       self.WriteLn('\t@true  # No-op, used by tests')
1526
1527       # Since this target depends on binary and resources which are in
1528       # nested subfolders, the framework directory will be older than
1529       # its dependencies usually. To prevent this rule from executing
1530       # on every build (expensive, especially with postbuilds), expliclity
1531       # update the time on the framework directory.
1532       self.WriteLn('\t@touch -c %s' % QuoteSpaces(self.output))
1533
1534     if postbuilds:
1535       assert not self.is_mac_bundle, ('Postbuilds for bundles should be done '
1536           'on the bundle, not the binary (target \'%s\')' % self.target)
1537       assert 'product_dir' not in spec, ('Postbuilds do not work with '
1538           'custom product_dir')
1539
1540     if self.type == 'executable':
1541       self.WriteLn('%s: LD_INPUTS := %s' % (
1542           QuoteSpaces(self.output_binary),
1543           ' '.join(map(QuoteSpaces, link_deps))))
1544       if self.toolset == 'host' and self.flavor == 'android':
1545         self.WriteDoCmd([self.output_binary], link_deps, 'link_host',
1546                         part_of_all, postbuilds=postbuilds)
1547       else:
1548         self.WriteDoCmd([self.output_binary], link_deps, 'link', part_of_all,
1549                         postbuilds=postbuilds)
1550
1551     elif self.type == 'static_library':
1552       for link_dep in link_deps:
1553         assert ' ' not in link_dep, (
1554             "Spaces in alink input filenames not supported (%s)"  % link_dep)
1555       if (self.flavor not in ('mac', 'openbsd', 'win') and not
1556           self.is_standalone_static_library):
1557         self.WriteDoCmd([self.output_binary], link_deps, 'alink_thin',
1558                         part_of_all, postbuilds=postbuilds)
1559       else:
1560         self.WriteDoCmd([self.output_binary], link_deps, 'alink', part_of_all,
1561                         postbuilds=postbuilds)
1562     elif self.type == 'shared_library':
1563       self.WriteLn('%s: LD_INPUTS := %s' % (
1564             QuoteSpaces(self.output_binary),
1565             ' '.join(map(QuoteSpaces, link_deps))))
1566       self.WriteDoCmd([self.output_binary], link_deps, 'solink', part_of_all,
1567                       postbuilds=postbuilds)
1568     elif self.type == 'loadable_module':
1569       for link_dep in link_deps:
1570         assert ' ' not in link_dep, (
1571             "Spaces in module input filenames not supported (%s)"  % link_dep)
1572       if self.toolset == 'host' and self.flavor == 'android':
1573         self.WriteDoCmd([self.output_binary], link_deps, 'solink_module_host',
1574                         part_of_all, postbuilds=postbuilds)
1575       else:
1576         self.WriteDoCmd(
1577             [self.output_binary], link_deps, 'solink_module', part_of_all,
1578             postbuilds=postbuilds)
1579     elif self.type == 'none':
1580       # Write a stamp line.
1581       self.WriteDoCmd([self.output_binary], deps, 'touch', part_of_all,
1582                       postbuilds=postbuilds)
1583     else:
1584       print "WARNING: no output for", self.type, target
1585
1586     # Add an alias for each target (if there are any outputs).
1587     # Installable target aliases are created below.
1588     if ((self.output and self.output != self.target) and
1589         (self.type not in self._INSTALLABLE_TARGETS)):
1590       self.WriteMakeRule([self.target], [self.output],
1591                          comment='Add target alias', phony = True)
1592       if part_of_all:
1593         self.WriteMakeRule(['all'], [self.target],
1594                            comment = 'Add target alias to "all" target.',
1595                            phony = True)
1596
1597     # Add special-case rules for our installable targets.
1598     # 1) They need to install to the build dir or "product" dir.
1599     # 2) They get shortcuts for building (e.g. "make chrome").
1600     # 3) They are part of "make all".
1601     if (self.type in self._INSTALLABLE_TARGETS or
1602         self.is_standalone_static_library):
1603       if self.type == 'shared_library':
1604         file_desc = 'shared library'
1605       elif self.type == 'static_library':
1606         file_desc = 'static library'
1607       else:
1608         file_desc = 'executable'
1609       install_path = self._InstallableTargetInstallPath()
1610       installable_deps = [self.output]
1611       if (self.flavor == 'mac' and not 'product_dir' in spec and
1612           self.toolset == 'target'):
1613         # On mac, products are created in install_path immediately.
1614         assert install_path == self.output, '%s != %s' % (
1615             install_path, self.output)
1616
1617       # Point the target alias to the final binary output.
1618       self.WriteMakeRule([self.target], [install_path],
1619                          comment='Add target alias', phony = True)
1620       if install_path != self.output:
1621         assert not self.is_mac_bundle  # See comment a few lines above.
1622         self.WriteDoCmd([install_path], [self.output], 'copy',
1623                         comment = 'Copy this to the %s output path.' %
1624                         file_desc, part_of_all=part_of_all)
1625         installable_deps.append(install_path)
1626       if self.output != self.alias and self.alias != self.target:
1627         self.WriteMakeRule([self.alias], installable_deps,
1628                            comment = 'Short alias for building this %s.' %
1629                            file_desc, phony = True)
1630       if part_of_all:
1631         self.WriteMakeRule(['all'], [install_path],
1632                            comment = 'Add %s to "all" target.' % file_desc,
1633                            phony = True)
1634
1635
1636   def WriteList(self, value_list, variable=None, prefix='',
1637                 quoter=QuoteIfNecessary):
1638     """Write a variable definition that is a list of values.
1639
1640     E.g. WriteList(['a','b'], 'foo', prefix='blah') writes out
1641          foo = blaha blahb
1642     but in a pretty-printed style.
1643     """
1644     values = ''
1645     if value_list:
1646       value_list = [quoter(prefix + l) for l in value_list]
1647       values = ' \\\n\t' + ' \\\n\t'.join(value_list)
1648     self.fp.write('%s :=%s\n\n' % (variable, values))
1649
1650
1651   def WriteDoCmd(self, outputs, inputs, command, part_of_all, comment=None,
1652                  postbuilds=False):
1653     """Write a Makefile rule that uses do_cmd.
1654
1655     This makes the outputs dependent on the command line that was run,
1656     as well as support the V= make command line flag.
1657     """
1658     suffix = ''
1659     if postbuilds:
1660       assert ',' not in command
1661       suffix = ',,1'  # Tell do_cmd to honor $POSTBUILDS
1662     self.WriteMakeRule(outputs, inputs,
1663                        actions = ['$(call do_cmd,%s%s)' % (command, suffix)],
1664                        comment = comment,
1665                        force = True)
1666     # Add our outputs to the list of targets we read depfiles from.
1667     # all_deps is only used for deps file reading, and for deps files we replace
1668     # spaces with ? because escaping doesn't work with make's $(sort) and
1669     # other functions.
1670     outputs = [QuoteSpaces(o, SPACE_REPLACEMENT) for o in outputs]
1671     self.WriteLn('all_deps += %s' % ' '.join(outputs))
1672
1673
1674   def WriteMakeRule(self, outputs, inputs, actions=None, comment=None,
1675                     order_only=False, force=False, phony=False):
1676     """Write a Makefile rule, with some extra tricks.
1677
1678     outputs: a list of outputs for the rule (note: this is not directly
1679              supported by make; see comments below)
1680     inputs: a list of inputs for the rule
1681     actions: a list of shell commands to run for the rule
1682     comment: a comment to put in the Makefile above the rule (also useful
1683              for making this Python script's code self-documenting)
1684     order_only: if true, makes the dependency order-only
1685     force: if true, include FORCE_DO_CMD as an order-only dep
1686     phony: if true, the rule does not actually generate the named output, the
1687            output is just a name to run the rule
1688     """
1689     outputs = map(QuoteSpaces, outputs)
1690     inputs = map(QuoteSpaces, inputs)
1691
1692     if comment:
1693       self.WriteLn('# ' + comment)
1694     if phony:
1695       self.WriteLn('.PHONY: ' + ' '.join(outputs))
1696     # TODO(evanm): just make order_only a list of deps instead of these hacks.
1697     if order_only:
1698       order_insert = '| '
1699       pick_output = ' '.join(outputs)
1700     else:
1701       order_insert = ''
1702       pick_output = outputs[0]
1703     if force:
1704       force_append = ' FORCE_DO_CMD'
1705     else:
1706       force_append = ''
1707     if actions:
1708       self.WriteLn("%s: TOOLSET := $(TOOLSET)" % outputs[0])
1709     self.WriteLn('%s: %s%s%s' % (pick_output, order_insert, ' '.join(inputs),
1710                                  force_append))
1711     if actions:
1712       for action in actions:
1713         self.WriteLn('\t%s' % action)
1714     if not order_only and len(outputs) > 1:
1715       # If we have more than one output, a rule like
1716       #   foo bar: baz
1717       # that for *each* output we must run the action, potentially
1718       # in parallel.  That is not what we're trying to write -- what
1719       # we want is that we run the action once and it generates all
1720       # the files.
1721       # http://www.gnu.org/software/hello/manual/automake/Multiple-Outputs.html
1722       # discusses this problem and has this solution:
1723       # 1) Write the naive rule that would produce parallel runs of
1724       # the action.
1725       # 2) Make the outputs seralized on each other, so we won't start
1726       # a parallel run until the first run finishes, at which point
1727       # we'll have generated all the outputs and we're done.
1728       self.WriteLn('%s: %s' % (' '.join(outputs[1:]), outputs[0]))
1729       # Add a dummy command to the "extra outputs" rule, otherwise make seems to
1730       # think these outputs haven't (couldn't have?) changed, and thus doesn't
1731       # flag them as changed (i.e. include in '$?') when evaluating dependent
1732       # rules, which in turn causes do_cmd() to skip running dependent commands.
1733       self.WriteLn('%s: ;' % (' '.join(outputs[1:])))
1734     self.WriteLn()
1735
1736
1737   def WriteAndroidNdkModuleRule(self, module_name, all_sources, link_deps):
1738     """Write a set of LOCAL_XXX definitions for Android NDK.
1739
1740     These variable definitions will be used by Android NDK but do nothing for
1741     non-Android applications.
1742
1743     Arguments:
1744       module_name: Android NDK module name, which must be unique among all
1745           module names.
1746       all_sources: A list of source files (will be filtered by Compilable).
1747       link_deps: A list of link dependencies, which must be sorted in
1748           the order from dependencies to dependents.
1749     """
1750     if self.type not in ('executable', 'shared_library', 'static_library'):
1751       return
1752
1753     self.WriteLn('# Variable definitions for Android applications')
1754     self.WriteLn('include $(CLEAR_VARS)')
1755     self.WriteLn('LOCAL_MODULE := ' + module_name)
1756     self.WriteLn('LOCAL_CFLAGS := $(CFLAGS_$(BUILDTYPE)) '
1757                  '$(DEFS_$(BUILDTYPE)) '
1758                  # LOCAL_CFLAGS is applied to both of C and C++.  There is
1759                  # no way to specify $(CFLAGS_C_$(BUILDTYPE)) only for C
1760                  # sources.
1761                  '$(CFLAGS_C_$(BUILDTYPE)) '
1762                  # $(INCS_$(BUILDTYPE)) includes the prefix '-I' while
1763                  # LOCAL_C_INCLUDES does not expect it.  So put it in
1764                  # LOCAL_CFLAGS.
1765                  '$(INCS_$(BUILDTYPE))')
1766     # LOCAL_CXXFLAGS is obsolete and LOCAL_CPPFLAGS is preferred.
1767     self.WriteLn('LOCAL_CPPFLAGS := $(CFLAGS_CC_$(BUILDTYPE))')
1768     self.WriteLn('LOCAL_C_INCLUDES :=')
1769     self.WriteLn('LOCAL_LDLIBS := $(LDFLAGS_$(BUILDTYPE)) $(LIBS)')
1770
1771     # Detect the C++ extension.
1772     cpp_ext = {'.cc': 0, '.cpp': 0, '.cxx': 0}
1773     default_cpp_ext = '.cpp'
1774     for filename in all_sources:
1775       ext = os.path.splitext(filename)[1]
1776       if ext in cpp_ext:
1777         cpp_ext[ext] += 1
1778         if cpp_ext[ext] > cpp_ext[default_cpp_ext]:
1779           default_cpp_ext = ext
1780     self.WriteLn('LOCAL_CPP_EXTENSION := ' + default_cpp_ext)
1781
1782     self.WriteList(map(self.Absolutify, filter(Compilable, all_sources)),
1783                    'LOCAL_SRC_FILES')
1784
1785     # Filter out those which do not match prefix and suffix and produce
1786     # the resulting list without prefix and suffix.
1787     def DepsToModules(deps, prefix, suffix):
1788       modules = []
1789       for filepath in deps:
1790         filename = os.path.basename(filepath)
1791         if filename.startswith(prefix) and filename.endswith(suffix):
1792           modules.append(filename[len(prefix):-len(suffix)])
1793       return modules
1794
1795     # Retrieve the default value of 'SHARED_LIB_SUFFIX'
1796     params = {'flavor': 'linux'}
1797     default_variables = {}
1798     CalculateVariables(default_variables, params)
1799
1800     self.WriteList(
1801         DepsToModules(link_deps,
1802                       generator_default_variables['SHARED_LIB_PREFIX'],
1803                       default_variables['SHARED_LIB_SUFFIX']),
1804         'LOCAL_SHARED_LIBRARIES')
1805     self.WriteList(
1806         DepsToModules(link_deps,
1807                       generator_default_variables['STATIC_LIB_PREFIX'],
1808                       generator_default_variables['STATIC_LIB_SUFFIX']),
1809         'LOCAL_STATIC_LIBRARIES')
1810
1811     if self.type == 'executable':
1812       self.WriteLn('include $(BUILD_EXECUTABLE)')
1813     elif self.type == 'shared_library':
1814       self.WriteLn('include $(BUILD_SHARED_LIBRARY)')
1815     elif self.type == 'static_library':
1816       self.WriteLn('include $(BUILD_STATIC_LIBRARY)')
1817     self.WriteLn()
1818
1819
1820   def WriteLn(self, text=''):
1821     self.fp.write(text + '\n')
1822
1823
1824   def GetSortedXcodeEnv(self, additional_settings=None):
1825     return gyp.xcode_emulation.GetSortedXcodeEnv(
1826         self.xcode_settings, "$(abs_builddir)",
1827         os.path.join("$(abs_srcdir)", self.path), "$(BUILDTYPE)",
1828         additional_settings)
1829
1830
1831   def GetSortedXcodePostbuildEnv(self):
1832     # CHROMIUM_STRIP_SAVE_FILE is a chromium-specific hack.
1833     # TODO(thakis): It would be nice to have some general mechanism instead.
1834     strip_save_file = self.xcode_settings.GetPerTargetSetting(
1835         'CHROMIUM_STRIP_SAVE_FILE', '')
1836     # Even if strip_save_file is empty, explicitly write it. Else a postbuild
1837     # might pick up an export from an earlier target.
1838     return self.GetSortedXcodeEnv(
1839         additional_settings={'CHROMIUM_STRIP_SAVE_FILE': strip_save_file})
1840
1841
1842   def WriteSortedXcodeEnv(self, target, env):
1843     for k, v in env:
1844       # For
1845       #  foo := a\ b
1846       # the escaped space does the right thing. For
1847       #  export foo := a\ b
1848       # it does not -- the backslash is written to the env as literal character.
1849       # So don't escape spaces in |env[k]|.
1850       self.WriteLn('%s: export %s := %s' % (QuoteSpaces(target), k, v))
1851
1852
1853   def Objectify(self, path):
1854     """Convert a path to its output directory form."""
1855     if '$(' in path:
1856       path = path.replace('$(obj)/', '$(obj).%s/$(TARGET)/' % self.toolset)
1857     if not '$(obj)' in path:
1858       path = '$(obj).%s/$(TARGET)/%s' % (self.toolset, path)
1859     return path
1860
1861
1862   def Pchify(self, path, lang):
1863     """Convert a prefix header path to its output directory form."""
1864     path = self.Absolutify(path)
1865     if '$(' in path:
1866       path = path.replace('$(obj)/', '$(obj).%s/$(TARGET)/pch-%s' %
1867                           (self.toolset, lang))
1868       return path
1869     return '$(obj).%s/$(TARGET)/pch-%s/%s' % (self.toolset, lang, path)
1870
1871
1872   def Absolutify(self, path):
1873     """Convert a subdirectory-relative path into a base-relative path.
1874     Skips over paths that contain variables."""
1875     if '$(' in path:
1876       # Don't call normpath in this case, as it might collapse the
1877       # path too aggressively if it features '..'. However it's still
1878       # important to strip trailing slashes.
1879       return path.rstrip('/')
1880     return os.path.normpath(os.path.join(self.path, path))
1881
1882
1883   def ExpandInputRoot(self, template, expansion, dirname):
1884     if '%(INPUT_ROOT)s' not in template and '%(INPUT_DIRNAME)s' not in template:
1885       return template
1886     path = template % {
1887         'INPUT_ROOT': expansion,
1888         'INPUT_DIRNAME': dirname,
1889         }
1890     return path
1891
1892
1893   def _InstallableTargetInstallPath(self):
1894     """Returns the location of the final output for an installable target."""
1895     # Xcode puts shared_library results into PRODUCT_DIR, and some gyp files
1896     # rely on this. Emulate this behavior for mac.
1897     if (self.type == 'shared_library' and
1898         (self.flavor != 'mac' or self.toolset != 'target')):
1899       # Install all shared libs into a common directory (per toolset) for
1900       # convenient access with LD_LIBRARY_PATH.
1901       return '$(builddir)/lib.%s/%s' % (self.toolset, self.alias)
1902     return '$(builddir)/' + self.alias
1903
1904
1905 def WriteAutoRegenerationRule(params, root_makefile, makefile_name,
1906                               build_files):
1907   """Write the target to regenerate the Makefile."""
1908   options = params['options']
1909   build_files_args = [gyp.common.RelativePath(filename, options.toplevel_dir)
1910                       for filename in params['build_files_arg']]
1911
1912   gyp_binary = gyp.common.FixIfRelativePath(params['gyp_binary'],
1913                                             options.toplevel_dir)
1914   if not gyp_binary.startswith(os.sep):
1915     gyp_binary = os.path.join('.', gyp_binary)
1916
1917   root_makefile.write(
1918       "quiet_cmd_regen_makefile = ACTION Regenerating $@\n"
1919       "cmd_regen_makefile = cd $(srcdir); %(cmd)s\n"
1920       "%(makefile_name)s: %(deps)s\n"
1921       "\t$(call do_cmd,regen_makefile)\n\n" % {
1922           'makefile_name': makefile_name,
1923           'deps': ' '.join(map(Sourceify, build_files)),
1924           'cmd': gyp.common.EncodePOSIXShellList(
1925                      [gyp_binary, '-fmake'] +
1926                      gyp.RegenerateFlags(options) +
1927                      build_files_args)})
1928
1929
1930 def PerformBuild(data, configurations, params):
1931   options = params['options']
1932   for config in configurations:
1933     arguments = ['make']
1934     if options.toplevel_dir and options.toplevel_dir != '.':
1935       arguments += '-C', options.toplevel_dir
1936     arguments.append('BUILDTYPE=' + config)
1937     print 'Building [%s]: %s' % (config, arguments)
1938     subprocess.check_call(arguments)
1939
1940
1941 def GenerateOutput(target_list, target_dicts, data, params):
1942   options = params['options']
1943   flavor = gyp.common.GetFlavor(params)
1944   generator_flags = params.get('generator_flags', {})
1945   builddir_name = generator_flags.get('output_dir', 'out')
1946   android_ndk_version = generator_flags.get('android_ndk_version', None)
1947   default_target = generator_flags.get('default_target', 'all')
1948
1949   def CalculateMakefilePath(build_file, base_name):
1950     """Determine where to write a Makefile for a given gyp file."""
1951     # Paths in gyp files are relative to the .gyp file, but we want
1952     # paths relative to the source root for the master makefile.  Grab
1953     # the path of the .gyp file as the base to relativize against.
1954     # E.g. "foo/bar" when we're constructing targets for "foo/bar/baz.gyp".
1955     base_path = gyp.common.RelativePath(os.path.dirname(build_file),
1956                                         options.depth)
1957     # We write the file in the base_path directory.
1958     output_file = os.path.join(options.depth, base_path, base_name)
1959     if options.generator_output:
1960       output_file = os.path.join(options.generator_output, output_file)
1961     base_path = gyp.common.RelativePath(os.path.dirname(build_file),
1962                                         options.toplevel_dir)
1963     return base_path, output_file
1964
1965   # TODO:  search for the first non-'Default' target.  This can go
1966   # away when we add verification that all targets have the
1967   # necessary configurations.
1968   default_configuration = None
1969   toolsets = set([target_dicts[target]['toolset'] for target in target_list])
1970   for target in target_list:
1971     spec = target_dicts[target]
1972     if spec['default_configuration'] != 'Default':
1973       default_configuration = spec['default_configuration']
1974       break
1975   if not default_configuration:
1976     default_configuration = 'Default'
1977
1978   srcdir = '.'
1979   makefile_name = 'Makefile' + options.suffix
1980   makefile_path = os.path.join(options.toplevel_dir, makefile_name)
1981   if options.generator_output:
1982     global srcdir_prefix
1983     makefile_path = os.path.join(options.generator_output, makefile_path)
1984     srcdir = gyp.common.RelativePath(srcdir, options.generator_output)
1985     srcdir_prefix = '$(srcdir)/'
1986
1987   flock_command= 'flock'
1988   header_params = {
1989       'default_target': default_target,
1990       'builddir': builddir_name,
1991       'default_configuration': default_configuration,
1992       'flock': flock_command,
1993       'flock_index': 1,
1994       'link_commands': LINK_COMMANDS_LINUX,
1995       'extra_commands': '',
1996       'srcdir': srcdir,
1997     }
1998   if flavor == 'mac':
1999     flock_command = './gyp-mac-tool flock'
2000     header_params.update({
2001         'flock': flock_command,
2002         'flock_index': 2,
2003         'link_commands': LINK_COMMANDS_MAC,
2004         'extra_commands': SHARED_HEADER_MAC_COMMANDS,
2005     })
2006   elif flavor == 'android':
2007     header_params.update({
2008         'link_commands': LINK_COMMANDS_ANDROID,
2009     })
2010   elif flavor == 'solaris':
2011     header_params.update({
2012         'flock': './gyp-flock-tool flock',
2013         'flock_index': 2,
2014     })
2015   elif flavor == 'freebsd':
2016     # Note: OpenBSD has sysutils/flock. lockf seems to be FreeBSD specific.
2017     header_params.update({
2018         'flock': 'lockf',
2019     })
2020   elif flavor == 'aix':
2021     header_params.update({
2022         'link_commands': LINK_COMMANDS_AIX,
2023         'flock': './gyp-flock-tool flock',
2024         'flock_index': 2,
2025     })
2026
2027   header_params.update({
2028     'CC.target':   GetEnvironFallback(('CC_target', 'CC'), '$(CC)'),
2029     'AR.target':   GetEnvironFallback(('AR_target', 'AR'), '$(AR)'),
2030     'CXX.target':  GetEnvironFallback(('CXX_target', 'CXX'), '$(CXX)'),
2031     'LINK.target': GetEnvironFallback(('LINK_target', 'LINK'), '$(LINK)'),
2032     'CC.host':     GetEnvironFallback(('CC_host',), 'gcc'),
2033     'AR.host':     GetEnvironFallback(('AR_host',), 'ar'),
2034     'CXX.host':    GetEnvironFallback(('CXX_host',), 'g++'),
2035     'LINK.host':   GetEnvironFallback(('LINK_host',), '$(CXX.host)'),
2036   })
2037
2038   build_file, _, _ = gyp.common.ParseQualifiedTarget(target_list[0])
2039   make_global_settings_array = data[build_file].get('make_global_settings', [])
2040   wrappers = {}
2041   wrappers['LINK'] = '%s $(builddir)/linker.lock' % flock_command
2042   for key, value in make_global_settings_array:
2043     if key.endswith('_wrapper'):
2044       wrappers[key[:-len('_wrapper')]] = '$(abspath %s)' % value
2045   make_global_settings = ''
2046   for key, value in make_global_settings_array:
2047     if re.match('.*_wrapper', key):
2048       continue
2049     if value[0] != '$':
2050       value = '$(abspath %s)' % value
2051     wrapper = wrappers.get(key)
2052     if wrapper:
2053       value = '%s %s' % (wrapper, value)
2054       del wrappers[key]
2055     if key in ('CC', 'CC.host', 'CXX', 'CXX.host'):
2056       make_global_settings += (
2057           'ifneq (,$(filter $(origin %s), undefined default))\n' % key)
2058       # Let gyp-time envvars win over global settings.
2059       if key in os.environ:
2060         value = os.environ[key]
2061       make_global_settings += '  %s = %s\n' % (key, value)
2062       make_global_settings += 'endif\n'
2063     else:
2064       make_global_settings += '%s ?= %s\n' % (key, value)
2065   # TODO(ukai): define cmd when only wrapper is specified in
2066   # make_global_settings.
2067
2068   header_params['make_global_settings'] = make_global_settings
2069
2070   ensure_directory_exists(makefile_path)
2071   root_makefile = open(makefile_path, 'w')
2072   root_makefile.write(SHARED_HEADER % header_params)
2073   # Currently any versions have the same effect, but in future the behavior
2074   # could be different.
2075   if android_ndk_version:
2076     root_makefile.write(
2077         '# Define LOCAL_PATH for build of Android applications.\n'
2078         'LOCAL_PATH := $(call my-dir)\n'
2079         '\n')
2080   for toolset in toolsets:
2081     root_makefile.write('TOOLSET := %s\n' % toolset)
2082     WriteRootHeaderSuffixRules(root_makefile)
2083
2084   # Put build-time support tools next to the root Makefile.
2085   dest_path = os.path.dirname(makefile_path)
2086   gyp.common.CopyTool(flavor, dest_path)
2087
2088   # Find the list of targets that derive from the gyp file(s) being built.
2089   needed_targets = set()
2090   for build_file in params['build_files']:
2091     for target in gyp.common.AllTargets(target_list, target_dicts, build_file):
2092       needed_targets.add(target)
2093
2094   build_files = set()
2095   include_list = set()
2096   for qualified_target in target_list:
2097     build_file, target, toolset = gyp.common.ParseQualifiedTarget(
2098         qualified_target)
2099
2100     this_make_global_settings = data[build_file].get('make_global_settings', [])
2101     assert make_global_settings_array == this_make_global_settings, (
2102         "make_global_settings needs to be the same for all targets.")
2103
2104     build_files.add(gyp.common.RelativePath(build_file, options.toplevel_dir))
2105     included_files = data[build_file]['included_files']
2106     for included_file in included_files:
2107       # The included_files entries are relative to the dir of the build file
2108       # that included them, so we have to undo that and then make them relative
2109       # to the root dir.
2110       relative_include_file = gyp.common.RelativePath(
2111           gyp.common.UnrelativePath(included_file, build_file),
2112           options.toplevel_dir)
2113       abs_include_file = os.path.abspath(relative_include_file)
2114       # If the include file is from the ~/.gyp dir, we should use absolute path
2115       # so that relocating the src dir doesn't break the path.
2116       if (params['home_dot_gyp'] and
2117           abs_include_file.startswith(params['home_dot_gyp'])):
2118         build_files.add(abs_include_file)
2119       else:
2120         build_files.add(relative_include_file)
2121
2122     base_path, output_file = CalculateMakefilePath(build_file,
2123         target + '.' + toolset + options.suffix + '.mk')
2124
2125     spec = target_dicts[qualified_target]
2126     configs = spec['configurations']
2127
2128     if flavor == 'mac':
2129       gyp.xcode_emulation.MergeGlobalXcodeSettingsToSpec(data[build_file], spec)
2130
2131     writer = MakefileWriter(generator_flags, flavor)
2132     writer.Write(qualified_target, base_path, output_file, spec, configs,
2133                  part_of_all=qualified_target in needed_targets)
2134
2135     # Our root_makefile lives at the source root.  Compute the relative path
2136     # from there to the output_file for including.
2137     mkfile_rel_path = gyp.common.RelativePath(output_file,
2138                                               os.path.dirname(makefile_path))
2139     include_list.add(mkfile_rel_path)
2140
2141   # Write out per-gyp (sub-project) Makefiles.
2142   depth_rel_path = gyp.common.RelativePath(options.depth, os.getcwd())
2143   for build_file in build_files:
2144     # The paths in build_files were relativized above, so undo that before
2145     # testing against the non-relativized items in target_list and before
2146     # calculating the Makefile path.
2147     build_file = os.path.join(depth_rel_path, build_file)
2148     gyp_targets = [target_dicts[target]['target_name'] for target in target_list
2149                    if target.startswith(build_file) and
2150                    target in needed_targets]
2151     # Only generate Makefiles for gyp files with targets.
2152     if not gyp_targets:
2153       continue
2154     base_path, output_file = CalculateMakefilePath(build_file,
2155         os.path.splitext(os.path.basename(build_file))[0] + '.Makefile')
2156     makefile_rel_path = gyp.common.RelativePath(os.path.dirname(makefile_path),
2157                                                 os.path.dirname(output_file))
2158     writer.WriteSubMake(output_file, makefile_rel_path, gyp_targets,
2159                         builddir_name)
2160
2161
2162   # Write out the sorted list of includes.
2163   root_makefile.write('\n')
2164   for include_file in sorted(include_list):
2165     # We wrap each .mk include in an if statement so users can tell make to
2166     # not load a file by setting NO_LOAD.  The below make code says, only
2167     # load the .mk file if the .mk filename doesn't start with a token in
2168     # NO_LOAD.
2169     root_makefile.write(
2170         "ifeq ($(strip $(foreach prefix,$(NO_LOAD),\\\n"
2171         "    $(findstring $(join ^,$(prefix)),\\\n"
2172         "                 $(join ^," + include_file + ")))),)\n")
2173     root_makefile.write("  include " + include_file + "\n")
2174     root_makefile.write("endif\n")
2175   root_makefile.write('\n')
2176
2177   if (not generator_flags.get('standalone')
2178       and generator_flags.get('auto_regeneration', True)):
2179     WriteAutoRegenerationRule(params, root_makefile, makefile_name, build_files)
2180
2181   root_makefile.write(SHARED_FOOTER)
2182
2183   root_makefile.close()