# Copyright (c) 2012 Google Inc. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import filecmp
import gyp.common
import gyp.xcodeproj_file
import errno
import os
import sys
import posixpath
import re
import shutil
import subprocess
import tempfile


# Project files generated by this module will use _intermediate_var as a
# custom Xcode setting whose value is a DerivedSources-like directory that's
# project-specific and configuration-specific.  The normal choice,
# DERIVED_FILE_DIR, is target-specific, which is thought to be too restrictive
# as it is likely that multiple targets within a single project file will want
# to access the same set of generated files.  The other option,
# PROJECT_DERIVED_FILE_DIR, is unsuitable because while it is project-specific,
# it is not configuration-specific.  INTERMEDIATE_DIR is defined as
# $(PROJECT_DERIVED_FILE_DIR)/$(CONFIGURATION).
_intermediate_var = 'INTERMEDIATE_DIR'

# SHARED_INTERMEDIATE_DIR is the same, except that it is shared among all
# targets that share the same BUILT_PRODUCTS_DIR.
_shared_intermediate_var = 'SHARED_INTERMEDIATE_DIR'

_library_search_paths_var = 'LIBRARY_SEARCH_PATHS'

generator_default_variables = {
  'EXECUTABLE_PREFIX': '',
  'EXECUTABLE_SUFFIX': '',
  'STATIC_LIB_PREFIX': 'lib',
  'SHARED_LIB_PREFIX': 'lib',
  'STATIC_LIB_SUFFIX': '.a',
  'SHARED_LIB_SUFFIX': '.dylib',
  # INTERMEDIATE_DIR is a place for targets to build up intermediate products.
  # It is specific to each build environment.  It is only guaranteed to exist
  # and be constant within the context of a project, corresponding to a single
  # input file.  Some build environments may allow their intermediate directory
  # to be shared on a wider scale, but this is not guaranteed.
  'INTERMEDIATE_DIR': '$(%s)' % _intermediate_var,
  'OS': 'mac',
  'PRODUCT_DIR': '$(BUILT_PRODUCTS_DIR)',
  'LIB_DIR': '$(BUILT_PRODUCTS_DIR)',
  'RULE_INPUT_ROOT': '$(INPUT_FILE_BASE)',
  'RULE_INPUT_EXT': '$(INPUT_FILE_SUFFIX)',
  'RULE_INPUT_NAME': '$(INPUT_FILE_NAME)',
  'RULE_INPUT_PATH': '$(INPUT_FILE_PATH)',
  'RULE_INPUT_DIRNAME': '$(INPUT_FILE_DIRNAME)',
  'SHARED_INTERMEDIATE_DIR': '$(%s)' % _shared_intermediate_var,
  'CONFIGURATION_NAME': '$(CONFIGURATION)',
}

# The Xcode-specific sections that hold paths.
generator_additional_path_sections = [
  'mac_bundle_resources',
  'mac_framework_headers',
  'mac_framework_private_headers',
  # 'mac_framework_dirs', input already handles _dirs endings.
]

# The Xcode-specific keys that exist on targets and aren't moved down to
# configurations.
generator_additional_non_configuration_keys = [
  'mac_bundle',
  'mac_bundle_resources',
  'mac_framework_headers',
  'mac_framework_private_headers',
  'mac_xctest_bundle',
  'xcode_create_dependents_test_runner',
]

# We want to let any rules apply to files that are resources also.
generator_extra_sources_for_rules = [
  'mac_bundle_resources',
  'mac_framework_headers',
  'mac_framework_private_headers',
]

# Xcode's standard set of library directories, which don't need to be duplicated
# in LIBRARY_SEARCH_PATHS. This list is not exhaustive, but that's okay.
xcode_standard_library_dirs = frozenset([
  '$(SDKROOT)/usr/lib',
  '$(SDKROOT)/usr/local/lib',
])

def CreateXCConfigurationList(configuration_names):
  xccl = gyp.xcodeproj_file.XCConfigurationList({'buildConfigurations': []})
  if len(configuration_names) == 0:
    configuration_names = ['Default']
  for configuration_name in configuration_names:
    xcbc = gyp.xcodeproj_file.XCBuildConfiguration({
        'name': configuration_name})
    xccl.AppendProperty('buildConfigurations', xcbc)
  xccl.SetProperty('defaultConfigurationName', configuration_names[0])
  return xccl


class XcodeProject(object):
  def __init__(self, gyp_path, path, build_file_dict):
    self.gyp_path = gyp_path
    self.path = path
    self.project = gyp.xcodeproj_file.PBXProject(path=path)
    projectDirPath = gyp.common.RelativePath(
                         os.path.dirname(os.path.abspath(self.gyp_path)),
                         os.path.dirname(path) or '.')
    self.project.SetProperty('projectDirPath', projectDirPath)
    self.project_file = \
        gyp.xcodeproj_file.XCProjectFile({'rootObject': self.project})
    self.build_file_dict = build_file_dict

    # TODO(mark): add destructor that cleans up self.path if created_dir is
    # True and things didn't complete successfully.  Or do something even
    # better with "try"?
    self.created_dir = False
    try:
      os.makedirs(self.path)
      self.created_dir = True
    except OSError, e:
      if e.errno != errno.EEXIST:
        raise

  def Finalize1(self, xcode_targets, serialize_all_tests):
    # Collect a list of all of the build configuration names used by the
    # various targets in the file.  It is very heavily advised to keep each
    # target in an entire project (even across multiple project files) using
    # the same set of configuration names.
    configurations = []
    for xct in self.project.GetProperty('targets'):
      xccl = xct.GetProperty('buildConfigurationList')
      xcbcs = xccl.GetProperty('buildConfigurations')
      for xcbc in xcbcs:
        name = xcbc.GetProperty('name')
        if name not in configurations:
          configurations.append(name)

    # Replace the XCConfigurationList attached to the PBXProject object with
    # a new one specifying all of the configuration names used by the various
    # targets.
    try:
      xccl = CreateXCConfigurationList(configurations)
      self.project.SetProperty('buildConfigurationList', xccl)
    except:
      sys.stderr.write("Problem with gyp file %s\n" % self.gyp_path)
      raise

    # The need for this setting is explained above where _intermediate_var is
    # defined.  The comments below about wanting to avoid project-wide build
    # settings apply here too, but this needs to be set on a project-wide basis
    # so that files relative to the _intermediate_var setting can be displayed
    # properly in the Xcode UI.
    #
    # Note that for configuration-relative files such as anything relative to
    # _intermediate_var, for the purposes of UI tree view display, Xcode will
    # only resolve the configuration name once, when the project file is
    # opened.  If the active build configuration is changed, the project file
    # must be closed and reopened if it is desired for the tree view to update.
    # This is filed as Apple radar 6588391.
    xccl.SetBuildSetting(_intermediate_var,
                         '$(PROJECT_DERIVED_FILE_DIR)/$(CONFIGURATION)')
    xccl.SetBuildSetting(_shared_intermediate_var,
                         '$(SYMROOT)/DerivedSources/$(CONFIGURATION)')

    # Set user-specified project-wide build settings and config files.  This
    # is intended to be used very sparingly.  Really, almost everything should
    # go into target-specific build settings sections.  The project-wide
    # settings are only intended to be used in cases where Xcode attempts to
    # resolve variable references in a project context as opposed to a target
    # context, such as when resolving sourceTree references while building up
    # the tree tree view for UI display.
    # Any values set globally are applied to all configurations, then any
    # per-configuration values are applied.
    for xck, xcv in self.build_file_dict.get('xcode_settings', {}).iteritems():
      xccl.SetBuildSetting(xck, xcv)
    if 'xcode_config_file' in self.build_file_dict:
      config_ref = self.project.AddOrGetFileInRootGroup(
          self.build_file_dict['xcode_config_file'])
      xccl.SetBaseConfiguration(config_ref)
    build_file_configurations = self.build_file_dict.get('configurations', {})
    if build_file_configurations:
      for config_name in configurations:
        build_file_configuration_named = \
            build_file_configurations.get(config_name, {})
        if build_file_configuration_named:
          xcc = xccl.ConfigurationNamed(config_name)
          for xck, xcv in build_file_configuration_named.get('xcode_settings',
                                                             {}).iteritems():
            xcc.SetBuildSetting(xck, xcv)
          if 'xcode_config_file' in build_file_configuration_named:
            config_ref = self.project.AddOrGetFileInRootGroup(
                build_file_configurations[config_name]['xcode_config_file'])
            xcc.SetBaseConfiguration(config_ref)

    # Sort the targets based on how they appeared in the input.
    # TODO(mark): Like a lot of other things here, this assumes internal
    # knowledge of PBXProject - in this case, of its "targets" property.

    # ordinary_targets are ordinary targets that are already in the project
    # file. run_test_targets are the targets that run unittests and should be
    # used for the Run All Tests target.  support_targets are the action/rule
    # targets used by GYP file targets, just kept for the assert check.
    ordinary_targets = []
    run_test_targets = []
    support_targets = []

    # targets is full list of targets in the project.
    targets = []

    # does the it define it's own "all"?
    has_custom_all = False

    # targets_for_all is the list of ordinary_targets that should be listed
    # in this project's "All" target.  It includes each non_runtest_target
    # that does not have suppress_wildcard set.
    targets_for_all = []

    for target in self.build_file_dict['targets']:
      target_name = target['target_name']
      toolset = target['toolset']
      qualified_target = gyp.common.QualifiedTarget(self.gyp_path, target_name,
                                                    toolset)
      xcode_target = xcode_targets[qualified_target]
      # Make sure that the target being added to the sorted list is already in
      # the unsorted list.
      assert xcode_target in self.project._properties['targets']
      targets.append(xcode_target)
      ordinary_targets.append(xcode_target)
      if xcode_target.support_target:
        support_targets.append(xcode_target.support_target)
        targets.append(xcode_target.support_target)

      if not int(target.get('suppress_wildcard', False)):
        targets_for_all.append(xcode_target)

      if target_name.lower() == 'all':
        has_custom_all = True;

      # If this target has a 'run_as' attribute, add its target to the
      # targets, and add it to the test targets.
      if target.get('run_as'):
        # Make a target to run something.  It should have one
        # dependency, the parent xcode target.
        xccl = CreateXCConfigurationList(configurations)
        run_target = gyp.xcodeproj_file.PBXAggregateTarget({
              'name':                   'Run ' + target_name,
              'productName':            xcode_target.GetProperty('productName'),
              'buildConfigurationList': xccl,
            },
            parent=self.project)
        run_target.AddDependency(xcode_target)

        command = target['run_as']
        script = ''
        if command.get('working_directory'):
          script = script + 'cd "%s"\n' % \
                   gyp.xcodeproj_file.ConvertVariablesToShellSyntax(
                       command.get('working_directory'))

        if command.get('environment'):
          script = script + "\n".join(
            ['export %s="%s"' %
             (key, gyp.xcodeproj_file.ConvertVariablesToShellSyntax(val))
             for (key, val) in command.get('environment').iteritems()]) + "\n"

        # Some test end up using sockets, files on disk, etc. and can get
        # confused if more then one test runs at a time.  The generator
        # flag 'xcode_serialize_all_test_runs' controls the forcing of all
        # tests serially.  It defaults to True.  To get serial runs this
        # little bit of python does the same as the linux flock utility to
        # make sure only one runs at a time.
        command_prefix = ''
        if serialize_all_tests:
          command_prefix = \
"""python -c "import fcntl, subprocess, sys
file = open('$TMPDIR/GYP_serialize_test_runs', 'a')
fcntl.flock(file.fileno(), fcntl.LOCK_EX)
sys.exit(subprocess.call(sys.argv[1:]))" """

        # If we were unable to exec for some reason, we want to exit
        # with an error, and fixup variable references to be shell
        # syntax instead of xcode syntax.
        script = script + 'exec ' + command_prefix + '%s\nexit 1\n' % \
                 gyp.xcodeproj_file.ConvertVariablesToShellSyntax(
                     gyp.common.EncodePOSIXShellList(command.get('action')))

        ssbp = gyp.xcodeproj_file.PBXShellScriptBuildPhase({
              'shellScript':      script,
              'showEnvVarsInLog': 0,
            })
        run_target.AppendProperty('buildPhases', ssbp)

        # Add the run target to the project file.
        targets.append(run_target)
        run_test_targets.append(run_target)
        xcode_target.test_runner = run_target


    # Make sure that the list of targets being replaced is the same length as
    # the one replacing it, but allow for the added test runner targets.
    assert len(self.project._properties['targets']) == \
      len(ordinary_targets) + len(support_targets)

    self.project._properties['targets'] = targets

    # Get rid of unnecessary levels of depth in groups like the Source group.
    self.project.RootGroupsTakeOverOnlyChildren(True)

    # Sort the groups nicely.  Do this after sorting the targets, because the
    # Products group is sorted based on the order of the targets.
    self.project.SortGroups()

    # Create an "All" target if there's more than one target in this project
    # file and the project didn't define its own "All" target.  Put a generated
    # "All" target first so that people opening up the project for the first
    # time will build everything by default.
    if len(targets_for_all) > 1 and not has_custom_all:
      xccl = CreateXCConfigurationList(configurations)
      all_target = gyp.xcodeproj_file.PBXAggregateTarget(
          {
            'buildConfigurationList': xccl,
            'name':                   'All',
          },
          parent=self.project)

      for target in targets_for_all:
        all_target.AddDependency(target)

      # TODO(mark): This is evil because it relies on internal knowledge of
      # PBXProject._properties.  It's important to get the "All" target first,
      # though.
      self.project._properties['targets'].insert(0, all_target)

    # The same, but for run_test_targets.
    if len(run_test_targets) > 1:
      xccl = CreateXCConfigurationList(configurations)
      run_all_tests_target = gyp.xcodeproj_file.PBXAggregateTarget(
          {
            'buildConfigurationList': xccl,
            'name':                   'Run All Tests',
          },
          parent=self.project)
      for run_test_target in run_test_targets:
        run_all_tests_target.AddDependency(run_test_target)

      # Insert after the "All" target, which must exist if there is more than
      # one run_test_target.
      self.project._properties['targets'].insert(1, run_all_tests_target)

  def Finalize2(self, xcode_targets, xcode_target_to_target_dict):
    # Finalize2 needs to happen in a separate step because the process of
    # updating references to other projects depends on the ordering of targets
    # within remote project files.  Finalize1 is responsible for sorting duty,
    # and once all project files are sorted, Finalize2 can come in and update
    # these references.

    # To support making a "test runner" target that will run all the tests
    # that are direct dependents of any given target, we look for
    # xcode_create_dependents_test_runner being set on an Aggregate target,
    # and generate a second target that will run the tests runners found under
    # the marked target.
    for bf_tgt in self.build_file_dict['targets']:
      if int(bf_tgt.get('xcode_create_dependents_test_runner', 0)):
        tgt_name = bf_tgt['target_name']
        toolset = bf_tgt['toolset']
        qualified_target = gyp.common.QualifiedTarget(self.gyp_path,
                                                      tgt_name, toolset)
        xcode_target = xcode_targets[qualified_target]
        if isinstance(xcode_target, gyp.xcodeproj_file.PBXAggregateTarget):
          # Collect all the run test targets.
          all_run_tests = []
          pbxtds = xcode_target.GetProperty('dependencies')
          for pbxtd in pbxtds:
            pbxcip = pbxtd.GetProperty('targetProxy')
            dependency_xct = pbxcip.GetProperty('remoteGlobalIDString')
            if hasattr(dependency_xct, 'test_runner'):
              all_run_tests.append(dependency_xct.test_runner)

          # Directly depend on all the runners as they depend on the target
          # that builds them.
          if len(all_run_tests) > 0:
            run_all_target = gyp.xcodeproj_file.PBXAggregateTarget({
                  'name':        'Run %s Tests' % tgt_name,
                  'productName': tgt_name,
                },
                parent=self.project)
            for run_test_target in all_run_tests:
              run_all_target.AddDependency(run_test_target)

            # Insert the test runner after the related target.
            idx = self.project._properties['targets'].index(xcode_target)
            self.project._properties['targets'].insert(idx + 1, run_all_target)

    # Update all references to other projects, to make sure that the lists of
    # remote products are complete.  Otherwise, Xcode will fill them in when
    # it opens the project file, which will result in unnecessary diffs.
    # TODO(mark): This is evil because it relies on internal knowledge of
    # PBXProject._other_pbxprojects.
    for other_pbxproject in self.project._other_pbxprojects.keys():
      self.project.AddOrGetProjectReference(other_pbxproject)

    self.project.SortRemoteProductReferences()

    # Give everything an ID.
    self.project_file.ComputeIDs()

    # Make sure that no two objects in the project file have the same ID.  If
    # multiple objects wind up with the same ID, upon loading the file, Xcode
    # will only recognize one object (the last one in the file?) and the
    # results are unpredictable.
    self.project_file.EnsureNoIDCollisions()

  def Write(self):
    # Write the project file to a temporary location first.  Xcode watches for
    # changes to the project file and presents a UI sheet offering to reload
    # the project when it does change.  However, in some cases, especially when
    # multiple projects are open or when Xcode is busy, things don't work so
    # seamlessly.  Sometimes, Xcode is able to detect that a project file has
    # changed but can't unload it because something else is referencing it.
    # To mitigate this problem, and to avoid even having Xcode present the UI
    # sheet when an open project is rewritten for inconsequential changes, the
    # project file is written to a temporary file in the xcodeproj directory
    # first.  The new temporary file is then compared to the existing project
    # file, if any.  If they differ, the new file replaces the old; otherwise,
    # the new project file is simply deleted.  Xcode properly detects a file
    # being renamed over an open project file as a change and so it remains
    # able to present the "project file changed" sheet under this system.
    # Writing to a temporary file first also avoids the possible problem of
    # Xcode rereading an incomplete project file.
    (output_fd, new_pbxproj_path) = \
        tempfile.mkstemp(suffix='.tmp', prefix='project.pbxproj.gyp.',
                         dir=self.path)

    try:
      output_file = os.fdopen(output_fd, 'wb')

      self.project_file.Print(output_file)
      output_file.close()

      pbxproj_path = os.path.join(self.path, 'project.pbxproj')

      same = False
      try:
        same = filecmp.cmp(pbxproj_path, new_pbxproj_path, False)
      except OSError, e:
        if e.errno != errno.ENOENT:
          raise

      if same:
        # The new file is identical to the old one, just get rid of the new
        # one.
        os.unlink(new_pbxproj_path)
      else:
        # The new file is different from the old one, or there is no old one.
        # Rename the new file to the permanent name.
        #
        # tempfile.mkstemp uses an overly restrictive mode, resulting in a
        # file that can only be read by the owner, regardless of the umask.
        # There's no reason to not respect the umask here, which means that
        # an extra hoop is required to fetch it and reset the new file's mode.
        #
        # No way to get the umask without setting a new one?  Set a safe one
        # and then set it back to the old value.
        umask = os.umask(077)
        os.umask(umask)

        os.chmod(new_pbxproj_path, 0666 & ~umask)
        os.rename(new_pbxproj_path, pbxproj_path)

    except Exception:
      # Don't leave turds behind.  In fact, if this code was responsible for
      # creating the xcodeproj directory, get rid of that too.
      os.unlink(new_pbxproj_path)
      if self.created_dir:
        shutil.rmtree(self.path, True)
      raise


def AddSourceToTarget(source, type, pbxp, xct):
  # TODO(mark): Perhaps source_extensions and library_extensions can be made a
  # little bit fancier.
  source_extensions = ['c', 'cc', 'cpp', 'cxx', 'm', 'mm', 's']

  # .o is conceptually more of a "source" than a "library," but Xcode thinks
  # of "sources" as things to compile and "libraries" (or "frameworks") as
  # things to link with. Adding an object file to an Xcode target's frameworks
  # phase works properly.
  library_extensions = ['a', 'dylib', 'framework', 'o']

  basename = posixpath.basename(source)
  (root, ext) = posixpath.splitext(basename)
  if ext:
    ext = ext[1:].lower()

  if ext in source_extensions and type != 'none':
    xct.SourcesPhase().AddFile(source)
  elif ext in library_extensions and type != 'none':
    xct.FrameworksPhase().AddFile(source)
  else:
    # Files that aren't added to a sources or frameworks build phase can still
    # go into the project file, just not as part of a build phase.
    pbxp.AddOrGetFileInRootGroup(source)


def AddResourceToTarget(resource, pbxp, xct):
  # TODO(mark): Combine with AddSourceToTarget above?  Or just inline this call
  # where it's used.
  xct.ResourcesPhase().AddFile(resource)


def AddHeaderToTarget(header, pbxp, xct, is_public):
  # TODO(mark): Combine with AddSourceToTarget above?  Or just inline this call
  # where it's used.
  settings = '{ATTRIBUTES = (%s, ); }' % ('Private', 'Public')[is_public]
  xct.HeadersPhase().AddFile(header, settings)


_xcode_variable_re = re.compile('(\$\((.*?)\))')
def ExpandXcodeVariables(string, expansions):
  """Expands Xcode-style $(VARIABLES) in string per the expansions dict.

  In some rare cases, it is appropriate to expand Xcode variables when a
  project file is generated.  For any substring $(VAR) in string, if VAR is a
  key in the expansions dict, $(VAR) will be replaced with expansions[VAR].
  Any $(VAR) substring in string for which VAR is not a key in the expansions
  dict will remain in the returned string.
  """

  matches = _xcode_variable_re.findall(string)
  if matches == None:
    return string

  matches.reverse()
  for match in matches:
    (to_replace, variable) = match
    if not variable in expansions:
      continue

    replacement = expansions[variable]
    string = re.sub(re.escape(to_replace), replacement, string)

  return string


_xcode_define_re = re.compile(r'([\\\"\' ])')
def EscapeXcodeDefine(s):
  """We must escape the defines that we give to XCode so that it knows not to
     split on spaces and to respect backslash and quote literals. However, we
     must not quote the define, or Xcode will incorrectly intepret variables
     especially $(inherited)."""
  return re.sub(_xcode_define_re, r'\\\1', s)


def PerformBuild(data, configurations, params):
  options = params['options']

  for build_file, build_file_dict in data.iteritems():
    (build_file_root, build_file_ext) = os.path.splitext(build_file)
    if build_file_ext != '.gyp':
      continue
    xcodeproj_path = build_file_root + options.suffix + '.xcodeproj'
    if options.generator_output:
      xcodeproj_path = os.path.join(options.generator_output, xcodeproj_path)

  for config in configurations:
    arguments = ['xcodebuild', '-project', xcodeproj_path]
    arguments += ['-configuration', config]
    print "Building [%s]: %s" % (config, arguments)
    subprocess.check_call(arguments)


def GenerateOutput(target_list, target_dicts, data, params):
  options = params['options']
  generator_flags = params.get('generator_flags', {})
  parallel_builds = generator_flags.get('xcode_parallel_builds', True)
  serialize_all_tests = \
      generator_flags.get('xcode_serialize_all_test_runs', True)
  project_version = generator_flags.get('xcode_project_version', None)
  skip_excluded_files = \
      not generator_flags.get('xcode_list_excluded_files', True)
  xcode_projects = {}
  for build_file, build_file_dict in data.iteritems():
    (build_file_root, build_file_ext) = os.path.splitext(build_file)
    if build_file_ext != '.gyp':
      continue
    xcodeproj_path = build_file_root + options.suffix + '.xcodeproj'
    if options.generator_output:
      xcodeproj_path = os.path.join(options.generator_output, xcodeproj_path)
    xcp = XcodeProject(build_file, xcodeproj_path, build_file_dict)
    xcode_projects[build_file] = xcp
    pbxp = xcp.project

    if parallel_builds:
      pbxp.SetProperty('attributes',
                       {'BuildIndependentTargetsInParallel': 'YES'})
    if project_version:
      xcp.project_file.SetXcodeVersion(project_version)

    # Add gyp/gypi files to project
    if not generator_flags.get('standalone'):
      main_group = pbxp.GetProperty('mainGroup')
      build_group = gyp.xcodeproj_file.PBXGroup({'name': 'Build'})
      main_group.AppendChild(build_group)
      for included_file in build_file_dict['included_files']:
        build_group.AddOrGetFileByPath(included_file, False)

  xcode_targets = {}
  xcode_target_to_target_dict = {}
  for qualified_target in target_list:
    [build_file, target_name, toolset] = \
        gyp.common.ParseQualifiedTarget(qualified_target)

    spec = target_dicts[qualified_target]
    if spec['toolset'] != 'target':
      raise Exception(
          'Multiple toolsets not supported in xcode build (target %s)' %
          qualified_target)
    configuration_names = [spec['default_configuration']]
    for configuration_name in sorted(spec['configurations'].keys()):
      if configuration_name not in configuration_names:
        configuration_names.append(configuration_name)
    xcp = xcode_projects[build_file]
    pbxp = xcp.project

    # Set up the configurations for the target according to the list of names
    # supplied.
    xccl = CreateXCConfigurationList(configuration_names)

    # Create an XCTarget subclass object for the target. The type with
    # "+bundle" appended will be used if the target has "mac_bundle" set.
    # loadable_modules not in a mac_bundle are mapped to
    # com.googlecode.gyp.xcode.bundle, a pseudo-type that xcode.py interprets
    # to create a single-file mh_bundle.
    _types = {
      'executable':             'com.apple.product-type.tool',
      'loadable_module':        'com.googlecode.gyp.xcode.bundle',
      'shared_library':         'com.apple.product-type.library.dynamic',
      'static_library':         'com.apple.product-type.library.static',
      'executable+bundle':      'com.apple.product-type.application',
      'loadable_module+bundle': 'com.apple.product-type.bundle',
      'loadable_module+xctest': 'com.apple.product-type.bundle.unit-test',
      'shared_library+bundle':  'com.apple.product-type.framework',
    }

    target_properties = {
      'buildConfigurationList': xccl,
      'name':                   target_name,
    }

    type = spec['type']
    is_xctest = int(spec.get('mac_xctest_bundle', 0))
    is_bundle = int(spec.get('mac_bundle', 0)) or is_xctest
    if type != 'none':
      type_bundle_key = type
      if is_xctest:
        type_bundle_key += '+xctest'
        assert type == 'loadable_module', (
            'mac_xctest_bundle targets must have type loadable_module '
            '(target %s)' % target_name)
      elif is_bundle:
        type_bundle_key += '+bundle'

      xctarget_type = gyp.xcodeproj_file.PBXNativeTarget
      try:
        target_properties['productType'] = _types[type_bundle_key]
      except KeyError, e:
        gyp.common.ExceptionAppend(e, "-- unknown product type while "
                                   "writing target %s" % target_name)
        raise
    else:
      xctarget_type = gyp.xcodeproj_file.PBXAggregateTarget
      assert not is_bundle, (
          'mac_bundle targets cannot have type none (target "%s")' %
          target_name)
      assert not is_xctest, (
          'mac_xctest_bundle targets cannot have type none (target "%s")' %
          target_name)

    target_product_name = spec.get('product_name')
    if target_product_name is not None:
      target_properties['productName'] = target_product_name

    xct = xctarget_type(target_properties, parent=pbxp,
                        force_outdir=spec.get('product_dir'),
                        force_prefix=spec.get('product_prefix'),
                        force_extension=spec.get('product_extension'))
    pbxp.AppendProperty('targets', xct)
    xcode_targets[qualified_target] = xct
    xcode_target_to_target_dict[xct] = spec

    spec_actions = spec.get('actions', [])
    spec_rules = spec.get('rules', [])

    # Xcode has some "issues" with checking dependencies for the "Compile
    # sources" step with any source files/headers generated by actions/rules.
    # To work around this, if a target is building anything directly (not
    # type "none"), then a second target is used to run the GYP actions/rules
    # and is made a dependency of this target.  This way the work is done
    # before the dependency checks for what should be recompiled.
    support_xct = None
    if type != 'none' and (spec_actions or spec_rules):
      support_xccl = CreateXCConfigurationList(configuration_names);
      support_target_suffix = generator_flags.get(
          'support_target_suffix', ' Support')
      support_target_properties = {
        'buildConfigurationList': support_xccl,
        'name':                   target_name + support_target_suffix,
      }
      if target_product_name:
        support_target_properties['productName'] = \
            target_product_name + ' Support'
      support_xct = \
          gyp.xcodeproj_file.PBXAggregateTarget(support_target_properties,
                                                parent=pbxp)
      pbxp.AppendProperty('targets', support_xct)
      xct.AddDependency(support_xct)
    # Hang the support target off the main target so it can be tested/found
    # by the generator during Finalize.
    xct.support_target = support_xct

    prebuild_index = 0

    # Add custom shell script phases for "actions" sections.
    for action in spec_actions:
      # There's no need to write anything into the script to ensure that the
      # output directories already exist, because Xcode will look at the
      # declared outputs and automatically ensure that they exist for us.

      # Do we have a message to print when this action runs?
      message = action.get('message')
      if message:
        message = 'echo note: ' + gyp.common.EncodePOSIXShellArgument(message)
      else:
        message = ''

      # Turn the list into a string that can be passed to a shell.
      action_string = gyp.common.EncodePOSIXShellList(action['action'])

      # Convert Xcode-type variable references to sh-compatible environment
      # variable references.
      message_sh = gyp.xcodeproj_file.ConvertVariablesToShellSyntax(message)
      action_string_sh = gyp.xcodeproj_file.ConvertVariablesToShellSyntax(
        action_string)

      script = ''
      # Include the optional message
      if message_sh:
        script += message_sh + '\n'
      # Be sure the script runs in exec, and that if exec fails, the script
      # exits signalling an error.
      script += 'exec ' + action_string_sh + '\nexit 1\n'
      ssbp = gyp.xcodeproj_file.PBXShellScriptBuildPhase({
            'inputPaths': action['inputs'],
            'name': 'Action "' + action['action_name'] + '"',
            'outputPaths': action['outputs'],
            'shellScript': script,
            'showEnvVarsInLog': 0,
          })

      if support_xct:
        support_xct.AppendProperty('buildPhases', ssbp)
      else:
        # TODO(mark): this assumes too much knowledge of the internals of
        # xcodeproj_file; some of these smarts should move into xcodeproj_file
        # itself.
        xct._properties['buildPhases'].insert(prebuild_index, ssbp)
        prebuild_index = prebuild_index + 1

      # TODO(mark): Should verify that at most one of these is specified.
      if int(action.get('process_outputs_as_sources', False)):
        for output in action['outputs']:
          AddSourceToTarget(output, type, pbxp, xct)

      if int(action.get('process_outputs_as_mac_bundle_resources', False)):
        for output in action['outputs']:
          AddResourceToTarget(output, pbxp, xct)

    # tgt_mac_bundle_resources holds the list of bundle resources so
    # the rule processing can check against it.
    if is_bundle:
      tgt_mac_bundle_resources = spec.get('mac_bundle_resources', [])
    else:
      tgt_mac_bundle_resources = []

    # Add custom shell script phases driving "make" for "rules" sections.
    #
    # Xcode's built-in rule support is almost powerful enough to use directly,
    # but there are a few significant deficiencies that render them unusable.
    # There are workarounds for some of its inadequacies, but in aggregate,
    # the workarounds added complexity to the generator, and some workarounds
    # actually require input files to be crafted more carefully than I'd like.
    # Consequently, until Xcode rules are made more capable, "rules" input
    # sections will be handled in Xcode output by shell script build phases
    # performed prior to the compilation phase.
    #
    # The following problems with Xcode rules were found.  The numbers are
    # Apple radar IDs.  I hope that these shortcomings are addressed, I really
    # liked having the rules handled directly in Xcode during the period that
    # I was prototyping this.
    #
    # 6588600 Xcode compiles custom script rule outputs too soon, compilation
    #         fails.  This occurs when rule outputs from distinct inputs are
    #         interdependent.  The only workaround is to put rules and their
    #         inputs in a separate target from the one that compiles the rule
    #         outputs.  This requires input file cooperation and it means that
    #         process_outputs_as_sources is unusable.
    # 6584932 Need to declare that custom rule outputs should be excluded from
    #         compilation.  A possible workaround is to lie to Xcode about a
    #         rule's output, giving it a dummy file it doesn't know how to
    #         compile.  The rule action script would need to touch the dummy.
    # 6584839 I need a way to declare additional inputs to a custom rule.
    #         A possible workaround is a shell script phase prior to
    #         compilation that touches a rule's primary input files if any
    #         would-be additional inputs are newer than the output.  Modifying
    #         the source tree - even just modification times - feels dirty.
    # 6564240 Xcode "custom script" build rules always dump all environment
    #         variables.  This is a low-prioroty problem and is not a
    #         show-stopper.
    rules_by_ext = {}
    for rule in spec_rules:
      rules_by_ext[rule['extension']] = rule

      # First, some definitions:
      #
      # A "rule source" is a file that was listed in a target's "sources"
      # list and will have a rule applied to it on the basis of matching the
      # rule's "extensions" attribute.  Rule sources are direct inputs to
      # rules.
      #
      # Rule definitions may specify additional inputs in their "inputs"
      # attribute.  These additional inputs are used for dependency tracking
      # purposes.
      #
      # A "concrete output" is a rule output with input-dependent variables
      # resolved.  For example, given a rule with:
      #   'extension': 'ext', 'outputs': ['$(INPUT_FILE_BASE).cc'],
      # if the target's "sources" list contained "one.ext" and "two.ext",
      # the "concrete output" for rule input "two.ext" would be "two.cc".  If
      # a rule specifies multiple outputs, each input file that the rule is
      # applied to will have the same number of concrete outputs.
      #
      # If any concrete outputs are outdated or missing relative to their
      # corresponding rule_source or to any specified additional input, the
      # rule action must be performed to generate the concrete outputs.

      # concrete_outputs_by_rule_source will have an item at the same index
      # as the rule['rule_sources'] that it corresponds to.  Each item is a
      # list of all of the concrete outputs for the rule_source.
      concrete_outputs_by_rule_source = []

      # concrete_outputs_all is a flat list of all concrete outputs that this
      # rule is able to produce, given the known set of input files
      # (rule_sources) that apply to it.
      concrete_outputs_all = []

      # messages & actions are keyed by the same indices as rule['rule_sources']
      # and concrete_outputs_by_rule_source.  They contain the message and
      # action to perform after resolving input-dependent variables.  The
      # message is optional, in which case None is stored for each rule source.
      messages = []
      actions = []

      for rule_source in rule.get('rule_sources', []):
        rule_source_dirname, rule_source_basename = \
            posixpath.split(rule_source)
        (rule_source_root, rule_source_ext) = \
            posixpath.splitext(rule_source_basename)

        # These are the same variable names that Xcode uses for its own native
        # rule support.  Because Xcode's rule engine is not being used, they
        # need to be expanded as they are written to the makefile.
        rule_input_dict = {
          'INPUT_FILE_BASE':   rule_source_root,
          'INPUT_FILE_SUFFIX': rule_source_ext,
          'INPUT_FILE_NAME':   rule_source_basename,
          'INPUT_FILE_PATH':   rule_source,
          'INPUT_FILE_DIRNAME': rule_source_dirname,
        }

        concrete_outputs_for_this_rule_source = []
        for output in rule.get('outputs', []):
          # Fortunately, Xcode and make both use $(VAR) format for their
          # variables, so the expansion is the only transformation necessary.
          # Any remaning $(VAR)-type variables in the string can be given
          # directly to make, which will pick up the correct settings from
          # what Xcode puts into the environment.
          concrete_output = ExpandXcodeVariables(output, rule_input_dict)
          concrete_outputs_for_this_rule_source.append(concrete_output)

          # Add all concrete outputs to the project.
          pbxp.AddOrGetFileInRootGroup(concrete_output)

        concrete_outputs_by_rule_source.append( \
            concrete_outputs_for_this_rule_source)
        concrete_outputs_all.extend(concrete_outputs_for_this_rule_source)

        # TODO(mark): Should verify that at most one of these is specified.
        if int(rule.get('process_outputs_as_sources', False)):
          for output in concrete_outputs_for_this_rule_source:
            AddSourceToTarget(output, type, pbxp, xct)

        # If the file came from the mac_bundle_resources list or if the rule
        # is marked to process outputs as bundle resource, do so.
        was_mac_bundle_resource = rule_source in tgt_mac_bundle_resources
        if was_mac_bundle_resource or \
            int(rule.get('process_outputs_as_mac_bundle_resources', False)):
          for output in concrete_outputs_for_this_rule_source:
            AddResourceToTarget(output, pbxp, xct)

        # Do we have a message to print when this rule runs?
        message = rule.get('message')
        if message:
          message = gyp.common.EncodePOSIXShellArgument(message)
          message = ExpandXcodeVariables(message, rule_input_dict)
        messages.append(message)

        # Turn the list into a string that can be passed to a shell.
        action_string = gyp.common.EncodePOSIXShellList(rule['action'])

        action = ExpandXcodeVariables(action_string, rule_input_dict)
        actions.append(action)

      if len(concrete_outputs_all) > 0:
        # TODO(mark): There's a possibilty for collision here.  Consider
        # target "t" rule "A_r" and target "t_A" rule "r".
        makefile_name = '%s.make' % re.sub(
            '[^a-zA-Z0-9_]', '_' , '%s_%s' % (target_name, rule['rule_name']))
        makefile_path = os.path.join(xcode_projects[build_file].path,
                                     makefile_name)
        # TODO(mark): try/close?  Write to a temporary file and swap it only
        # if it's got changes?
        makefile = open(makefile_path, 'wb')

        # make will build the first target in the makefile by default.  By
        # convention, it's called "all".  List all (or at least one)
        # concrete output for each rule source as a prerequisite of the "all"
        # target.
        makefile.write('all: \\\n')
        for concrete_output_index in \
            xrange(0, len(concrete_outputs_by_rule_source)):
          # Only list the first (index [0]) concrete output of each input
          # in the "all" target.  Otherwise, a parallel make (-j > 1) would
          # attempt to process each input multiple times simultaneously.
          # Otherwise, "all" could just contain the entire list of
          # concrete_outputs_all.
          concrete_output = \
              concrete_outputs_by_rule_source[concrete_output_index][0]
          if concrete_output_index == len(concrete_outputs_by_rule_source) - 1:
            eol = ''
          else:
            eol = ' \\'
          makefile.write('    %s%s\n' % (concrete_output, eol))

        for (rule_source, concrete_outputs, message, action) in \
            zip(rule['rule_sources'], concrete_outputs_by_rule_source,
                messages, actions):
          makefile.write('\n')

          # Add a rule that declares it can build each concrete output of a
          # rule source.  Collect the names of the directories that are
          # required.
          concrete_output_dirs = []
          for concrete_output_index in xrange(0, len(concrete_outputs)):
            concrete_output = concrete_outputs[concrete_output_index]
            if concrete_output_index == 0:
              bol = ''
            else:
              bol = '    '
            makefile.write('%s%s \\\n' % (bol, concrete_output))

            concrete_output_dir = posixpath.dirname(concrete_output)
            if (concrete_output_dir and
                concrete_output_dir not in concrete_output_dirs):
              concrete_output_dirs.append(concrete_output_dir)

          makefile.write('    : \\\n')

          # The prerequisites for this rule are the rule source itself and
          # the set of additional rule inputs, if any.
          prerequisites = [rule_source]
          prerequisites.extend(rule.get('inputs', []))
          for prerequisite_index in xrange(0, len(prerequisites)):
            prerequisite = prerequisites[prerequisite_index]
            if prerequisite_index == len(prerequisites) - 1:
              eol = ''
            else:
              eol = ' \\'
            makefile.write('    %s%s\n' % (prerequisite, eol))

          # Make sure that output directories exist before executing the rule
          # action.
          if len(concrete_output_dirs) > 0:
            makefile.write('\t@mkdir -p "%s"\n' %
                           '" "'.join(concrete_output_dirs))

          # The rule message and action have already had the necessary variable
          # substitutions performed.
          if message:
            # Mark it with note: so Xcode picks it up in build output.
            makefile.write('\t@echo note: %s\n' % message)
          makefile.write('\t%s\n' % action)

        makefile.close()

        # It might be nice to ensure that needed output directories exist
        # here rather than in each target in the Makefile, but that wouldn't
        # work if there ever was a concrete output that had an input-dependent
        # variable anywhere other than in the leaf position.

        # Don't declare any inputPaths or outputPaths.  If they're present,
        # Xcode will provide a slight optimization by only running the script
        # phase if any output is missing or outdated relative to any input.
        # Unfortunately, it will also assume that all outputs are touched by
        # the script, and if the outputs serve as files in a compilation
        # phase, they will be unconditionally rebuilt.  Since make might not
        # rebuild everything that could be declared here as an output, this
        # extra compilation activity is unnecessary.  With inputPaths and
        # outputPaths not supplied, make will always be called, but it knows
        # enough to not do anything when everything is up-to-date.

        # To help speed things up, pass -j COUNT to make so it does some work
        # in parallel.  Don't use ncpus because Xcode will build ncpus targets
        # in parallel and if each target happens to have a rules step, there
        # would be ncpus^2 things going.  With a machine that has 2 quad-core
        # Xeons, a build can quickly run out of processes based on
        # scheduling/other tasks, and randomly failing builds are no good.
        script = \
"""JOB_COUNT="$(/usr/sbin/sysctl -n hw.ncpu)"
if [ "${JOB_COUNT}" -gt 4 ]; then
  JOB_COUNT=4
fi
exec xcrun make -f "${PROJECT_FILE_PATH}/%s" -j "${JOB_COUNT}"
exit 1
""" % makefile_name
        ssbp = gyp.xcodeproj_file.PBXShellScriptBuildPhase({
              'name': 'Rule "' + rule['rule_name'] + '"',
              'shellScript': script,
              'showEnvVarsInLog': 0,
            })

        if support_xct:
          support_xct.AppendProperty('buildPhases', ssbp)
        else:
          # TODO(mark): this assumes too much knowledge of the internals of
          # xcodeproj_file; some of these smarts should move into xcodeproj_file
          # itself.
          xct._properties['buildPhases'].insert(prebuild_index, ssbp)
          prebuild_index = prebuild_index + 1

      # Extra rule inputs also go into the project file.  Concrete outputs were
      # already added when they were computed.
      groups = ['inputs', 'inputs_excluded']
      if skip_excluded_files:
        groups = [x for x in groups if not x.endswith('_excluded')]
      for group in groups:
        for item in rule.get(group, []):
          pbxp.AddOrGetFileInRootGroup(item)

    # Add "sources".
    for source in spec.get('sources', []):
      (source_root, source_extension) = posixpath.splitext(source)
      if source_extension[1:] not in rules_by_ext:
        # AddSourceToTarget will add the file to a root group if it's not
        # already there.
        AddSourceToTarget(source, type, pbxp, xct)
      else:
        pbxp.AddOrGetFileInRootGroup(source)

    # Add "mac_bundle_resources" and "mac_framework_private_headers" if
    # it's a bundle of any type.
    if is_bundle:
      for resource in tgt_mac_bundle_resources:
        (resource_root, resource_extension) = posixpath.splitext(resource)
        if resource_extension[1:] not in rules_by_ext:
          AddResourceToTarget(resource, pbxp, xct)
        else:
          pbxp.AddOrGetFileInRootGroup(resource)

      for header in spec.get('mac_framework_private_headers', []):
        AddHeaderToTarget(header, pbxp, xct, False)

    # Add "mac_framework_headers". These can be valid for both frameworks
    # and static libraries.
    if is_bundle or type == 'static_library':
      for header in spec.get('mac_framework_headers', []):
        AddHeaderToTarget(header, pbxp, xct, True)

    # Add "copies".
    pbxcp_dict = {}
    for copy_group in spec.get('copies', []):
      dest = copy_group['destination']
      if dest[0] not in ('/', '$'):
        # Relative paths are relative to $(SRCROOT).
        dest = '$(SRCROOT)/' + dest

      # Coalesce multiple "copies" sections in the same target with the same
      # "destination" property into the same PBXCopyFilesBuildPhase, otherwise
      # they'll wind up with ID collisions.
      pbxcp = pbxcp_dict.get(dest, None)
      if pbxcp is None:
        pbxcp = gyp.xcodeproj_file.PBXCopyFilesBuildPhase({
              'name': 'Copy to ' + copy_group['destination']
            },
            parent=xct)
        pbxcp.SetDestination(dest)

        # TODO(mark): The usual comment about this knowing too much about
        # gyp.xcodeproj_file internals applies.
        xct._properties['buildPhases'].insert(prebuild_index, pbxcp)

        pbxcp_dict[dest] = pbxcp

      for file in copy_group['files']:
        pbxcp.AddFile(file)

    # Excluded files can also go into the project file.
    if not skip_excluded_files:
      for key in ['sources', 'mac_bundle_resources', 'mac_framework_headers',
                  'mac_framework_private_headers']:
        excluded_key = key + '_excluded'
        for item in spec.get(excluded_key, []):
          pbxp.AddOrGetFileInRootGroup(item)

    # So can "inputs" and "outputs" sections of "actions" groups.
    groups = ['inputs', 'inputs_excluded', 'outputs', 'outputs_excluded']
    if skip_excluded_files:
      groups = [x for x in groups if not x.endswith('_excluded')]
    for action in spec.get('actions', []):
      for group in groups:
        for item in action.get(group, []):
          # Exclude anything in BUILT_PRODUCTS_DIR.  They're products, not
          # sources.
          if not item.startswith('$(BUILT_PRODUCTS_DIR)/'):
            pbxp.AddOrGetFileInRootGroup(item)

    for postbuild in spec.get('postbuilds', []):
      action_string_sh = gyp.common.EncodePOSIXShellList(postbuild['action'])
      script = 'exec ' + action_string_sh + '\nexit 1\n'

      # Make the postbuild step depend on the output of ld or ar from this
      # target. Apparently putting the script step after the link step isn't
      # sufficient to ensure proper ordering in all cases. With an input
      # declared but no outputs, the script step should run every time, as
      # desired.
      ssbp = gyp.xcodeproj_file.PBXShellScriptBuildPhase({
            'inputPaths': ['$(BUILT_PRODUCTS_DIR)/$(EXECUTABLE_PATH)'],
            'name': 'Postbuild "' + postbuild['postbuild_name'] + '"',
            'shellScript': script,
            'showEnvVarsInLog': 0,
          })
      xct.AppendProperty('buildPhases', ssbp)

    # Add dependencies before libraries, because adding a dependency may imply
    # adding a library.  It's preferable to keep dependencies listed first
    # during a link phase so that they can override symbols that would
    # otherwise be provided by libraries, which will usually include system
    # libraries.  On some systems, ld is finicky and even requires the
    # libraries to be ordered in such a way that unresolved symbols in
    # earlier-listed libraries may only be resolved by later-listed libraries.
    # The Mac linker doesn't work that way, but other platforms do, and so
    # their linker invocations need to be constructed in this way.  There's
    # no compelling reason for Xcode's linker invocations to differ.

    if 'dependencies' in spec:
      for dependency in spec['dependencies']:
        xct.AddDependency(xcode_targets[dependency])
        # The support project also gets the dependencies (in case they are
        # needed for the actions/rules to work).
        if support_xct:
          support_xct.AddDependency(xcode_targets[dependency])

    if 'libraries' in spec:
      for library in spec['libraries']:
        xct.FrameworksPhase().AddFile(library)
        # Add the library's directory to LIBRARY_SEARCH_PATHS if necessary.
        # I wish Xcode handled this automatically.
        library_dir = posixpath.dirname(library)
        if library_dir not in xcode_standard_library_dirs and (
            not xct.HasBuildSetting(_library_search_paths_var) or
            library_dir not in xct.GetBuildSetting(_library_search_paths_var)):
          xct.AppendBuildSetting(_library_search_paths_var, library_dir)

    for configuration_name in configuration_names:
      configuration = spec['configurations'][configuration_name]
      xcbc = xct.ConfigurationNamed(configuration_name)
      for include_dir in configuration.get('mac_framework_dirs', []):
        xcbc.AppendBuildSetting('FRAMEWORK_SEARCH_PATHS', include_dir)
      for include_dir in configuration.get('include_dirs', []):
        xcbc.AppendBuildSetting('HEADER_SEARCH_PATHS', include_dir)
      for library_dir in configuration.get('library_dirs', []):
        if library_dir not in xcode_standard_library_dirs and (
            not xcbc.HasBuildSetting(_library_search_paths_var) or
            library_dir not in xcbc.GetBuildSetting(_library_search_paths_var)):
          xcbc.AppendBuildSetting(_library_search_paths_var, library_dir)

      if 'defines' in configuration:
        for define in configuration['defines']:
          set_define = EscapeXcodeDefine(define)
          xcbc.AppendBuildSetting('GCC_PREPROCESSOR_DEFINITIONS', set_define)
      if 'xcode_settings' in configuration:
        for xck, xcv in configuration['xcode_settings'].iteritems():
          xcbc.SetBuildSetting(xck, xcv)
      if 'xcode_config_file' in configuration:
        config_ref = pbxp.AddOrGetFileInRootGroup(
            configuration['xcode_config_file'])
        xcbc.SetBaseConfiguration(config_ref)

  build_files = []
  for build_file, build_file_dict in data.iteritems():
    if build_file.endswith('.gyp'):
      build_files.append(build_file)

  for build_file in build_files:
    xcode_projects[build_file].Finalize1(xcode_targets, serialize_all_tests)

  for build_file in build_files:
    xcode_projects[build_file].Finalize2(xcode_targets,
                                         xcode_target_to_target_dict)

  for build_file in build_files:
    xcode_projects[build_file].Write()
