| Index: ios/build/packaging/link_dependencies.py
|
| diff --git a/ios/build/packaging/link_dependencies.py b/ios/build/packaging/link_dependencies.py
|
| new file mode 100755
|
| index 0000000000000000000000000000000000000000..df541a63758a734f7fce000adb9a8ad7e4058369
|
| --- /dev/null
|
| +++ b/ios/build/packaging/link_dependencies.py
|
| @@ -0,0 +1,149 @@
|
| +#!/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 subprocess
|
| +
|
| +
|
| +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
|
| + """
|
| + p = subprocess.Popen(['libtool', '-o', output] + inputs)
|
| + p.communicate()
|
| + 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()
|
|
|