# Copyright (c) 2013 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.

"""cmake output module

This module is under development and should be considered experimental.

This module produces cmake (2.8.8+) input as its output. One CMakeLists.txt is
created for each configuration.

This module's original purpose was to support editing in IDEs like KDevelop
which use CMake for project management. It is also possible to use CMake to
generate projects for other IDEs such as eclipse cdt and code::blocks. QtCreator
will convert the CMakeLists.txt to a code::blocks cbp for the editor to read,
but build using CMake. As a result QtCreator editor is unaware of compiler
defines. The generated CMakeLists.txt can also be used to build on Linux. There
is currently no support for building on platforms other than Linux.

The generated CMakeLists.txt should properly compile all projects. However,
there is a mismatch between gyp and cmake with regard to linking. All attempts
are made to work around this, but CMake sometimes sees -Wl,--start-group as a
library and incorrectly repeats it. As a result the output of this generator
should not be relied on for building.

When using with kdevelop, use version 4.4+. Previous versions of kdevelop will
not be able to find the header file directories described in the generated
CMakeLists.txt file.
"""

import multiprocessing
import os
import signal
import string
import subprocess
import gyp.common

generator_default_variables = {
  'EXECUTABLE_PREFIX': '',
  'EXECUTABLE_SUFFIX': '',
  'STATIC_LIB_PREFIX': 'lib',
  'STATIC_LIB_SUFFIX': '.a',
  'SHARED_LIB_PREFIX': 'lib',
  'SHARED_LIB_SUFFIX': '.so',
  'SHARED_LIB_DIR': '${builddir}/lib.${TOOLSET}',
  'LIB_DIR': '${obj}.${TOOLSET}',
  'INTERMEDIATE_DIR': '${obj}.${TOOLSET}/${TARGET}/geni',
  'SHARED_INTERMEDIATE_DIR': '${obj}/gen',
  'PRODUCT_DIR': '${builddir}',
  'RULE_INPUT_PATH': '${RULE_INPUT_PATH}',
  'RULE_INPUT_DIRNAME': '${RULE_INPUT_DIRNAME}',
  'RULE_INPUT_NAME': '${RULE_INPUT_NAME}',
  'RULE_INPUT_ROOT': '${RULE_INPUT_ROOT}',
  'RULE_INPUT_EXT': '${RULE_INPUT_EXT}',
  'CONFIGURATION_NAME': '${configuration}',
}

FULL_PATH_VARS = ('${CMAKE_SOURCE_DIR}', '${builddir}', '${obj}')

generator_supports_multiple_toolsets = True
generator_wants_static_library_dependencies_adjusted = True

COMPILABLE_EXTENSIONS = {
  '.c': 'cc',
  '.cc': 'cxx',
  '.cpp': 'cxx',
  '.cxx': 'cxx',
  '.s': 's', # cc
  '.S': 's', # cc
}


def RemovePrefix(a, prefix):
  """Returns 'a' without 'prefix' if it starts with 'prefix'."""
  return a[len(prefix):] if a.startswith(prefix) else a


def CalculateVariables(default_variables, params):
  """Calculate additional variables for use in the build (called by gyp)."""
  default_variables.setdefault('OS', gyp.common.GetFlavor(params))


def Compilable(filename):
  """Return true if the file is compilable (should be in OBJS)."""
  return any(filename.endswith(e) for e in COMPILABLE_EXTENSIONS)


def Linkable(filename):
  """Return true if the file is linkable (should be on the link line)."""
  return filename.endswith('.o')


def NormjoinPathForceCMakeSource(base_path, rel_path):
  """Resolves rel_path against base_path and returns the result.

  If rel_path is an absolute path it is returned unchanged.
  Otherwise it is resolved against base_path and normalized.
  If the result is a relative path, it is forced to be relative to the
  CMakeLists.txt.
  """
  if os.path.isabs(rel_path):
    return rel_path
  if any([rel_path.startswith(var) for var in FULL_PATH_VARS]):
    return rel_path
  # TODO: do we need to check base_path for absolute variables as well?
  return os.path.join('${CMAKE_SOURCE_DIR}',
                      os.path.normpath(os.path.join(base_path, rel_path)))


def NormjoinPath(base_path, rel_path):
  """Resolves rel_path against base_path and returns the result.
  TODO: what is this really used for?
  If rel_path begins with '$' it is returned unchanged.
  Otherwise it is resolved against base_path if relative, then normalized.
  """
  if rel_path.startswith('$') and not rel_path.startswith('${configuration}'):
    return rel_path
  return os.path.normpath(os.path.join(base_path, rel_path))


def CMakeStringEscape(a):
  """Escapes the string 'a' for use inside a CMake string.

  This means escaping
  '\' otherwise it may be seen as modifying the next character
  '"' otherwise it will end the string
  ';' otherwise the string becomes a list

  The following do not need to be escaped
  '#' when the lexer is in string state, this does not start a comment

  The following are yet unknown
  '$' generator variables (like ${obj}) must not be escaped,
      but text $ should be escaped
      what is wanted is to know which $ come from generator variables
  """
  return a.replace('\\', '\\\\').replace(';', '\\;').replace('"', '\\"')


def SetFileProperty(output, source_name, property_name, values, sep):
  """Given a set of source file, sets the given property on them."""
  output.write('set_source_files_properties(')
  output.write(source_name)
  output.write(' PROPERTIES ')
  output.write(property_name)
  output.write(' "')
  for value in values:
    output.write(CMakeStringEscape(value))
    output.write(sep)
  output.write('")\n')


def SetFilesProperty(output, source_names, property_name, values, sep):
  """Given a set of source files, sets the given property on them."""
  output.write('set_source_files_properties(\n')
  for source_name in source_names:
    output.write('  ')
    output.write(source_name)
    output.write('\n')
  output.write(' PROPERTIES\n  ')
  output.write(property_name)
  output.write(' "')
  for value in values:
    output.write(CMakeStringEscape(value))
    output.write(sep)
  output.write('"\n)\n')


def SetTargetProperty(output, target_name, property_name, values, sep=''):
  """Given a target, sets the given property."""
  output.write('set_target_properties(')
  output.write(target_name)
  output.write(' PROPERTIES ')
  output.write(property_name)
  output.write(' "')
  for value in values:
    output.write(CMakeStringEscape(value))
    output.write(sep)
  output.write('")\n')


def SetVariable(output, variable_name, value):
  """Sets a CMake variable."""
  output.write('set(')
  output.write(variable_name)
  output.write(' "')
  output.write(CMakeStringEscape(value))
  output.write('")\n')


def SetVariableList(output, variable_name, values):
  """Sets a CMake variable to a list."""
  if not values:
    return SetVariable(output, variable_name, "")
  if len(values) == 1:
    return SetVariable(output, variable_name, values[0])
  output.write('list(APPEND ')
  output.write(variable_name)
  output.write('\n  "')
  output.write('"\n  "'.join([CMakeStringEscape(value) for value in values]))
  output.write('")\n')


def UnsetVariable(output, variable_name):
  """Unsets a CMake variable."""
  output.write('unset(')
  output.write(variable_name)
  output.write(')\n')


def WriteVariable(output, variable_name, prepend=None):
  if prepend:
    output.write(prepend)
  output.write('${')
  output.write(variable_name)
  output.write('}')


class CMakeTargetType:
  def __init__(self, command, modifier, property_modifier):
    self.command = command
    self.modifier = modifier
    self.property_modifier = property_modifier


cmake_target_type_from_gyp_target_type = {
  'executable': CMakeTargetType('add_executable', None, 'RUNTIME'),
  'static_library': CMakeTargetType('add_library', 'STATIC', 'ARCHIVE'),
  'shared_library': CMakeTargetType('add_library', 'SHARED', 'LIBRARY'),
  'loadable_module': CMakeTargetType('add_library', 'MODULE', 'LIBRARY'),
  'none': CMakeTargetType('add_custom_target', 'SOURCES', None),
}


def StringToCMakeTargetName(a):
  """Converts the given string 'a' to a valid CMake target name.

  All invalid characters are replaced by '_'.
  Invalid for cmake: ' ', '/', '(', ')'
  Invalid for make: ':'
  Invalid for unknown reasons but cause failures: '.'
  """
  return a.translate(string.maketrans(' /():.', '______'))


def WriteActions(target_name, actions, extra_sources, extra_deps,
                 path_to_gyp, output):
  """Write CMake for the 'actions' in the target.

  Args:
    target_name: the name of the CMake target being generated.
    actions: the Gyp 'actions' dict for this target.
    extra_sources: [(<cmake_src>, <src>)] to append with generated source files.
    extra_deps: [<cmake_taget>] to append with generated targets.
    path_to_gyp: relative path from CMakeLists.txt being generated to
        the Gyp file in which the target being generated is defined.
  """
  for action in actions:
    action_name = StringToCMakeTargetName(action['action_name'])
    action_target_name = '%s__%s' % (target_name, action_name)

    inputs = action['inputs']
    inputs_name = action_target_name + '__input'
    SetVariableList(output, inputs_name,
        [NormjoinPathForceCMakeSource(path_to_gyp, dep) for dep in inputs])

    outputs = action['outputs']
    cmake_outputs = [NormjoinPathForceCMakeSource(path_to_gyp, out)
                     for out in outputs]
    outputs_name = action_target_name + '__output'
    SetVariableList(output, outputs_name, cmake_outputs)

    # Build up a list of outputs.
    # Collect the output dirs we'll need.
    dirs = set(dir for dir in (os.path.dirname(o) for o in outputs) if dir)

    if int(action.get('process_outputs_as_sources', False)):
      extra_sources.extend(zip(cmake_outputs, outputs))

    # add_custom_command
    output.write('add_custom_command(OUTPUT ')
    WriteVariable(output, outputs_name)
    output.write('\n')

    if len(dirs) > 0:
      for directory in dirs:
        output.write('  COMMAND ${CMAKE_COMMAND} -E make_directory ')
        output.write(directory)
        output.write('\n')

    output.write('  COMMAND ')
    output.write(gyp.common.EncodePOSIXShellList(action['action']))
    output.write('\n')

    output.write('  DEPENDS ')
    WriteVariable(output, inputs_name)
    output.write('\n')

    output.write('  WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/')
    output.write(path_to_gyp)
    output.write('\n')

    output.write('  COMMENT ')
    if 'message' in action:
      output.write(action['message'])
    else:
      output.write(action_target_name)
    output.write('\n')

    output.write('  VERBATIM\n')
    output.write(')\n')

    # add_custom_target
    output.write('add_custom_target(')
    output.write(action_target_name)
    output.write('\n  DEPENDS ')
    WriteVariable(output, outputs_name)
    output.write('\n  SOURCES ')
    WriteVariable(output, inputs_name)
    output.write('\n)\n')

    extra_deps.append(action_target_name)


def NormjoinRulePathForceCMakeSource(base_path, rel_path, rule_source):
  if rel_path.startswith(("${RULE_INPUT_PATH}","${RULE_INPUT_DIRNAME}")):
    if any([rule_source.startswith(var) for var in FULL_PATH_VARS]):
      return rel_path
  return NormjoinPathForceCMakeSource(base_path, rel_path)


def WriteRules(target_name, rules, extra_sources, extra_deps,
               path_to_gyp, output):
  """Write CMake for the 'rules' in the target.

  Args:
    target_name: the name of the CMake target being generated.
    actions: the Gyp 'actions' dict for this target.
    extra_sources: [(<cmake_src>, <src>)] to append with generated source files.
    extra_deps: [<cmake_taget>] to append with generated targets.
    path_to_gyp: relative path from CMakeLists.txt being generated to
        the Gyp file in which the target being generated is defined.
  """
  for rule in rules:
    rule_name = StringToCMakeTargetName(target_name + '__' + rule['rule_name'])

    inputs = rule.get('inputs', [])
    inputs_name = rule_name + '__input'
    SetVariableList(output, inputs_name,
        [NormjoinPathForceCMakeSource(path_to_gyp, dep) for dep in inputs])
    outputs = rule['outputs']
    var_outputs = []

    for count, rule_source in enumerate(rule.get('rule_sources', [])):
      action_name = rule_name + '_' + str(count)

      rule_source_dirname, rule_source_basename = os.path.split(rule_source)
      rule_source_root, rule_source_ext = os.path.splitext(rule_source_basename)

      SetVariable(output, 'RULE_INPUT_PATH', rule_source)
      SetVariable(output, 'RULE_INPUT_DIRNAME', rule_source_dirname)
      SetVariable(output, 'RULE_INPUT_NAME', rule_source_basename)
      SetVariable(output, 'RULE_INPUT_ROOT', rule_source_root)
      SetVariable(output, 'RULE_INPUT_EXT', rule_source_ext)

      # Build up a list of outputs.
      # Collect the output dirs we'll need.
      dirs = set(dir for dir in (os.path.dirname(o) for o in outputs) if dir)

      # Create variables for the output, as 'local' variable will be unset.
      these_outputs = []
      for output_index, out in enumerate(outputs):
        output_name = action_name + '_' + str(output_index)
        SetVariable(output, output_name,
                     NormjoinRulePathForceCMakeSource(path_to_gyp, out,
                                                      rule_source))
        if int(rule.get('process_outputs_as_sources', False)):
          extra_sources.append(('${' + output_name + '}', out))
        these_outputs.append('${' + output_name + '}')
        var_outputs.append('${' + output_name + '}')

      # add_custom_command
      output.write('add_custom_command(OUTPUT\n')
      for out in these_outputs:
        output.write('  ')
        output.write(out)
        output.write('\n')

      for directory in dirs:
        output.write('  COMMAND ${CMAKE_COMMAND} -E make_directory ')
        output.write(directory)
        output.write('\n')

      output.write('  COMMAND ')
      output.write(gyp.common.EncodePOSIXShellList(rule['action']))
      output.write('\n')

      output.write('  DEPENDS ')
      WriteVariable(output, inputs_name)
      output.write(' ')
      output.write(NormjoinPath(path_to_gyp, rule_source))
      output.write('\n')

      # CMAKE_SOURCE_DIR is where the CMakeLists.txt lives.
      # The cwd is the current build directory.
      output.write('  WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/')
      output.write(path_to_gyp)
      output.write('\n')

      output.write('  COMMENT ')
      if 'message' in rule:
        output.write(rule['message'])
      else:
        output.write(action_name)
      output.write('\n')

      output.write('  VERBATIM\n')
      output.write(')\n')

      UnsetVariable(output, 'RULE_INPUT_PATH')
      UnsetVariable(output, 'RULE_INPUT_DIRNAME')
      UnsetVariable(output, 'RULE_INPUT_NAME')
      UnsetVariable(output, 'RULE_INPUT_ROOT')
      UnsetVariable(output, 'RULE_INPUT_EXT')

    # add_custom_target
    output.write('add_custom_target(')
    output.write(rule_name)
    output.write(' DEPENDS\n')
    for out in var_outputs:
      output.write('  ')
      output.write(out)
      output.write('\n')
    output.write('SOURCES ')
    WriteVariable(output, inputs_name)
    output.write('\n')
    for rule_source in rule.get('rule_sources', []):
      output.write('  ')
      output.write(NormjoinPath(path_to_gyp, rule_source))
      output.write('\n')
    output.write(')\n')

    extra_deps.append(rule_name)


def WriteCopies(target_name, copies, extra_deps, path_to_gyp, output):
  """Write CMake for the 'copies' in the target.

  Args:
    target_name: the name of the CMake target being generated.
    actions: the Gyp 'actions' dict for this target.
    extra_deps: [<cmake_taget>] to append with generated targets.
    path_to_gyp: relative path from CMakeLists.txt being generated to
        the Gyp file in which the target being generated is defined.
  """
  copy_name = target_name + '__copies'

  # CMake gets upset with custom targets with OUTPUT which specify no output.
  have_copies = any(copy['files'] for copy in copies)
  if not have_copies:
    output.write('add_custom_target(')
    output.write(copy_name)
    output.write(')\n')
    extra_deps.append(copy_name)
    return

  class Copy:
    def __init__(self, ext, command):
      self.cmake_inputs = []
      self.cmake_outputs = []
      self.gyp_inputs = []
      self.gyp_outputs = []
      self.ext = ext
      self.inputs_name = None
      self.outputs_name = None
      self.command = command

  file_copy = Copy('', 'copy')
  dir_copy = Copy('_dirs', 'copy_directory')

  for copy in copies:
    files = copy['files']
    destination = copy['destination']
    for src in files:
      path = os.path.normpath(src)
      basename = os.path.split(path)[1]
      dst = os.path.join(destination, basename)

      copy = file_copy if os.path.basename(src) else dir_copy

      copy.cmake_inputs.append(NormjoinPath(path_to_gyp, src))
      copy.cmake_outputs.append(NormjoinPathForceCMakeSource(path_to_gyp, dst))
      copy.gyp_inputs.append(src)
      copy.gyp_outputs.append(dst)

  for copy in (file_copy, dir_copy):
    if copy.cmake_inputs:
      copy.inputs_name = copy_name + '__input' + copy.ext
      SetVariableList(output, copy.inputs_name, copy.cmake_inputs)

      copy.outputs_name = copy_name + '__output' + copy.ext
      SetVariableList(output, copy.outputs_name, copy.cmake_outputs)

  # add_custom_command
  output.write('add_custom_command(\n')

  output.write('OUTPUT')
  for copy in (file_copy, dir_copy):
    if copy.outputs_name:
      WriteVariable(output, copy.outputs_name, ' ')
  output.write('\n')

  for copy in (file_copy, dir_copy):
    for src, dst in zip(copy.gyp_inputs, copy.gyp_outputs):
      # 'cmake -E copy src dst' will create the 'dst' directory if needed.
      output.write('COMMAND ${CMAKE_COMMAND} -E %s ' % copy.command)
      output.write(src)
      output.write(' ')
      output.write(dst)
      output.write("\n")

  output.write('DEPENDS')
  for copy in (file_copy, dir_copy):
    if copy.inputs_name:
      WriteVariable(output, copy.inputs_name, ' ')
  output.write('\n')

  output.write('WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/')
  output.write(path_to_gyp)
  output.write('\n')

  output.write('COMMENT Copying for ')
  output.write(target_name)
  output.write('\n')

  output.write('VERBATIM\n')
  output.write(')\n')

  # add_custom_target
  output.write('add_custom_target(')
  output.write(copy_name)
  output.write('\n  DEPENDS')
  for copy in (file_copy, dir_copy):
    if copy.outputs_name:
      WriteVariable(output, copy.outputs_name, ' ')
  output.write('\n  SOURCES')
  if file_copy.inputs_name:
    WriteVariable(output, file_copy.inputs_name, ' ')
  output.write('\n)\n')

  extra_deps.append(copy_name)


def CreateCMakeTargetBaseName(qualified_target):
  """This is the name we would like the target to have."""
  _, gyp_target_name, gyp_target_toolset = (
      gyp.common.ParseQualifiedTarget(qualified_target))
  cmake_target_base_name = gyp_target_name
  if gyp_target_toolset and gyp_target_toolset != 'target':
    cmake_target_base_name += '_' + gyp_target_toolset
  return StringToCMakeTargetName(cmake_target_base_name)


def CreateCMakeTargetFullName(qualified_target):
  """An unambiguous name for the target."""
  gyp_file, gyp_target_name, gyp_target_toolset = (
      gyp.common.ParseQualifiedTarget(qualified_target))
  cmake_target_full_name = gyp_file + ':' + gyp_target_name
  if gyp_target_toolset and gyp_target_toolset != 'target':
    cmake_target_full_name += '_' + gyp_target_toolset
  return StringToCMakeTargetName(cmake_target_full_name)


class CMakeNamer(object):
  """Converts Gyp target names into CMake target names.

  CMake requires that target names be globally unique. One way to ensure
  this is to fully qualify the names of the targets. Unfortunatly, this
  ends up with all targets looking like "chrome_chrome_gyp_chrome" instead
  of just "chrome". If this generator were only interested in building, it
  would be possible to fully qualify all target names, then create
  unqualified target names which depend on all qualified targets which
  should have had that name. This is more or less what the 'make' generator
  does with aliases. However, one goal of this generator is to create CMake
  files for use with IDEs, and fully qualified names are not as user
  friendly.

  Since target name collision is rare, we do the above only when required.

  Toolset variants are always qualified from the base, as this is required for
  building. However, it also makes sense for an IDE, as it is possible for
  defines to be different.
  """
  def __init__(self, target_list):
    self.cmake_target_base_names_conficting = set()

    cmake_target_base_names_seen = set()
    for qualified_target in target_list:
      cmake_target_base_name = CreateCMakeTargetBaseName(qualified_target)

      if cmake_target_base_name not in cmake_target_base_names_seen:
        cmake_target_base_names_seen.add(cmake_target_base_name)
      else:
        self.cmake_target_base_names_conficting.add(cmake_target_base_name)

  def CreateCMakeTargetName(self, qualified_target):
    base_name = CreateCMakeTargetBaseName(qualified_target)
    if base_name in self.cmake_target_base_names_conficting:
      return CreateCMakeTargetFullName(qualified_target)
    return base_name


def WriteTarget(namer, qualified_target, target_dicts, build_dir, config_to_use,
                options, generator_flags, all_qualified_targets, output):

  # The make generator does this always.
  # TODO: It would be nice to be able to tell CMake all dependencies.
  circular_libs = generator_flags.get('circular', True)

  if not generator_flags.get('standalone', False):
    output.write('\n#')
    output.write(qualified_target)
    output.write('\n')

  gyp_file, _, _ = gyp.common.ParseQualifiedTarget(qualified_target)
  rel_gyp_file = gyp.common.RelativePath(gyp_file, options.toplevel_dir)
  rel_gyp_dir = os.path.dirname(rel_gyp_file)

  # Relative path from build dir to top dir.
  build_to_top = gyp.common.InvertRelativePath(build_dir, options.toplevel_dir)
  # Relative path from build dir to gyp dir.
  build_to_gyp = os.path.join(build_to_top, rel_gyp_dir)

  path_from_cmakelists_to_gyp = build_to_gyp

  spec = target_dicts.get(qualified_target, {})
  config = spec.get('configurations', {}).get(config_to_use, {})

  target_name = spec.get('target_name', '<missing target name>')
  target_type = spec.get('type', '<missing target type>')
  target_toolset = spec.get('toolset')

  SetVariable(output, 'TARGET', target_name)
  SetVariable(output, 'TOOLSET', target_toolset)

  cmake_target_name = namer.CreateCMakeTargetName(qualified_target)

  extra_sources = []
  extra_deps = []

  # Actions must come first, since they can generate more OBJs for use below.
  if 'actions' in spec:
    WriteActions(cmake_target_name, spec['actions'], extra_sources, extra_deps,
                 path_from_cmakelists_to_gyp, output)

  # Rules must be early like actions.
  if 'rules' in spec:
    WriteRules(cmake_target_name, spec['rules'], extra_sources, extra_deps,
               path_from_cmakelists_to_gyp, output)

  # Copies
  if 'copies' in spec:
    WriteCopies(cmake_target_name, spec['copies'], extra_deps,
                path_from_cmakelists_to_gyp, output)

  # Target and sources
  srcs = spec.get('sources', [])

  # Gyp separates the sheep from the goats based on file extensions.
  def partition(l, p):
    return reduce(lambda x, e: x[not p(e)].append(e) or x, l, ([], []))
  compilable_srcs, other_srcs = partition(srcs, Compilable)

  # CMake gets upset when executable targets provide no sources.
  if target_type == 'executable' and not compilable_srcs and not extra_sources:
    print ('Executable %s has no complilable sources, treating as "none".' %
                       target_name                                         )
    target_type = 'none'

  cmake_target_type = cmake_target_type_from_gyp_target_type.get(target_type)
  if cmake_target_type is None:
    print ('Target %s has unknown target type %s, skipping.' %
          (        target_name,               target_type  ) )
    return

  other_srcs_name = None
  if other_srcs:
    other_srcs_name = cmake_target_name + '__other_srcs'
    SetVariableList(output, other_srcs_name,
        [NormjoinPath(path_from_cmakelists_to_gyp, src) for src in other_srcs])

  # CMake is opposed to setting linker directories and considers the practice
  # of setting linker directories dangerous. Instead, it favors the use of
  # find_library and passing absolute paths to target_link_libraries.
  # However, CMake does provide the command link_directories, which adds
  # link directories to targets defined after it is called.
  # As a result, link_directories must come before the target definition.
  # CMake unfortunately has no means of removing entries from LINK_DIRECTORIES.
  library_dirs = config.get('library_dirs')
  if library_dirs is not None:
    output.write('link_directories(')
    for library_dir in library_dirs:
      output.write(' ')
      output.write(NormjoinPath(path_from_cmakelists_to_gyp, library_dir))
      output.write('\n')
    output.write(')\n')

  output.write(cmake_target_type.command)
  output.write('(')
  output.write(cmake_target_name)

  if cmake_target_type.modifier is not None:
    output.write(' ')
    output.write(cmake_target_type.modifier)

  if other_srcs_name:
    WriteVariable(output, other_srcs_name, ' ')

  output.write('\n')

  for src in compilable_srcs:
    output.write('  ')
    output.write(NormjoinPath(path_from_cmakelists_to_gyp, src))
    output.write('\n')
  for extra_source in extra_sources:
    output.write('  ')
    src, _ = extra_source
    output.write(NormjoinPath(path_from_cmakelists_to_gyp, src))
    output.write('\n')

  output.write(')\n')

  # Output name and location.
  if target_type != 'none':
    # Mark uncompiled sources as uncompiled.
    if other_srcs_name:
      output.write('set_source_files_properties(')
      WriteVariable(output, other_srcs_name, '')
      output.write(' PROPERTIES HEADER_FILE_ONLY "TRUE")\n')

    # Output directory
    target_output_directory = spec.get('product_dir')
    if target_output_directory is None:
      if target_type in ('executable', 'loadable_module'):
        target_output_directory = generator_default_variables['PRODUCT_DIR']
      elif target_type in ('shared_library'):
        target_output_directory = '${builddir}/lib.${TOOLSET}'
      elif spec.get('standalone_static_library', False):
        target_output_directory = generator_default_variables['PRODUCT_DIR']
      else:
        base_path = gyp.common.RelativePath(os.path.dirname(gyp_file),
                                            options.toplevel_dir)
        target_output_directory = '${obj}.${TOOLSET}'
        target_output_directory = (
            os.path.join(target_output_directory, base_path))

    cmake_target_output_directory = NormjoinPathForceCMakeSource(
                                        path_from_cmakelists_to_gyp,
                                        target_output_directory)
    SetTargetProperty(output,
        cmake_target_name,
        cmake_target_type.property_modifier + '_OUTPUT_DIRECTORY',
        cmake_target_output_directory)

    # Output name
    default_product_prefix = ''
    default_product_name = target_name
    default_product_ext = ''
    if target_type == 'static_library':
      static_library_prefix = generator_default_variables['STATIC_LIB_PREFIX']
      default_product_name = RemovePrefix(default_product_name,
                                          static_library_prefix)
      default_product_prefix = static_library_prefix
      default_product_ext = generator_default_variables['STATIC_LIB_SUFFIX']

    elif target_type in ('loadable_module', 'shared_library'):
      shared_library_prefix = generator_default_variables['SHARED_LIB_PREFIX']
      default_product_name = RemovePrefix(default_product_name,
                                          shared_library_prefix)
      default_product_prefix = shared_library_prefix
      default_product_ext = generator_default_variables['SHARED_LIB_SUFFIX']

    elif target_type != 'executable':
      print ('ERROR: What output file should be generated?',
              'type', target_type, 'target', target_name)

    product_prefix = spec.get('product_prefix', default_product_prefix)
    product_name = spec.get('product_name', default_product_name)
    product_ext = spec.get('product_extension')
    if product_ext:
      product_ext = '.' + product_ext
    else:
      product_ext = default_product_ext

    SetTargetProperty(output, cmake_target_name, 'PREFIX', product_prefix)
    SetTargetProperty(output, cmake_target_name,
                        cmake_target_type.property_modifier + '_OUTPUT_NAME',
                        product_name)
    SetTargetProperty(output, cmake_target_name, 'SUFFIX', product_ext)

    # Make the output of this target referenceable as a source.
    cmake_target_output_basename = product_prefix + product_name + product_ext
    cmake_target_output = os.path.join(cmake_target_output_directory,
                                       cmake_target_output_basename)
    SetFileProperty(output, cmake_target_output, 'GENERATED', ['TRUE'], '')

  # Let CMake know if the 'all' target should depend on this target.
  exclude_from_all = ('TRUE' if qualified_target not in all_qualified_targets
                             else 'FALSE')
  SetTargetProperty(output, cmake_target_name,
                      'EXCLUDE_FROM_ALL', exclude_from_all)
  for extra_target_name in extra_deps:
    SetTargetProperty(output, extra_target_name,
                        'EXCLUDE_FROM_ALL', exclude_from_all)

  # Includes
  includes = config.get('include_dirs')
  if includes:
    # This (target include directories) is what requires CMake 2.8.8
    includes_name = cmake_target_name + '__include_dirs'
    SetVariableList(output, includes_name,
        [NormjoinPathForceCMakeSource(path_from_cmakelists_to_gyp, include)
         for include in includes])
    output.write('set_property(TARGET ')
    output.write(cmake_target_name)
    output.write(' APPEND PROPERTY INCLUDE_DIRECTORIES ')
    WriteVariable(output, includes_name, '')
    output.write(')\n')

  # Defines
  defines = config.get('defines')
  if defines is not None:
    SetTargetProperty(output,
                        cmake_target_name,
                        'COMPILE_DEFINITIONS',
                        defines,
                        ';')

  # Compile Flags - http://www.cmake.org/Bug/view.php?id=6493
  # CMake currently does not have target C and CXX flags.
  # So, instead of doing...

  # cflags_c = config.get('cflags_c')
  # if cflags_c is not None:
  #   SetTargetProperty(output, cmake_target_name,
  #                       'C_COMPILE_FLAGS', cflags_c, ' ')

  # cflags_cc = config.get('cflags_cc')
  # if cflags_cc is not None:
  #   SetTargetProperty(output, cmake_target_name,
  #                       'CXX_COMPILE_FLAGS', cflags_cc, ' ')

  # Instead we must...
  s_sources = []
  c_sources = []
  cxx_sources = []
  for src in srcs:
    _, ext = os.path.splitext(src)
    src_type = COMPILABLE_EXTENSIONS.get(ext, None)

    if src_type == 's':
      s_sources.append(NormjoinPath(path_from_cmakelists_to_gyp, src))

    if src_type == 'cc':
      c_sources.append(NormjoinPath(path_from_cmakelists_to_gyp, src))

    if src_type == 'cxx':
      cxx_sources.append(NormjoinPath(path_from_cmakelists_to_gyp, src))

  for extra_source in extra_sources:
    src, real_source = extra_source
    _, ext = os.path.splitext(real_source)
    src_type = COMPILABLE_EXTENSIONS.get(ext, None)

    if src_type == 's':
      s_sources.append(NormjoinPath(path_from_cmakelists_to_gyp, src))

    if src_type == 'cc':
      c_sources.append(NormjoinPath(path_from_cmakelists_to_gyp, src))

    if src_type == 'cxx':
      cxx_sources.append(NormjoinPath(path_from_cmakelists_to_gyp, src))

  cflags = config.get('cflags', [])
  cflags_c = config.get('cflags_c', [])
  cflags_cxx = config.get('cflags_cc', [])
  if c_sources and not (s_sources or cxx_sources):
    flags = []
    flags.extend(cflags)
    flags.extend(cflags_c)
    SetTargetProperty(output, cmake_target_name, 'COMPILE_FLAGS', flags, ' ')

  elif cxx_sources and not (s_sources or c_sources):
    flags = []
    flags.extend(cflags)
    flags.extend(cflags_cxx)
    SetTargetProperty(output, cmake_target_name, 'COMPILE_FLAGS', flags, ' ')

  else:
    if s_sources and cflags:
      SetFilesProperty(output, s_sources, 'COMPILE_FLAGS', cflags, ' ')

    if c_sources and (cflags or cflags_c):
      flags = []
      flags.extend(cflags)
      flags.extend(cflags_c)
      SetFilesProperty(output, c_sources, 'COMPILE_FLAGS', flags, ' ')

    if cxx_sources and (cflags or cflags_cxx):
      flags = []
      flags.extend(cflags)
      flags.extend(cflags_cxx)
      SetFilesProperty(output, cxx_sources, 'COMPILE_FLAGS', flags, ' ')

  # Have assembly link as c if there are no other files
  if not c_sources and not cxx_sources and s_sources:
    SetTargetProperty(output, cmake_target_name, 'LINKER_LANGUAGE', ['C'])

  # Linker flags
  ldflags = config.get('ldflags')
  if ldflags is not None:
    SetTargetProperty(output, cmake_target_name, 'LINK_FLAGS', ldflags, ' ')

  # Note on Dependencies and Libraries:
  # CMake wants to handle link order, resolving the link line up front.
  # Gyp does not retain or enforce specifying enough information to do so.
  # So do as other gyp generators and use --start-group and --end-group.
  # Give CMake as little information as possible so that it doesn't mess it up.

  # Dependencies
  rawDeps = spec.get('dependencies', [])

  static_deps = []
  shared_deps = []
  other_deps = []
  for rawDep in rawDeps:
    dep_cmake_name = namer.CreateCMakeTargetName(rawDep)
    dep_spec = target_dicts.get(rawDep, {})
    dep_target_type = dep_spec.get('type', None)

    if dep_target_type == 'static_library':
      static_deps.append(dep_cmake_name)
    elif dep_target_type ==  'shared_library':
      shared_deps.append(dep_cmake_name)
    else:
      other_deps.append(dep_cmake_name)

  # ensure all external dependencies are complete before internal dependencies
  # extra_deps currently only depend on their own deps, so otherwise run early
  if static_deps or shared_deps or other_deps:
    for extra_dep in extra_deps:
      output.write('add_dependencies(')
      output.write(extra_dep)
      output.write('\n')
      for deps in (static_deps, shared_deps, other_deps):
        for dep in gyp.common.uniquer(deps):
          output.write('  ')
          output.write(dep)
          output.write('\n')
      output.write(')\n')

  linkable = target_type in ('executable', 'loadable_module', 'shared_library')
  other_deps.extend(extra_deps)
  if other_deps or (not linkable and (static_deps or shared_deps)):
    output.write('add_dependencies(')
    output.write(cmake_target_name)
    output.write('\n')
    for dep in gyp.common.uniquer(other_deps):
      output.write('  ')
      output.write(dep)
      output.write('\n')
    if not linkable:
      for deps in (static_deps, shared_deps):
        for lib_dep in gyp.common.uniquer(deps):
          output.write('  ')
          output.write(lib_dep)
          output.write('\n')
    output.write(')\n')

  # Libraries
  if linkable:
    external_libs = [lib for lib in spec.get('libraries', []) if len(lib) > 0]
    if external_libs or static_deps or shared_deps:
      output.write('target_link_libraries(')
      output.write(cmake_target_name)
      output.write('\n')
      if static_deps:
        write_group = circular_libs and len(static_deps) > 1
        if write_group:
          output.write('-Wl,--start-group\n')
        for dep in gyp.common.uniquer(static_deps):
          output.write('  ')
          output.write(dep)
          output.write('\n')
        if write_group:
          output.write('-Wl,--end-group\n')
      if shared_deps:
        for dep in gyp.common.uniquer(shared_deps):
          output.write('  ')
          output.write(dep)
          output.write('\n')
      if external_libs:
        for lib in gyp.common.uniquer(external_libs):
          output.write('  ')
          output.write(lib)
          output.write('\n')

      output.write(')\n')

  UnsetVariable(output, 'TOOLSET')
  UnsetVariable(output, 'TARGET')


def GenerateOutputForConfig(target_list, target_dicts, data,
                            params, config_to_use):
  options = params['options']
  generator_flags = params['generator_flags']

  # generator_dir: relative path from pwd to where make puts build files.
  # Makes migrating from make to cmake easier, cmake doesn't put anything here.
  # Each Gyp configuration creates a different CMakeLists.txt file
  # to avoid incompatibilities between Gyp and CMake configurations.
  generator_dir = os.path.relpath(options.generator_output or '.')

  # output_dir: relative path from generator_dir to the build directory.
  output_dir = generator_flags.get('output_dir', 'out')

  # build_dir: relative path from source root to our output files.
  # e.g. "out/Debug"
  build_dir = os.path.normpath(os.path.join(generator_dir,
                                            output_dir,
                                            config_to_use))

  toplevel_build = os.path.join(options.toplevel_dir, build_dir)

  output_file = os.path.join(toplevel_build, 'CMakeLists.txt')
  gyp.common.EnsureDirExists(output_file)

  output = open(output_file, 'w')
  output.write('cmake_minimum_required(VERSION 2.8.8 FATAL_ERROR)\n')
  output.write('cmake_policy(VERSION 2.8.8)\n')

  _, project_target, _ = gyp.common.ParseQualifiedTarget(target_list[-1])
  output.write('project(')
  output.write(project_target)
  output.write(')\n')

  SetVariable(output, 'configuration', config_to_use)

  # The following appears to be as-yet undocumented.
  # http://public.kitware.com/Bug/view.php?id=8392
  output.write('enable_language(ASM)\n')
  # ASM-ATT does not support .S files.
  # output.write('enable_language(ASM-ATT)\n')

  SetVariable(output, 'builddir', '${CMAKE_BINARY_DIR}')
  SetVariable(output, 'obj', '${builddir}/obj')
  output.write('\n')

  # TODO: Undocumented/unsupported (the CMake Java generator depends on it).
  # CMake by default names the object resulting from foo.c to be foo.c.o.
  # Gyp traditionally names the object resulting from foo.c foo.o.
  # This should be irrelevant, but some targets extract .o files from .a
  # and depend on the name of the extracted .o files.
  output.write('set(CMAKE_C_OUTPUT_EXTENSION_REPLACE 1)\n')
  output.write('set(CMAKE_CXX_OUTPUT_EXTENSION_REPLACE 1)\n')
  output.write('\n')

  namer = CMakeNamer(target_list)

  # The list of targets upon which the 'all' target should depend.
  # CMake has it's own implicit 'all' target, one is not created explicitly.
  all_qualified_targets = set()
  for build_file in params['build_files']:
    for qualified_target in gyp.common.AllTargets(target_list,
                                                  target_dicts,
                                                  os.path.normpath(build_file)):
      all_qualified_targets.add(qualified_target)

  for qualified_target in target_list:
    WriteTarget(namer, qualified_target, target_dicts, build_dir, config_to_use,
                options, generator_flags, all_qualified_targets, output)

  output.close()


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

  # generator_dir: relative path from pwd to where make puts build files.
  # Makes migrating from make to cmake easier, cmake doesn't put anything here.
  generator_dir = os.path.relpath(options.generator_output or '.')

  # output_dir: relative path from generator_dir to the build directory.
  output_dir = generator_flags.get('output_dir', 'out')

  for config_name in configurations:
    # build_dir: relative path from source root to our output files.
    # e.g. "out/Debug"
    build_dir = os.path.normpath(os.path.join(generator_dir,
                                              output_dir,
                                              config_name))
    arguments = ['cmake', '-G', 'Ninja']
    print 'Generating [%s]: %s' % (config_name, arguments)
    subprocess.check_call(arguments, cwd=build_dir)

    arguments = ['ninja', '-C', build_dir]
    print 'Building [%s]: %s' % (config_name, arguments)
    subprocess.check_call(arguments)


def CallGenerateOutputForConfig(arglist):
  # Ignore the interrupt signal so that the parent process catches it and
  # kills all multiprocessing children.
  signal.signal(signal.SIGINT, signal.SIG_IGN)

  target_list, target_dicts, data, params, config_name = arglist
  GenerateOutputForConfig(target_list, target_dicts, data, params, config_name)


def GenerateOutput(target_list, target_dicts, data, params):
  user_config = params.get('generator_flags', {}).get('config', None)
  if user_config:
    GenerateOutputForConfig(target_list, target_dicts, data,
                            params, user_config)
  else:
    config_names = target_dicts[target_list[0]]['configurations'].keys()
    if params['parallel']:
      try:
        pool = multiprocessing.Pool(len(config_names))
        arglists = []
        for config_name in config_names:
          arglists.append((target_list, target_dicts, data,
                           params, config_name))
          pool.map(CallGenerateOutputForConfig, arglists)
      except KeyboardInterrupt, e:
        pool.terminate()
        raise e
    else:
      for config_name in config_names:
        GenerateOutputForConfig(target_list, target_dicts, data,
                                params, config_name)
