#!/usr/bin/env python3
#
# Copyright (C) 2019 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Call cargo -v, parse its output, and generate Android.bp.

Usage: Run this script in a crate workspace root directory.
The Cargo.toml file should work at least for the host platform.

(1) Without other flags, "cargo2android.py --run"
    calls cargo clean, calls cargo build -v, and generates Android.bp.
    The cargo build only generates crates for the host,
    without test crates.

(2) To build crates for both host and device in Android.bp, use the
    --device flag, for example:
    cargo2android.py --run --device

    Note that cargo build is only called once with the default target
    x86_64-unknown-linux-gnu.

(3) To build default and test crates, for host and device, use both
    --device and --tests flags:
    cargo2android.py --run --device --tests

    This is equivalent to using the --cargo flag to add extra builds:
    cargo2android.py --run
      --cargo "build --target x86_64-unknown-linux-gnu"
      --cargo "build --tests --target x86_64-unknown-linux-gnu"

    Note that when there are tests for this module or for its reverse
    dependencies, these tests will be added to the TEST_MAPPING file.

If there are rustc warning messages, this script will add
a warning comment to the owner crate module in Android.bp.
"""

from __future__ import print_function
from update_crate_tests import TestMapping

import argparse
import glob
import json
import os
import os.path
import platform
import re
import shutil
import sys

# Some Rust packages include extra unwanted crates.
# This set contains all such excluded crate names.
EXCLUDED_CRATES = set(['protobuf_bin_gen_rust_do_not_use'])

RENAME_MAP = {
    # This map includes all changes to the default rust module names
    # to resolve name conflicts, avoid confusion, or work as plugin.
    'libbacktrace': 'libbacktrace_rust',
    'libbase': 'libbase_rust',
    'libfuse': 'libfuse_rust',
    'libgcc': 'libgcc_rust',
    'liblog': 'liblog_rust',
    'libminijail': 'libminijail_rust',
    'libsync': 'libsync_rust',
    'libx86_64': 'libx86_64_rust',
    'protoc_gen_rust': 'protoc-gen-rust',
}

RENAME_STEM_MAP = {
    # This map includes all changes to the default rust module stem names,
    # which is used for output files when different from the module name.
    'protoc_gen_rust': 'protoc-gen-rust',
}

RENAME_DEFAULTS_MAP = {
    # This map includes all changes to the default prefix of rust_default
    # module names, to avoid conflict with existing Android modules.
    'libc': 'rust_libc',
}

# Header added to all generated Android.bp files.
ANDROID_BP_HEADER = (
    '// This file is generated by cargo2android.py {args}.\n' +
    '// Do not modify this file as changes will be overridden on upgrade.\n')

CARGO_OUT = 'cargo.out'  # Name of file to keep cargo build -v output.

# This should be kept in sync with tools/external_updater/crates_updater.py.
ERRORS_LINE = 'Errors in ' + CARGO_OUT + ':'

TARGET_TMP = 'target.tmp'  # Name of temporary output directory.

# Message to be displayed when this script is called without the --run flag.
DRY_RUN_NOTE = (
    'Dry-run: This script uses ./' + TARGET_TMP + ' for output directory,\n' +
    'runs cargo clean, runs cargo build -v, saves output to ./cargo.out,\n' +
    'and writes to Android.bp in the current and subdirectories.\n\n' +
    'To do do all of the above, use the --run flag.\n' +
    'See --help for other flags, and more usage notes in this script.\n')

# Cargo -v output of a call to rustc.
RUSTC_PAT = re.compile('^ +Running `rustc (.*)`$')

# Cargo -vv output of a call to rustc could be split into multiple lines.
# Assume that the first line will contain some CARGO_* env definition.
RUSTC_VV_PAT = re.compile('^ +Running `.*CARGO_.*=.*$')
# The combined -vv output rustc command line pattern.
RUSTC_VV_CMD_ARGS = re.compile('^ *Running `.*CARGO_.*=.* rustc (.*)`$')

# Cargo -vv output of a "cc" or "ar" command; all in one line.
CC_AR_VV_PAT = re.compile(r'^\[([^ ]*)[^\]]*\] running:? "(cc|ar)" (.*)$')
# Some package, such as ring-0.13.5, has pattern '... running "cc"'.

# Rustc output of file location path pattern for a warning message.
WARNING_FILE_PAT = re.compile('^ *--> ([^:]*):[0-9]+')

# Rust package name with suffix -d1.d2.d3.
VERSION_SUFFIX_PAT = re.compile(r'^(.*)-[0-9]+\.[0-9]+\.[0-9]+$')


def altered_name(name):
  return RENAME_MAP[name] if (name in RENAME_MAP) else name


def altered_stem(name):
  return RENAME_STEM_MAP[name] if (name in RENAME_STEM_MAP) else name


def altered_defaults(name):
  return RENAME_DEFAULTS_MAP[name] if (name in RENAME_DEFAULTS_MAP) else name


def is_build_crate_name(name):
  # We added special prefix to build script crate names.
  return name.startswith('build_script_')


def is_dependent_file_path(path):
  # Absolute or dependent '.../' paths are not main files of this crate.
  return path.startswith('/') or path.startswith('.../')


def get_module_name(crate):  # to sort crates in a list
  return crate.module_name


def pkg2crate_name(s):
  return s.replace('-', '_').replace('.', '_')


def file_base_name(path):
  return os.path.splitext(os.path.basename(path))[0]


def test_base_name(path):
  return pkg2crate_name(file_base_name(path))


def unquote(s):  # remove quotes around str
  if s and len(s) > 1 and s[0] == '"' and s[-1] == '"':
    return s[1:-1]
  return s


def remove_version_suffix(s):  # remove -d1.d2.d3 suffix
  if VERSION_SUFFIX_PAT.match(s):
    return VERSION_SUFFIX_PAT.match(s).group(1)
  return s


def short_out_name(pkg, s):  # replace /.../pkg-*/out/* with .../out/*
  return re.sub('^/.*/' + pkg + '-[0-9a-f]*/out/', '.../out/', s)


def escape_quotes(s):  # replace '"' with '\\"'
  return s.replace('"', '\\"')


class Crate(object):
  """Information of a Rust crate to collect/emit for an Android.bp module."""

  def __init__(self, runner, outf_name):
    # Remembered global runner and its members.
    self.runner = runner
    self.debug = runner.args.debug
    self.cargo_dir = ''  # directory of my Cargo.toml
    self.outf_name = outf_name  # path to Android.bp
    self.outf = None  # open file handle of outf_name during dump*
    # Variants/results that could be merged from multiple rustc lines.
    self.host_supported = False
    self.device_supported = False
    self.has_warning = False
    # Android module properties derived from rustc parameters.
    self.module_name = ''  # unique in Android build system
    self.module_type = ''  # rust_{binary,library,test}[_host] etc.
    self.defaults = ''  # rust_defaults used by rust_test* modules
    self.default_srcs = False  # use 'srcs' defined in self.defaults
    self.root_pkg = ''  # parent package name of a sub/test packge, from -L
    self.srcs = list()  # main_src or merged multiple source files
    self.stem = ''  # real base name of output file
    # Kept parsed status
    self.errors = ''  # all errors found during parsing
    self.line_num = 1  # runner told input source line number
    self.line = ''  # original rustc command line parameters
    # Parameters collected from rustc command line.
    self.crate_name = ''  # follows --crate-name
    self.main_src = ''  # follows crate_name parameter, shortened
    self.crate_types = list()  # follows --crate-type
    self.cfgs = list()  # follows --cfg, without feature= prefix
    self.features = list()  # follows --cfg, name in 'feature="..."'
    self.codegens = list()  # follows -C, some ignored
    self.externs = list()  # follows --extern
    self.core_externs = list()  # first part of self.externs elements
    self.static_libs = list()  # e.g.  -l static=host_cpuid
    self.shared_libs = list()  # e.g.  -l dylib=wayland-client, -l z
    self.cap_lints = ''  # follows --cap-lints
    self.emit_list = ''  # e.g., --emit=dep-info,metadata,link
    self.edition = '2015'  # rustc default, e.g., --edition=2018
    self.target = ''  # follows --target

  def write(self, s):
    # convenient way to output one line at a time with EOL.
    self.outf.write(s + '\n')

  def same_flags(self, other):
    # host_supported, device_supported, has_warning are not compared but merged
    # target is not compared, to merge different target/host modules
    # externs is not compared; only core_externs is compared
    return (not self.errors and not other.errors and
            self.edition == other.edition and
            self.cap_lints == other.cap_lints and
            self.emit_list == other.emit_list and
            self.core_externs == other.core_externs and
            self.codegens == other.codegens and
            self.features == other.features and
            self.static_libs == other.static_libs and
            self.shared_libs == other.shared_libs and self.cfgs == other.cfgs)

  def merge_host_device(self, other):
    """Returns true if attributes are the same except host/device support."""
    return (self.crate_name == other.crate_name and
            self.crate_types == other.crate_types and
            self.main_src == other.main_src and
            # before merge, each test module has an unique module name and stem
            (self.stem == other.stem or self.crate_types == ['test']) and
            self.root_pkg == other.root_pkg and not self.skip_crate() and
            self.same_flags(other))

  def merge_test(self, other):
    """Returns true if self and other are tests of same root_pkg."""
    # Before merger, each test has its own crate_name.
    # A merged test uses its source file base name as output file name,
    # so a test is mergeable only if its base name equals to its crate name.
    return (self.crate_types == other.crate_types and
            self.crate_types == ['test'] and self.root_pkg == other.root_pkg and
            not self.skip_crate() and
            other.crate_name == test_base_name(other.main_src) and
            (len(self.srcs) > 1 or
             (self.crate_name == test_base_name(self.main_src)) and
             self.host_supported == other.host_supported and
             self.device_supported == other.device_supported) and
            self.same_flags(other))

  def merge(self, other, outf_name):
    """Try to merge crate into self."""
    # Cargo build --tests could recompile a library for tests.
    # We need to merge such duplicated calls to rustc, with
    # the algorithm in merge_host_device.
    should_merge_host_device = self.merge_host_device(other)
    should_merge_test = False
    if not should_merge_host_device:
      should_merge_test = self.merge_test(other)
    if should_merge_host_device or should_merge_test:
      self.runner.init_bp_file(outf_name)
      with open(outf_name, 'a') as outf:  # to write debug info
        self.outf = outf
        other.outf = outf
        self.do_merge(other, should_merge_test)
      return True
    return False

  def do_merge(self, other, should_merge_test):
    """Merge attributes of other to self."""
    if self.debug:
      self.write('\n// Before merge definition (1):')
      self.dump_debug_info()
      self.write('\n// Before merge definition (2):')
      other.dump_debug_info()
    # Merge properties of other to self.
    self.has_warning = self.has_warning or other.has_warning
    if not self.target:  # okay to keep only the first target triple
      self.target = other.target
    # decide_module_type sets up default self.stem,
    # which can be changed if self is a merged test module.
    self.decide_module_type()
    if should_merge_test:
      self.srcs.append(other.main_src)
      # use a short unique name as the merged module name.
      prefix = self.root_pkg + '_tests'
      self.module_name = self.runner.claim_module_name(prefix, self, 0)
      self.stem = self.module_name
      # This normalized root_pkg name although might be the same
      # as other module's crate_name, it is not actually used for
      # output file name. A merged test module always have multiple
      # source files and each source file base name is used as
      # its output file name.
      self.crate_name = pkg2crate_name(self.root_pkg)
    if self.debug:
      self.write('\n// After merge definition (1):')
      self.dump_debug_info()

  def find_cargo_dir(self):
    """Deepest directory with Cargo.toml and contains the main_src."""
    if not is_dependent_file_path(self.main_src):
      dir_name = os.path.dirname(self.main_src)
      while dir_name:
        if os.path.exists(dir_name + '/Cargo.toml'):
          self.cargo_dir = dir_name
          return
        dir_name = os.path.dirname(dir_name)

  def add_codegens_flag(self, flag):
    """Ignore options not used in Android."""
    # 'prefer-dynamic' does not work with common flag -C lto
    # 'embed-bitcode' is ignored; we might control LTO with other .bp flag
    # 'codegen-units' is set in Android global config or by default
    if not (flag.startswith('codegen-units=') or
            flag.startswith('debuginfo=') or
            flag.startswith('embed-bitcode=') or
            flag.startswith('extra-filename=') or
            flag.startswith('incremental=') or
            flag.startswith('metadata=') or
            flag == 'prefer-dynamic'):
      self.codegens.append(flag)

  def parse(self, line_num, line):
    """Find important rustc arguments to convert to Android.bp properties."""
    self.line_num = line_num
    self.line = line
    args = line.split()  # Loop through every argument of rustc.
    i = 0
    while i < len(args):
      arg = args[i]
      if arg == '--crate-name':
        i += 1
        self.crate_name = args[i]
      elif arg == '--crate-type':
        i += 1
        # cargo calls rustc with multiple --crate-type flags.
        # rustc can accept:
        #   --crate-type [bin|lib|rlib|dylib|cdylib|staticlib|proc-macro]
        self.crate_types.append(args[i])
      elif arg == '--test':
        self.crate_types.append('test')
      elif arg == '--target':
        i += 1
        self.target = args[i]
      elif arg == '--cfg':
        i += 1
        if args[i].startswith('\'feature='):
          self.features.append(unquote(args[i].replace('\'feature=', '')[:-1]))
        else:
          self.cfgs.append(args[i])
      elif arg == '--extern':
        i += 1
        extern_names = re.sub('=/[^ ]*/deps/', ' = ', args[i])
        self.externs.append(extern_names)
        self.core_externs.append(re.sub(' = .*', '', extern_names))
      elif arg == '-C':  # codegen options
        i += 1
        self.add_codegens_flag(args[i])
      elif arg.startswith('-C'):
        # cargo has been passing "-C <xyz>" flag to rustc,
        # but newer cargo could pass '-Cembed-bitcode=no' to rustc.
        self.add_codegens_flag(arg[2:])
      elif arg == '--cap-lints':
        i += 1
        self.cap_lints = args[i]
      elif arg == '-L':
        i += 1
        if args[i].startswith('dependency=') and args[i].endswith('/deps'):
          if '/' + TARGET_TMP + '/' in args[i]:
            self.root_pkg = re.sub(
                '^.*/', '', re.sub('/' + TARGET_TMP + '/.*/deps$', '', args[i]))
          else:
            self.root_pkg = re.sub('^.*/', '',
                                   re.sub('/[^/]+/[^/]+/deps$', '', args[i]))
          self.root_pkg = remove_version_suffix(self.root_pkg)
      elif arg == '-l':
        i += 1
        if args[i].startswith('static='):
          self.static_libs.append(re.sub('static=', '', args[i]))
        elif args[i].startswith('dylib='):
          self.shared_libs.append(re.sub('dylib=', '', args[i]))
        else:
          self.shared_libs.append(args[i])
      elif arg == '--out-dir' or arg == '--color':  # ignored
        i += 1
      elif arg.startswith('--error-format=') or arg.startswith('--json='):
        _ = arg  # ignored
      elif arg.startswith('--emit='):
        self.emit_list = arg.replace('--emit=', '')
      elif arg.startswith('--edition='):
        self.edition = arg.replace('--edition=', '')
      elif not arg.startswith('-'):
        # shorten imported crate main source paths like $HOME/.cargo/
        # registry/src/github.com-1ecc6299db9ec823/memchr-2.3.3/src/lib.rs
        self.main_src = re.sub(r'^/[^ ]*/registry/src/', '.../', args[i])
        self.main_src = re.sub(r'^\.\.\./github.com-[0-9a-f]*/', '.../',
                               self.main_src)
        self.find_cargo_dir()
        if self.cargo_dir:  # for a subdirectory
          if self.runner.args.no_subdir:  # all .bp content to /dev/null
            self.outf_name = '/dev/null'
          elif not self.runner.args.onefile:
            # Write to Android.bp in the subdirectory with Cargo.toml.
            self.outf_name = self.cargo_dir + '/Android.bp'
            self.main_src = self.main_src[len(self.cargo_dir) + 1:]
      else:
        self.errors += 'ERROR: unknown ' + arg + '\n'
      i += 1
    if not self.crate_name:
      self.errors += 'ERROR: missing --crate-name\n'
    if not self.main_src:
      self.errors += 'ERROR: missing main source file\n'
    else:
      self.srcs.append(self.main_src)
    if not self.crate_types:
      # Treat "--cfg test" as "--test"
      if 'test' in self.cfgs:
        self.crate_types.append('test')
      else:
        self.errors += 'ERROR: missing --crate-type or --test\n'
    elif len(self.crate_types) > 1:
      if 'test' in self.crate_types:
        self.errors += 'ERROR: cannot handle both --crate-type and --test\n'
      if 'lib' in self.crate_types and 'rlib' in self.crate_types:
        self.errors += 'ERROR: cannot generate both lib and rlib crate types\n'
    if not self.root_pkg:
      self.root_pkg = self.crate_name
    self.device_supported = self.runner.args.device
    self.host_supported = not self.runner.args.no_host
    self.cfgs = sorted(set(self.cfgs))
    self.features = sorted(set(self.features))
    self.codegens = sorted(set(self.codegens))
    self.externs = sorted(set(self.externs))
    self.core_externs = sorted(set(self.core_externs))
    self.static_libs = sorted(set(self.static_libs))
    self.shared_libs = sorted(set(self.shared_libs))
    self.crate_types = sorted(set(self.crate_types))
    self.decide_module_type()
    self.module_name = altered_name(self.stem)
    return self

  def dump_line(self):
    self.write('\n// Line ' + str(self.line_num) + ' ' + self.line)

  def feature_list(self):
    """Return a string of main_src + "feature_list"."""
    pkg = self.main_src
    if pkg.startswith('.../'):  # keep only the main package name
      pkg = re.sub('/.*', '', pkg[4:])
    elif pkg.startswith('/'):  # use relative path for a local package
      pkg = os.path.relpath(pkg)
    if not self.features:
      return pkg
    return pkg + ' "' + ','.join(self.features) + '"'

  def dump_skip_crate(self, kind):
    if self.debug:
      self.write('\n// IGNORED: ' + kind + ' ' + self.main_src)
    return self

  def skip_crate(self):
    """Return crate_name or a message if this crate should be skipped."""
    if (is_build_crate_name(self.crate_name) or
        self.crate_name in EXCLUDED_CRATES):
      return self.crate_name
    if is_dependent_file_path(self.main_src):
      return 'dependent crate'
    return ''

  def dump(self):
    """Dump all error/debug/module code to the output .bp file."""
    self.runner.init_bp_file(self.outf_name)
    with open(self.outf_name, 'a') as outf:
      self.outf = outf
      if self.errors:
        self.dump_line()
        self.write(self.errors)
      elif self.skip_crate():
        self.dump_skip_crate(self.skip_crate())
      else:
        if self.debug:
          self.dump_debug_info()
        self.dump_android_module()

  def dump_debug_info(self):
    """Dump parsed data, when cargo2android is called with --debug."""

    def dump(name, value):
      self.write('//%12s = %s' % (name, value))

    def opt_dump(name, value):
      if value:
        dump(name, value)

    def dump_list(fmt, values):
      for v in values:
        self.write(fmt % v)

    self.dump_line()
    dump('module_name', self.module_name)
    dump('crate_name', self.crate_name)
    dump('crate_types', self.crate_types)
    dump('main_src', self.main_src)
    dump('has_warning', self.has_warning)
    dump('for_host', self.host_supported)
    dump('for_device', self.device_supported)
    dump('module_type', self.module_type)
    opt_dump('target', self.target)
    opt_dump('edition', self.edition)
    opt_dump('emit_list', self.emit_list)
    opt_dump('cap_lints', self.cap_lints)
    dump_list('//         cfg = %s', self.cfgs)
    dump_list('//         cfg = \'feature "%s"\'', self.features)
    # TODO(chh): escape quotes in self.features, but not in other dump_list
    dump_list('//     codegen = %s', self.codegens)
    dump_list('//     externs = %s', self.externs)
    dump_list('//   -l static = %s', self.static_libs)
    dump_list('//  -l (dylib) = %s', self.shared_libs)

  def dump_android_module(self):
    """Dump one or more Android module definition, depending on crate_types."""
    if len(self.crate_types) == 1:
      self.dump_single_type_android_module()
      return
    if 'test' in self.crate_types:
      self.write('\nERROR: multiple crate types cannot include test type')
      return
    # Dump one Android module per crate_type.
    for crate_type in self.crate_types:
      self.decide_one_module_type(crate_type)
      self.dump_one_android_module(crate_type)

  def build_default_name(self):
    """Return a short and readable name for the rust_defaults module."""
    # Choices: (1) root_pkg + '_defaults',
    # (2) root_pkg + '_defaults_' + crate_name
    # (3) root_pkg + '_defaults_' + main_src_basename_path
    # (4) root_pkg + '_defaults_' + a_positive_sequence_number
    name1 = altered_defaults(self.root_pkg) + '_defaults'
    if self.runner.try_claim_module_name(name1, self):
      return name1
    name2 = name1 + '_' + self.crate_name
    if self.runner.try_claim_module_name(name2, self):
      return name2
    name3 = name1 + '_' + self.main_src_basename_path()
    if self.runner.try_claim_module_name(name3, self):
      return name3
    return self.runner.claim_module_name(name1, self, 0)

  def dump_srcs_list(self):
    """Dump the srcs list, for defaults or regular modules."""
    if len(self.srcs) > 1:
      srcs = sorted(set(self.srcs))  # make a copy and dedup
    else:
      srcs = [self.main_src]
    copy_out = self.runner.copy_out_module_name()
    if copy_out:
      srcs.append(':' + copy_out)
    self.dump_android_property_list('srcs', '"%s"', srcs)

  def dump_defaults_module(self):
    """Dump a rust_defaults module to be shared by other modules."""
    name = self.build_default_name()
    self.defaults = name
    self.write('\nrust_defaults {')
    self.write('    name: "' + name + '",')
    if self.runner.args.global_defaults:
      self.write('    defaults: ["' + self.runner.args.global_defaults + '"],')
    self.write('    crate_name: "' + self.crate_name + '",')
    if len(self.srcs) == 1:  # only one source file; share it in defaults
      self.default_srcs = True
      if self.has_warning and not self.cap_lints:
        self.write('    // has rustc warnings')
      self.dump_srcs_list()
    if 'test' in self.crate_types:
      self.write('    test_suites: ["general-tests"],')
      self.write('    auto_gen_config: true,')
    self.dump_edition_flags_libs()
    self.write('}')

  def dump_single_type_android_module(self):
    """Dump one simple Android module, which has only one crate_type."""
    crate_type = self.crate_types[0]
    if crate_type != 'test':
      # do not change self.stem or self.module_name
      self.dump_one_android_module(crate_type)
      return
    # Dump one test module per source file, and separate host and device tests.
    # crate_type == 'test'
    if (self.host_supported and self.device_supported) or len(self.srcs) > 1:
      self.srcs = sorted(set(self.srcs))
      self.dump_defaults_module()
    saved_srcs = self.srcs
    for src in saved_srcs:
      self.srcs = [src]
      saved_device_supported = self.device_supported
      saved_host_supported = self.host_supported
      saved_main_src = self.main_src
      self.main_src = src
      if saved_host_supported:
        self.device_supported = False
        self.host_supported = True
        self.module_name = self.test_module_name()
        self.decide_one_module_type(crate_type)
        self.dump_one_android_module(crate_type)
      if saved_device_supported:
        self.device_supported = True
        self.host_supported = False
        self.module_name = self.test_module_name()
        self.decide_one_module_type(crate_type)
        self.dump_one_android_module(crate_type)
      self.host_supported = saved_host_supported
      self.device_supported = saved_device_supported
      self.main_src = saved_main_src
    self.srcs = saved_srcs

  def dump_one_android_module(self, crate_type):
    """Dump one Android module definition."""
    if not self.module_type:
      self.write('\nERROR: unknown crate_type ' + crate_type)
      return
    self.write('\n' + self.module_type + ' {')
    self.dump_android_core_properties()
    if not self.defaults:
      self.dump_edition_flags_libs()
    if self.runner.args.host_first_multilib and self.host_supported and crate_type != 'test':
      self.write('    compile_multilib: "first",')
    if self.runner.args.apex_available and crate_type == 'lib':
      self.write('    apex_available: [')
      for apex in self.runner.args.apex_available:
        self.write('        "%s",' % apex)
      self.write('    ],')
    if self.runner.args.min_sdk_version and crate_type == 'lib':
      self.write('    min_sdk_version: "%s",' % self.runner.args.min_sdk_version)
    self.write('}')

  def dump_android_flags(self):
    """Dump Android module flags property."""
    if not self.codegens and not self.cap_lints:
      return
    self.write('    flags: [')
    if self.cap_lints:
      self.write('        "--cap-lints ' + self.cap_lints + '",')
    codegens_fmt = '"-C %s"'
    self.dump_android_property_list_items(codegens_fmt, self.codegens)
    self.write('    ],')

  def dump_edition_flags_libs(self):
    if self.edition:
      self.write('    edition: "' + self.edition + '",')
    self.dump_android_property_list('features', '"%s"', self.features)
    self.dump_android_property_list('cfgs', '"%s"', self.cfgs)
    self.dump_android_flags()
    if self.externs:
      self.dump_android_externs()
    self.dump_android_property_list('static_libs', '"lib%s"', self.static_libs)
    self.dump_android_property_list('shared_libs', '"lib%s"', self.shared_libs)

  def main_src_basename_path(self):
    return re.sub('/', '_', re.sub('.rs$', '', self.main_src))

  def test_module_name(self):
    """Return a unique name for a test module."""
    # root_pkg+(_host|_device) + '_test_'+source_file_name
    suffix = self.main_src_basename_path()
    host_device = '_host'
    if self.device_supported:
      host_device = '_device'
    return self.root_pkg + host_device + '_test_' + suffix

  def decide_module_type(self):
    # Use the first crate type for the default/first module.
    crate_type = self.crate_types[0] if self.crate_types else ''
    self.decide_one_module_type(crate_type)

  def decide_one_module_type(self, crate_type):
    """Decide which Android module type to use."""
    host = '' if self.device_supported else '_host'
    if crate_type == 'bin':  # rust_binary[_host]
      self.module_type = 'rust_binary' + host
      # In rare cases like protobuf-codegen, the output binary name must
      # be renamed to use as a plugin for protoc.
      self.stem = altered_stem(self.crate_name)
      self.module_name = altered_name(self.crate_name)
    elif crate_type == 'lib':  # rust_library[_host]
      # TODO(chh): should this be rust_library[_host]?
      # Assuming that Cargo.toml do not use both 'lib' and 'rlib',
      # because we map them both to rlib.
      self.module_type = 'rust_library' + host
      self.stem = 'lib' + self.crate_name
      self.module_name = altered_name(self.stem)
    elif crate_type == 'rlib':  # rust_library[_host]
      self.module_type = 'rust_library' + host
      self.stem = 'lib' + self.crate_name
      self.module_name = altered_name(self.stem)
    elif crate_type == 'dylib':  # rust_library[_host]_dylib
      self.module_type = 'rust_library' + host + '_dylib'
      self.stem = 'lib' + self.crate_name
      self.module_name = altered_name(self.stem) + '_dylib'
    elif crate_type == 'cdylib':  # rust_library[_host]_shared
      self.module_type = 'rust_ffi' + host + '_shared'
      self.stem = 'lib' + self.crate_name
      self.module_name = altered_name(self.stem) + '_shared'
    elif crate_type == 'staticlib':  # rust_library[_host]_static
      self.module_type = 'rust_ffi' + host + '_static'
      self.stem = 'lib' + self.crate_name
      self.module_name = altered_name(self.stem) + '_static'
    elif crate_type == 'test':  # rust_test[_host]
      self.module_type = 'rust_test' + host
      # Before do_merge, stem name is based on the --crate-name parameter.
      # and test module name is based on stem.
      self.stem = self.test_module_name()
      # self.stem will be changed after merging with other tests.
      # self.stem is NOT used for final test binary name.
      # rust_test uses each source file base name as part of output file name.
      # In do_merge, this function is called again, with a module_name.
      # We make sure that the module name is unique in each package.
      if self.module_name:
        # Cargo uses "-C extra-filename=..." and "-C metadata=..." to add
        # different suffixes and distinguish multiple tests of the same
        # crate name. We ignore -C and use claim_module_name to get
        # unique sequential suffix.
        self.module_name = self.runner.claim_module_name(
            self.module_name, self, 0)
        # Now the module name is unique, stem should also match and unique.
        self.stem = self.module_name
    elif crate_type == 'proc-macro':  # rust_proc_macro
      self.module_type = 'rust_proc_macro'
      self.stem = 'lib' + self.crate_name
      self.module_name = altered_name(self.stem)
    else:  # unknown module type, rust_prebuilt_dylib? rust_library[_host]?
      self.module_type = ''
      self.stem = ''

  def dump_android_property_list_items(self, fmt, values):
    for v in values:
      # fmt has quotes, so we need escape_quotes(v)
      self.write('        ' + (fmt % escape_quotes(v)) + ',')

  def dump_android_property_list(self, name, fmt, values):
    if not values:
      return
    if len(values) > 1:
      self.write('    ' + name + ': [')
      self.dump_android_property_list_items(fmt, values)
      self.write('    ],')
    else:
      self.write('    ' + name + ': [' +
                 (fmt % escape_quotes(values[0])) + '],')

  def dump_android_core_properties(self):
    """Dump the module header, name, stem, etc."""
    self.write('    name: "' + self.module_name + '",')
    # see properties shared by dump_defaults_module
    if self.defaults:
      self.write('    defaults: ["' + self.defaults + '"],')
    elif self.runner.args.global_defaults:
      self.write('    defaults: ["' + self.runner.args.global_defaults + '"],')
    if self.stem != self.module_name:
      self.write('    stem: "' + self.stem + '",')
    if self.has_warning and not self.cap_lints and not self.default_srcs:
      self.write('    // has rustc warnings')
    if self.host_supported and self.device_supported and self.module_type != 'rust_proc_macro':
      self.write('    host_supported: true,')
    if not self.defaults:
      self.write('    crate_name: "' + self.crate_name + '",')
    if not self.default_srcs:
      self.dump_srcs_list()
    if 'test' in self.crate_types and not self.defaults:
      # self.root_pkg can have multiple test modules, with different *_tests[n]
      # names, but their executables can all be installed under the same _tests
      # directory. When built from Cargo.toml, all tests should have different
      # file or crate names. So we used (root_pkg + '_tests') name as the
      # relative_install_path.
      # However, some package like 'slab' can have non-mergeable tests that
      # must be separated by different module names. So, here we no longer
      # emit relative_install_path.
      # self.write('    relative_install_path: "' + self.root_pkg + '_tests",')
      self.write('    test_suites: ["general-tests"],')
      self.write('    auto_gen_config: true,')
    if 'test' in self.crate_types and self.host_supported:
      self.write('    test_options: {')
      self.write('        unit_test: true,')
      self.write('    },')

  def dump_android_externs(self):
    """Dump the dependent rlibs and dylibs property."""
    so_libs = list()
    rust_libs = ''
    deps_libname = re.compile('^.* = lib(.*)-[0-9a-f]*.(rlib|so|rmeta)$')
    for lib in self.externs:
      # normal value of lib: "libc = liblibc-*.rlib"
      # strange case in rand crate:  "getrandom_package = libgetrandom-*.rlib"
      # we should use "libgetrandom", not "lib" + "getrandom_package"
      groups = deps_libname.match(lib)
      if groups is not None:
        lib_name = groups.group(1)
      else:
        lib_name = re.sub(' .*$', '', lib)
      if lib.endswith('.rlib') or lib.endswith('.rmeta'):
        # On MacOS .rmeta is used when Linux uses .rlib or .rmeta.
        rust_libs += '        "' + altered_name('lib' + lib_name) + '",\n'
      elif lib.endswith('.so'):
        so_libs.append(lib_name)
      elif lib != 'proc_macro':  # --extern proc_macro is special and ignored
        rust_libs += '        // ERROR: unknown type of lib ' + lib + '\n'
    if rust_libs:
      self.write('    rustlibs: [\n' + rust_libs + '    ],')
    # Are all dependent .so files proc_macros?
    # TODO(chh): Separate proc_macros and dylib.
    self.dump_android_property_list('proc_macros', '"lib%s"', so_libs)


class ARObject(object):
  """Information of an "ar" link command."""

  def __init__(self, runner, outf_name):
    # Remembered global runner and its members.
    self.runner = runner
    self.pkg = ''
    self.outf_name = outf_name  # path to Android.bp
    # "ar" arguments
    self.line_num = 1
    self.line = ''
    self.flags = ''  # e.g. "crs"
    self.lib = ''  # e.g. "/.../out/lib*.a"
    self.objs = list()  # e.g. "/.../out/.../*.o"

  def parse(self, pkg, line_num, args_line):
    """Collect ar obj/lib file names."""
    self.pkg = pkg
    self.line_num = line_num
    self.line = args_line
    args = args_line.split()
    num_args = len(args)
    if num_args < 3:
      print('ERROR: "ar" command has too few arguments', args_line)
    else:
      self.flags = unquote(args[0])
      self.lib = unquote(args[1])
      self.objs = sorted(set(map(unquote, args[2:])))
    return self

  def write(self, s):
    self.outf.write(s + '\n')

  def dump_debug_info(self):
    self.write('\n// Line ' + str(self.line_num) + ' "ar" ' + self.line)
    self.write('// ar_object for %12s' % self.pkg)
    self.write('//   flags = %s' % self.flags)
    self.write('//     lib = %s' % short_out_name(self.pkg, self.lib))
    for o in self.objs:
      self.write('//     obj = %s' % short_out_name(self.pkg, o))

  def dump_android_lib(self):
    """Write cc_library_static into Android.bp."""
    self.write('\ncc_library_static {')
    self.write('    name: "' + file_base_name(self.lib) + '",')
    self.write('    host_supported: true,')
    if self.flags != 'crs':
      self.write('    // ar flags = %s' % self.flags)
    if self.pkg not in self.runner.pkg_obj2cc:
      self.write('    ERROR: cannot find source files.\n}')
      return
    self.write('    srcs: [')
    obj2cc = self.runner.pkg_obj2cc[self.pkg]
    # Note: wflags are ignored.
    dflags = list()
    fflags = list()
    for obj in self.objs:
      self.write('        "' + short_out_name(self.pkg, obj2cc[obj].src) + '",')
      # TODO(chh): union of dflags and flags of all obj
      # Now, just a temporary hack that uses the last obj's flags
      dflags = obj2cc[obj].dflags
      fflags = obj2cc[obj].fflags
    self.write('    ],')
    self.write('    cflags: [')
    self.write('        "-O3",')  # TODO(chh): is this default correct?
    self.write('        "-Wno-error",')
    for x in fflags:
      self.write('        "-f' + x + '",')
    for x in dflags:
      self.write('        "-D' + x + '",')
    self.write('    ],')
    self.write('}')

  def dump(self):
    """Dump error/debug/module info to the output .bp file."""
    self.runner.init_bp_file(self.outf_name)
    with open(self.outf_name, 'a') as outf:
      self.outf = outf
      if self.runner.args.debug:
        self.dump_debug_info()
      self.dump_android_lib()


class CCObject(object):
  """Information of a "cc" compilation command."""

  def __init__(self, runner, outf_name):
    # Remembered global runner and its members.
    self.runner = runner
    self.pkg = ''
    self.outf_name = outf_name  # path to Android.bp
    # "cc" arguments
    self.line_num = 1
    self.line = ''
    self.src = ''
    self.obj = ''
    self.dflags = list()  # -D flags
    self.fflags = list()  # -f flags
    self.iflags = list()  # -I flags
    self.wflags = list()  # -W flags
    self.other_args = list()

  def parse(self, pkg, line_num, args_line):
    """Collect cc compilation flags and src/out file names."""
    self.pkg = pkg
    self.line_num = line_num
    self.line = args_line
    args = args_line.split()
    i = 0
    while i < len(args):
      arg = args[i]
      if arg == '"-c"':
        i += 1
        if args[i].startswith('"-o'):
          # ring-0.13.5 dumps: ... "-c" "-o/.../*.o" ".../*.c"
          self.obj = unquote(args[i])[2:]
          i += 1
          self.src = unquote(args[i])
        else:
          self.src = unquote(args[i])
      elif arg == '"-o"':
        i += 1
        self.obj = unquote(args[i])
      elif arg == '"-I"':
        i += 1
        self.iflags.append(unquote(args[i]))
      elif arg.startswith('"-D'):
        self.dflags.append(unquote(args[i])[2:])
      elif arg.startswith('"-f'):
        self.fflags.append(unquote(args[i])[2:])
      elif arg.startswith('"-W'):
        self.wflags.append(unquote(args[i])[2:])
      elif not (arg.startswith('"-O') or arg == '"-m64"' or arg == '"-g"' or
                arg == '"-g3"'):
        # ignore -O -m64 -g
        self.other_args.append(unquote(args[i]))
      i += 1
    self.dflags = sorted(set(self.dflags))
    self.fflags = sorted(set(self.fflags))
    # self.wflags is not sorted because some are order sensitive
    # and we ignore them anyway.
    if self.pkg not in self.runner.pkg_obj2cc:
      self.runner.pkg_obj2cc[self.pkg] = {}
    self.runner.pkg_obj2cc[self.pkg][self.obj] = self
    return self

  def write(self, s):
    self.outf.write(s + '\n')

  def dump_debug_flags(self, name, flags):
    self.write('//  ' + name + ':')
    for f in flags:
      self.write('//    %s' % f)

  def dump(self):
    """Dump only error/debug info to the output .bp file."""
    if not self.runner.args.debug:
      return
    self.runner.init_bp_file(self.outf_name)
    with open(self.outf_name, 'a') as outf:
      self.outf = outf
      self.write('\n// Line ' + str(self.line_num) + ' "cc" ' + self.line)
      self.write('// cc_object for %12s' % self.pkg)
      self.write('//    src = %s' % short_out_name(self.pkg, self.src))
      self.write('//    obj = %s' % short_out_name(self.pkg, self.obj))
      self.dump_debug_flags('-I flags', self.iflags)
      self.dump_debug_flags('-D flags', self.dflags)
      self.dump_debug_flags('-f flags', self.fflags)
      self.dump_debug_flags('-W flags', self.wflags)
      if self.other_args:
        self.dump_debug_flags('other args', self.other_args)


class Runner(object):
  """Main class to parse cargo -v output and print Android module definitions."""

  def __init__(self, args):
    self.bp_files = set()  # Remember all output Android.bp files.
    self.root_pkg = ''  # name of package in ./Cargo.toml
    # Saved flags, modes, and data.
    self.args = args
    self.dry_run = not args.run
    self.skip_cargo = args.skipcargo
    self.cargo_path = './cargo'  # path to cargo, will be set later
    self.checked_out_files = False  # to check only once
    self.build_out_files = []  # output files generated by build.rs
    # All cc/ar objects, crates, dependencies, and warning files
    self.cc_objects = list()
    self.pkg_obj2cc = {}
    # pkg_obj2cc[cc_object[i].pkg][cc_objects[i].obj] = cc_objects[i]
    self.ar_objects = list()
    self.crates = list()
    self.dependencies = list()  # dependent and build script crates
    self.warning_files = set()
    # Keep a unique mapping from (module name) to crate
    self.name_owners = {}
    # Save and dump all errors from cargo to Android.bp.
    self.errors = ''
    self.setup_cargo_path()
    # Default action is cargo clean, followed by build or user given actions.
    if args.cargo:
      self.cargo = ['clean'] + args.cargo
    else:
      default_target = '--target x86_64-unknown-linux-gnu'
      # Use the same target for both host and default device builds.
      # Same target is used as default in host x86_64 Android compilation.
      # Note: b/169872957, prebuilt cargo failed to build vsock
      # on x86_64-unknown-linux-musl systems.
      self.cargo = ['clean', 'build ' + default_target]
      if args.tests:
        self.cargo.append('build --tests ' + default_target)

  def setup_cargo_path(self):
    """Find cargo in the --cargo_bin or prebuilt rust bin directory."""
    if self.args.cargo_bin:
      self.cargo_path = os.path.join(self.args.cargo_bin, 'cargo')
      if not os.path.isfile(self.cargo_path):
        sys.exit('ERROR: cannot find cargo in ' + self.args.cargo_bin)
      print('WARNING: using cargo in ' + self.args.cargo_bin)
      return
    # We have only tested this on Linux.
    if platform.system() != 'Linux':
      sys.exit('ERROR: this script has only been tested on Linux with cargo.')
    # Assuming that this script is in development/scripts.
    my_dir = os.path.dirname(os.path.abspath(__file__))
    linux_dir = os.path.join(my_dir, '..', '..',
                             'prebuilts', 'rust', 'linux-x86')
    if not os.path.isdir(linux_dir):
      sys.exit('ERROR: cannot find directory ' + linux_dir)
    rust_version = self.find_rust_version(my_dir, linux_dir)
    cargo_bin = os.path.join(linux_dir, rust_version, 'bin')
    self.cargo_path = os.path.join(cargo_bin, 'cargo')
    if not os.path.isfile(self.cargo_path):
      sys.exit('ERROR: cannot find cargo in ' + cargo_bin
               + '; please try --cargo_bin= flag.')
    return

  def find_rust_version(self, my_dir, linux_dir):
    """Use my script directory, find prebuilt rust version."""
    # First look up build/soong/rust/config/global.go.
    path2global = os.path.join(my_dir, '..', '..',
                               'build', 'soong', 'rust', 'config', 'global.go')
    if os.path.isfile(path2global):
      # try to find: RustDefaultVersion = "1.44.0"
      version_pat = re.compile(
          r'\s*RustDefaultVersion\s*=\s*"([0-9]+\.[0-9]+\.[0-9]+)".*$')
      with open(path2global, 'r') as inf:
        for line in inf:
          result = version_pat.match(line)
          if result:
            return result.group(1)
    print('WARNING: cannot find RustDefaultVersion in ' + path2global)
    # Otherwise, find the newest (largest) version number in linux_dir.
    rust_version = (0, 0, 0)  # the prebuilt version to use
    version_pat = re.compile(r'([0-9]+)\.([0-9]+)\.([0-9]+)$')
    for dir_name in os.listdir(linux_dir):
      result = version_pat.match(dir_name)
      if not result:
        continue
      version = (result.group(1), result.group(2), result.group(3))
      if version > rust_version:
        rust_version = version
    return '.'.join(rust_version)

  def find_out_files(self):
    # list1 has build.rs output for normal crates
    list1 = glob.glob(TARGET_TMP + '/*/*/build/' + self.root_pkg + '-*/out/*')
    # list2 has build.rs output for proc-macro crates
    list2 = glob.glob(TARGET_TMP + '/*/build/' + self.root_pkg + '-*/out/*')
    return list1 + list2

  def copy_out_files(self):
    """Copy build.rs output files to ./out and set up build_out_files."""
    if self.checked_out_files:
      return
    self.checked_out_files = True
    cargo_out_files = self.find_out_files()
    out_files = set()
    if cargo_out_files:
      os.makedirs('out', exist_ok=True)
    for path in cargo_out_files:
      file_name = path.split('/')[-1]
      out_files.add(file_name)
      shutil.copy(path, 'out/' + file_name)
    self.build_out_files = sorted(out_files)

  def has_used_out_dir(self):
    """Returns true if env!("OUT_DIR") is found."""
    return 0 == os.system('grep -rl --exclude build.rs --include \\*.rs' +
                          ' \'env!("OUT_DIR")\' * > /dev/null')

  def copy_out_module_name(self):
    if self.args.copy_out and self.build_out_files:
      return 'copy_' + self.root_pkg + '_build_out'
    else:
      return ''

  def read_license(self, name):
    if not os.path.isfile(name):
      return ''
    license = ''
    with open(name, 'r') as intf:
      line = intf.readline()
      # Firstly skip ANDROID_BP_HEADER
      while line.startswith('//'):
        line = intf.readline()
      # Read all lines until we see a rust_* or genrule rule.
      while line != '' and not (line.startswith('rust_') or line.startswith('genrule {')):
        license += line
        line = intf.readline()
    return license.strip()

  def dump_copy_out_module(self, outf):
    """Output the genrule module to copy out/* to $(genDir)."""
    copy_out = self.copy_out_module_name()
    if not copy_out:
      return
    outf.write('\ngenrule {\n')
    outf.write('    name: "' + copy_out + '",\n')
    outf.write('    srcs: ["out/*"],\n')
    outf.write('    cmd: "cp $(in) $(genDir)",\n')
    if len(self.build_out_files) > 1:
      outf.write('    out: [\n')
      for f in self.build_out_files:
        outf.write('        "' + f + '",\n')
      outf.write('    ],\n')
    else:
      outf.write('    out: ["' + self.build_out_files[0] + '"],\n')
    outf.write('}\n')

  def init_bp_file(self, name):
    # name could be Android.bp or sub_dir_path/Android.bp
    if name not in self.bp_files:
      self.bp_files.add(name)
      license_section = self.read_license(name)
      with open(name, 'w') as outf:
        print_args = filter(lambda x: x != "--no-test-mapping", sys.argv[1:])
        outf.write(ANDROID_BP_HEADER.format(args=' '.join(print_args)))
        outf.write('\n')
        outf.write(license_section)
        outf.write('\n')
        # at most one copy_out module per .bp file
        self.dump_copy_out_module(outf)

  def dump_test_mapping_files(self):
    """Dump all TEST_MAPPING files."""
    if self.dry_run:
      print('Dry-run skip dump of TEST_MAPPING')
    elif self.args.no_test_mapping:
      print('Skipping generation of TEST_MAPPING')
    else:
      test_mapping = TestMapping(None)
      for bp_file_name in self.bp_files:
        test_mapping.create_test_mapping(os.path.dirname(bp_file_name))
    return self

  def try_claim_module_name(self, name, owner):
    """Reserve and return True if it has not been reserved yet."""
    if name not in self.name_owners or owner == self.name_owners[name]:
      self.name_owners[name] = owner
      return True
    return False

  def claim_module_name(self, prefix, owner, counter):
    """Return prefix if not owned yet, otherwise, prefix+str(counter)."""
    while True:
      name = prefix
      if counter > 0:
        name += '_' + str(counter)
      if self.try_claim_module_name(name, owner):
        return name
      counter += 1

  def find_root_pkg(self):
    """Read name of [package] in ./Cargo.toml."""
    if not os.path.exists('./Cargo.toml'):
      return
    with open('./Cargo.toml', 'r') as inf:
      pkg_section = re.compile(r'^ *\[package\]')
      name = re.compile('^ *name *= * "([^"]*)"')
      in_pkg = False
      for line in inf:
        if in_pkg:
          if name.match(line):
            self.root_pkg = name.match(line).group(1)
            break
        else:
          in_pkg = pkg_section.match(line) is not None

  def run_cargo(self):
    """Calls cargo -v and save its output to ./cargo.out."""
    if self.skip_cargo:
      return self
    cargo_toml = './Cargo.toml'
    cargo_out = './cargo.out'
    # Do not use Cargo.lock, because .bp rules are designed to
    # run with "latest" crates avaialable on Android.
    cargo_lock = './Cargo.lock'
    cargo_lock_saved = './cargo.lock.saved'
    had_cargo_lock = os.path.exists(cargo_lock)
    if not os.access(cargo_toml, os.R_OK):
      print('ERROR: Cannot find or read', cargo_toml)
      return self
    if not self.dry_run:
      if os.path.exists(cargo_out):
        os.remove(cargo_out)
      if not self.args.use_cargo_lock and had_cargo_lock:  # save it
        os.rename(cargo_lock, cargo_lock_saved)
    cmd_tail = ' --target-dir ' + TARGET_TMP + ' >> ' + cargo_out + ' 2>&1'
    # set up search PATH for cargo to find the correct rustc
    saved_path = os.environ['PATH']
    os.environ['PATH'] = os.path.dirname(self.cargo_path) + ':' + saved_path
    # Add [workspace] to Cargo.toml if it is not there.
    added_workspace = False
    if self.args.add_workspace:
      with open(cargo_toml, 'r') as in_file:
        cargo_toml_lines = in_file.readlines()
      found_workspace = '[workspace]\n' in cargo_toml_lines
      if found_workspace:
        print('### WARNING: found [workspace] in Cargo.toml')
      else:
        with open(cargo_toml, 'a') as out_file:
          out_file.write('[workspace]\n')
          added_workspace = True
          if self.args.verbose:
            print('### INFO: added [workspace] to Cargo.toml')
    for c in self.cargo:
      features = ''
      if c != 'clean':
        if self.args.features is not None:
          features = ' --no-default-features'
        if self.args.features:
          features += ' --features ' + self.args.features
      cmd_v_flag = ' -vv ' if self.args.vv else ' -v '
      cmd = self.cargo_path + cmd_v_flag
      cmd += c + features + cmd_tail
      if self.args.rustflags and c != 'clean':
        cmd = 'RUSTFLAGS="' + self.args.rustflags + '" ' + cmd
      if self.dry_run:
        print('Dry-run skip:', cmd)
      else:
        if self.args.verbose:
          print('Running:', cmd)
        with open(cargo_out, 'a') as out_file:
          out_file.write('### Running: ' + cmd + '\n')
        ret = os.system(cmd)
        if ret != 0:
          print('*** There was an error while running cargo.  ' +
                'See the cargo.out file for details.')
    if added_workspace:  # restore original Cargo.toml
      with open(cargo_toml, 'w') as out_file:
        out_file.writelines(cargo_toml_lines)
      if self.args.verbose:
        print('### INFO: restored original Cargo.toml')
    os.environ['PATH'] = saved_path
    if not self.dry_run:
      if not had_cargo_lock:  # restore to no Cargo.lock state
        os.remove(cargo_lock)
      elif not self.args.use_cargo_lock:  # restore saved Cargo.lock
        os.rename(cargo_lock_saved, cargo_lock)
    return self

  def dump_dependencies(self):
    """Append dependencies and their features to Android.bp."""
    if not self.dependencies:
      return
    dependent_list = list()
    for c in self.dependencies:
      dependent_list.append(c.feature_list())
    sorted_dependencies = sorted(set(dependent_list))
    self.init_bp_file('Android.bp')
    with open('Android.bp', 'a') as outf:
      outf.write('\n// dependent_library ["feature_list"]\n')
      for s in sorted_dependencies:
        outf.write('//   ' + s + '\n')

  def dump_pkg_obj2cc(self):
    """Dump debug info of the pkg_obj2cc map."""
    if not self.args.debug:
      return
    self.init_bp_file('Android.bp')
    with open('Android.bp', 'a') as outf:
      sorted_pkgs = sorted(self.pkg_obj2cc.keys())
      for pkg in sorted_pkgs:
        if not self.pkg_obj2cc[pkg]:
          continue
        outf.write('\n// obj => src for %s\n' % pkg)
        obj2cc = self.pkg_obj2cc[pkg]
        for obj in sorted(obj2cc.keys()):
          outf.write('//  ' + short_out_name(pkg, obj) + ' => ' +
                     short_out_name(pkg, obj2cc[obj].src) + '\n')

  def apply_patch(self):
    """Apply local patch file if it is given."""
    if self.args.patch:
      if self.dry_run:
        print('Dry-run skip patch file:', self.args.patch)
      else:
        if not os.path.exists(self.args.patch):
          self.append_to_bp('ERROR cannot find patch file: ' + self.args.patch)
          return self
        if self.args.verbose:
          print('### INFO: applying local patch file:', self.args.patch)
        os.system('patch -s --no-backup-if-mismatch ./Android.bp ' +
                  self.args.patch)
    return self

  def gen_bp(self):
    """Parse cargo.out and generate Android.bp files."""
    if self.dry_run:
      print('Dry-run skip: read', CARGO_OUT, 'write Android.bp')
    elif os.path.exists(CARGO_OUT):
      self.find_root_pkg()
      if self.args.copy_out:
        self.copy_out_files()
      elif self.find_out_files() and self.has_used_out_dir():
        print('WARNING: ' + self.root_pkg + ' has cargo output files; ' +
              'please rerun with the --copy-out flag.')
      with open(CARGO_OUT, 'r') as cargo_out:
        self.parse(cargo_out, 'Android.bp')
        self.crates.sort(key=get_module_name)
        for obj in self.cc_objects:
          obj.dump()
        self.dump_pkg_obj2cc()
        for crate in self.crates:
          crate.dump()
        dumped_libs = set()
        for lib in self.ar_objects:
          if lib.pkg == self.root_pkg:
            lib_name = file_base_name(lib.lib)
            if lib_name not in dumped_libs:
              dumped_libs.add(lib_name)
              lib.dump()
        if self.args.dependencies and self.dependencies:
          self.dump_dependencies()
        if self.errors:
          self.append_to_bp('\n' + ERRORS_LINE + '\n' + self.errors)
    return self

  def add_ar_object(self, obj):
    self.ar_objects.append(obj)

  def add_cc_object(self, obj):
    self.cc_objects.append(obj)

  def add_crate(self, crate):
    """Merge crate with someone in crates, or append to it. Return crates."""
    if crate.skip_crate():
      if self.args.debug:  # include debug info of all crates
        self.crates.append(crate)
      if self.args.dependencies:  # include only dependent crates
        if (is_dependent_file_path(crate.main_src) and
            not is_build_crate_name(crate.crate_name)):
          self.dependencies.append(crate)
    else:
      for c in self.crates:
        if c.merge(crate, 'Android.bp'):
          return
      # If not merged, decide module type and name now.
      crate.decide_module_type()
      self.crates.append(crate)

  def find_warning_owners(self):
    """For each warning file, find its owner crate."""
    missing_owner = False
    for f in self.warning_files:
      cargo_dir = ''  # find lowest crate, with longest path
      owner = None  # owner crate of this warning
      for c in self.crates:
        if (f.startswith(c.cargo_dir + '/') and
            len(cargo_dir) < len(c.cargo_dir)):
          cargo_dir = c.cargo_dir
          owner = c
      if owner:
        owner.has_warning = True
      else:
        missing_owner = True
    if missing_owner and os.path.exists('Cargo.toml'):
      # owner is the root cargo, with empty cargo_dir
      for c in self.crates:
        if not c.cargo_dir:
          c.has_warning = True

  def rustc_command(self, n, rustc_line, line, outf_name):
    """Process a rustc command line from cargo -vv output."""
    # cargo build -vv output can have multiple lines for a rustc command
    # due to '\n' in strings for environment variables.
    # strip removes leading spaces and '\n' at the end
    new_rustc = (rustc_line.strip() + line) if rustc_line else line
    # Use an heuristic to detect the completions of a multi-line command.
    # This might fail for some very rare case, but easy to fix manually.
    if not line.endswith('`\n') or (new_rustc.count('`') % 2) != 0:
      return new_rustc
    if RUSTC_VV_CMD_ARGS.match(new_rustc):
      args = RUSTC_VV_CMD_ARGS.match(new_rustc).group(1)
      self.add_crate(Crate(self, outf_name).parse(n, args))
    else:
      self.assert_empty_vv_line(new_rustc)
    return ''

  def cc_ar_command(self, n, groups, outf_name):
    pkg = groups.group(1)
    line = groups.group(3)
    if groups.group(2) == 'cc':
      self.add_cc_object(CCObject(self, outf_name).parse(pkg, n, line))
    else:
      self.add_ar_object(ARObject(self, outf_name).parse(pkg, n, line))

  def append_to_bp(self, line):
    self.init_bp_file('Android.bp')
    with open('Android.bp', 'a') as outf:
      outf.write(line)

  def assert_empty_vv_line(self, line):
    if line:  # report error if line is not empty
      self.append_to_bp('ERROR -vv line: ' + line)
    return ''

  def parse(self, inf, outf_name):
    """Parse rustc and warning messages in inf, return a list of Crates."""
    n = 0  # line number
    prev_warning = False  # true if the previous line was warning: ...
    rustc_line = ''  # previous line(s) matching RUSTC_VV_PAT
    for line in inf:
      n += 1
      if line.startswith('warning: '):
        prev_warning = True
        rustc_line = self.assert_empty_vv_line(rustc_line)
        continue
      new_rustc = ''
      if RUSTC_PAT.match(line):
        args_line = RUSTC_PAT.match(line).group(1)
        self.add_crate(Crate(self, outf_name).parse(n, args_line))
        self.assert_empty_vv_line(rustc_line)
      elif rustc_line or RUSTC_VV_PAT.match(line):
        new_rustc = self.rustc_command(n, rustc_line, line, outf_name)
      elif CC_AR_VV_PAT.match(line):
        self.cc_ar_command(n, CC_AR_VV_PAT.match(line), outf_name)
      elif prev_warning and WARNING_FILE_PAT.match(line):
        self.assert_empty_vv_line(rustc_line)
        fpath = WARNING_FILE_PAT.match(line).group(1)
        if fpath[0] != '/':  # ignore absolute path
          self.warning_files.add(fpath)
      elif line.startswith('error: ') or line.startswith('error[E'):
        if not self.args.ignore_cargo_errors:
          self.errors += line
      prev_warning = False
      rustc_line = new_rustc
    self.find_warning_owners()


def get_parser():
  """Parse main arguments."""
  parser = argparse.ArgumentParser('cargo2android')
  parser.add_argument(
      '--add_workspace',
      action='store_true',
      default=False,
      help=('append [workspace] to Cargo.toml before calling cargo,' +
            ' to treat current directory as root of package source;' +
            ' otherwise the relative source file path in generated' +
            ' .bp file will be from the parent directory.'))
  parser.add_argument(
      '--cargo',
      action='append',
      metavar='args_string',
      help=('extra cargo build -v args in a string, ' +
            'each --cargo flag calls cargo build -v once'))
  parser.add_argument(
      '--cargo_bin',
      type=str,
      help='use cargo in the cargo_bin directory instead of the prebuilt one')
  parser.add_argument(
      '--copy-out',
      action='store_true',
      default=False,
      help=('only for root directory, ' +
            'copy build.rs output to ./out/* and add a genrule to copy ' +
            './out/* to genrule output; for crates with code pattern: ' +
            'include!(concat!(env!("OUT_DIR"), "/<some_file>.rs"))'))
  parser.add_argument(
      '--debug',
      action='store_true',
      default=False,
      help='dump debug info into Android.bp')
  parser.add_argument(
      '--dependencies',
      action='store_true',
      default=False,
      help='dump debug info of dependent crates')
  parser.add_argument(
      '--device',
      action='store_true',
      default=False,
      help='run cargo also for a default device target')
  parser.add_argument(
      '--features',
      type=str,
      help=('pass features to cargo build, ' +
            'empty string means no default features'))
  parser.add_argument(
      '--global_defaults',
      type=str,
      help='add a defaults name to every module')
  parser.add_argument(
      '--host-first-multilib',
      action='store_true',
      default=False,
      help=('add a compile_multilib:"first" property ' +
            'to Android.bp host modules.'))
  parser.add_argument(
      '--ignore-cargo-errors',
      action='store_true',
      default=False,
      help='do not append cargo/rustc error messages to Android.bp')
  parser.add_argument(
      '--no-host',
      action='store_true',
      default=False,
      help='do not run cargo for the host; only for the device target')
  parser.add_argument(
      '--no-subdir',
      action='store_true',
      default=False,
      help='do not output anything for sub-directories')
  parser.add_argument(
      '--onefile',
      action='store_true',
      default=False,
      help=('output all into one ./Android.bp, default will generate ' +
            'one Android.bp per Cargo.toml in subdirectories'))
  parser.add_argument(
      '--patch',
      type=str,
      help='apply the given patch file to generated ./Android.bp')
  parser.add_argument(
      '--run',
      action='store_true',
      default=False,
      help='run it, default is dry-run')
  parser.add_argument('--rustflags', type=str, help='passing flags to rustc')
  parser.add_argument(
      '--skipcargo',
      action='store_true',
      default=False,
      help='skip cargo command, parse cargo.out, and generate Android.bp')
  parser.add_argument(
      '--tests',
      action='store_true',
      default=False,
      help='run cargo build --tests after normal build')
  parser.add_argument(
      '--use-cargo-lock',
      action='store_true',
      default=False,
      help=('run cargo build with existing Cargo.lock ' +
            '(used when some latest dependent crates failed)'))
  parser.add_argument(
      '--min-sdk-version',
      type=str,
      help='Minimum SDK version')
  parser.add_argument(
      '--apex-available',
      nargs='*',
      help='Mark the main library as apex_available with the given apexes.')
  parser.add_argument(
      '--no-test-mapping',
      action='store_true',
      default=False,
      help='Do not generate a TEST_MAPPING file.  Use only to speed up debugging.')
  parser.add_argument(
      '--verbose',
      action='store_true',
      default=False,
      help='echo executed commands')
  parser.add_argument(
      '--vv',
      action='store_true',
      default=False,
      help='run cargo with -vv instead of default -v')
  parser.add_argument(
      '--dump-config-and-exit',
      type=str,
      help=('Dump command-line arguments (minus this flag) to a config file and exit. ' +
            'This is intended to help migrate from command line options to config files.'))
  parser.add_argument(
      '--config',
      type=str,
      help=('Load command-line options from the given config file. ' +
            'Options in this file will override those passed on the command line.'))
  return parser


def parse_args(parser):
  """Parses command-line options."""
  args = parser.parse_args()
  # Use the values specified in a config file if one was found.
  if args.config:
    with open(args.config, 'r') as f:
      config = json.load(f)
      args_dict = vars(args)
      for arg in config:
        args_dict[arg.replace('-', '_')] = config[arg]
  return args


def dump_config(parser, args):
  """Writes the non-default command-line options to the specified file."""
  args_dict = vars(args)
  # Filter out the arguments that have their default value.
  # Also filter certain "temporary" arguments.
  non_default_args = {}
  for arg in args_dict:
    if args_dict[arg] != parser.get_default(
        arg) and arg != 'dump_config_and_exit' and arg != 'no_test_mapping':
      non_default_args[arg.replace('_', '-')] = args_dict[arg]
  # Write to the specified file.
  with open(args.dump_config_and_exit, 'w') as f:
    json.dump(non_default_args, f, indent=2, sort_keys=True)


def main():
  parser = get_parser()
  args = parse_args(parser)
  if not args.run:  # default is dry-run
    print(DRY_RUN_NOTE)
  if args.dump_config_and_exit:
    dump_config(parser, args)
  else:
    Runner(args).run_cargo().gen_bp().apply_patch().dump_test_mapping_files()


if __name__ == '__main__':
  main()
