#!/usr/bin/env python
#
# Copyright 2014 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Links the deps of a binary into a static library.

Run with a working directory, the name of a binary target, and the name of the
static library that should be produced. For example:

  $ link_dependencies.py out/Release-iphoneos \
                         crnet_consumer.app/crnet_consumer \
                         out/Release-iphoneos/crnet_standalone.a
"""

import argparse
import os
import re
import subprocess
import sys


class SubprocessError(Exception):
  pass


def extract_inputs(query_result, prefix=''):
  """Extracts inputs from ninja query output.

  Given 'ninja -t query' output for a target, extracts all the inputs of that
  target, prefixing them with an optional prefix. Inputs prefixed with '|' are
  implicit, so we discard them as they shouldn't be linked into the resulting
  binary (these are things like the .ninja files themselves, dep lists, and so
  on).

  Example query result:
    arch/crnet_consumer.armv7:
      input: link
        obj/[long path...]/crnet_consumer.crnet_consumer_app_delegate.armv7.o
        obj/[long path...]/crnet_consumer.crnet_consumer_view_controller.armv7.o
        obj/[long path...]/crnet_consumer.main.armv7.o
        libcrnet.a
        libdata_reduction_proxy_code_browser.a
        ... many more inputs ...
        liburl_util.a
        | obj/content/content.actions_depends.stamp
        | gen/components/data_reduction_proxy/common/version.h
        | obj/ui/resources/ui_resources.actions_rules_copies.stamp
        ... more implicit inputs ...
    outputs:
      crnet_consumer.app/crnet_consumer

  Args:
    query_result: output from 'ninja -t query'
    prefix: optional file system path to prefix to returned inputs

  Returns:
    A list of the inputs.
  """
  extracting = False
  inputs = []
  for line in query_result.splitlines():
    if line.startswith('  input:'):
      extracting = True
    elif line.startswith('  outputs:'):
      extracting = False
    elif extracting and '|' not in line:
      inputs.append(os.path.join(prefix, line.strip()))
  return inputs


def query_ninja(target, workdir, prefix=''):
  """Returns the inputs for the named target.

  Queries ninja for the set of inputs of the named target, then returns the list
  of inputs to that target.

  Args:
    target: ninja target name to query for
    workdir: workdir for ninja
    prefix: optional file system path to prefix to returned inputs

  Returns:
    A list of file system paths to the inputs to the named target.
  """
  proc = subprocess.Popen(['ninja', '-C', workdir, '-t', 'query', target],
                          stdout=subprocess.PIPE)
  stdout, _ = proc.communicate()
  return extract_inputs(stdout, prefix)


def is_library(target):
  """Returns whether target is a library file."""
  return os.path.splitext(target)[1] in ('.a', '.o')


def library_deps(targets, workdir, query=query_ninja):
  """Returns the set of library dependencies for the supplied targets.

  The entries in the targets list can be either a static library, an object
  file, or an executable. Static libraries and object files are incorporated
  directly; executables are treated as being thin executable inputs to a fat
  executable link step, and have their own library dependencies added in their
  place.

  Args:
    targets: list of targets to include library dependencies from
    workdir: working directory to run ninja queries in
    query: function taking target, workdir, and prefix and returning an input
           set
  Returns:
    Set of library dependencies.
  """
  deps = set()
  for target in targets:
    if is_library(target):
      deps.add(os.path.join(workdir, target))
    else:
      deps = deps.union(query(target, workdir, workdir))
  return deps


def link(output, inputs):
  """Links output from inputs using libtool.

  Args:
    output: file system path to desired output library
    inputs: list of file system paths to input libraries
  """
  libtool_re = re.compile(r'^.*libtool: (?:for architecture: \S* )?'
                          r'file: .* has no symbols$')
  p = subprocess.Popen(
      ['libtool', '-o', output] + inputs, stderr=subprocess.PIPE)
  _, err = p.communicate()
  for line in err.splitlines():
    if not libtool_re.match(line):
      print >>sys.stderr, line
  if p.returncode != 0:
    message = "subprocess libtool returned {0}".format(p.returncode)
    raise SubprocessError(message)


def main():
  parser = argparse.ArgumentParser(
      description='Link dependencies of a ninja target into a static library')
  parser.add_argument('workdir', nargs=1, help='ninja working directory')
  parser.add_argument('target', nargs=1, help='target to query for deps')
  parser.add_argument('output', nargs=1, help='path to output static library')
  args = parser.parse_args()

  inputs = query_ninja(args.target[0], args.workdir[0])
  link(args.output[0], list(library_deps(inputs, args.workdir[0])))


if __name__ == '__main__':
  main()
