summaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'scripts')
-rw-r--r--scripts/Android.bp60
-rw-r--r--scripts/OWNERS1
-rwxr-xr-xscripts/build-mainline-modules.sh25
-rwxr-xr-xscripts/construct_context.py90
-rwxr-xr-xscripts/construct_context_test.py81
-rw-r--r--scripts/gen-kotlin-build-file.py94
-rwxr-xr-xscripts/gen-kotlin-build-file.sh73
-rwxr-xr-xscripts/lint-project-xml.py151
-rw-r--r--scripts/ninja_rsp.py83
-rw-r--r--scripts/rustfmt.toml5
-rwxr-xr-xscripts/transitive-deps.sh4
11 files changed, 589 insertions, 78 deletions
diff --git a/scripts/Android.bp b/scripts/Android.bp
index e848b5019..7782c6862 100644
--- a/scripts/Android.bp
+++ b/scripts/Android.bp
@@ -106,7 +106,7 @@ python_binary_host {
py3: {
enabled: false,
},
- }
+ },
}
python_binary_host {
@@ -148,3 +148,61 @@ python_test_host {
],
test_suites: ["general-tests"],
}
+
+python_binary_host {
+ name: "construct_context",
+ main: "construct_context.py",
+ srcs: [
+ "construct_context.py",
+ ],
+ version: {
+ py2: {
+ enabled: true,
+ },
+ py3: {
+ enabled: false,
+ },
+ },
+ libs: [
+ "manifest_utils",
+ ],
+}
+
+python_test_host {
+ name: "construct_context_test",
+ main: "construct_context_test.py",
+ srcs: [
+ "construct_context_test.py",
+ "construct_context.py",
+ ],
+ version: {
+ py2: {
+ enabled: true,
+ },
+ py3: {
+ enabled: false,
+ },
+ },
+ libs: [
+ "manifest_utils",
+ ],
+ test_suites: ["general-tests"],
+}
+
+python_binary_host {
+ name: "lint-project-xml",
+ main: "lint-project-xml.py",
+ srcs: [
+ "lint-project-xml.py",
+ "ninja_rsp.py",
+ ],
+}
+
+python_binary_host {
+ name: "gen-kotlin-build-file.py",
+ main: "gen-kotlin-build-file.py",
+ srcs: [
+ "gen-kotlin-build-file.py",
+ "ninja_rsp.py",
+ ],
+}
diff --git a/scripts/OWNERS b/scripts/OWNERS
index dd0966fa5..8c644247e 100644
--- a/scripts/OWNERS
+++ b/scripts/OWNERS
@@ -1,3 +1,4 @@
per-file system-clang-format,system-clang-format-2 = enh@google.com,smoreland@google.com
per-file build-mainline-modules.sh = ngeoffray@google.com,paulduffin@google.com,mast@google.com
per-file build-aml-prebuilts.sh = ngeoffray@google.com,paulduffin@google.com,mast@google.com
+per-file construct_context.py = ngeoffray@google.com,calin@google.com,mathieuc@google.com,skvadrik@google.com
diff --git a/scripts/build-mainline-modules.sh b/scripts/build-mainline-modules.sh
index df763c822..c7baca70d 100755
--- a/scripts/build-mainline-modules.sh
+++ b/scripts/build-mainline-modules.sh
@@ -21,6 +21,16 @@ MODULES_SDK_AND_EXPORTS=(
conscrypt-module-host-exports
runtime-module-sdk
runtime-module-host-exports
+ i18n-module-test-exports
+ i18n-module-sdk
+ platform-mainline-sdk
+)
+
+# List of libraries installed on the platform that are needed for ART chroot
+# testing.
+PLATFORM_LIBRARIES=(
+ liblog
+ libartpalette-system
)
# We want to create apex modules for all supported architectures.
@@ -41,13 +51,21 @@ echo_and_run() {
"$@"
}
+lib_dir() {
+ case $1 in
+ (aosp_arm|aosp_x86) echo "lib";;
+ (aosp_arm64|aosp_x86_64) echo "lib64";;
+ esac
+}
+
OUT_DIR=$(source build/envsetup.sh > /dev/null; TARGET_PRODUCT= get_build_var OUT_DIR)
DIST_DIR=$(source build/envsetup.sh > /dev/null; TARGET_PRODUCT= get_build_var DIST_DIR)
for product in "${PRODUCTS[@]}"; do
echo_and_run build/soong/soong_ui.bash --make-mode $@ \
TARGET_PRODUCT=${product} \
- ${MAINLINE_MODULES[@]}
+ ${MAINLINE_MODULES[@]} \
+ ${PLATFORM_LIBRARIES[@]}
PRODUCT_OUT=$(source build/envsetup.sh > /dev/null; TARGET_PRODUCT=${product} get_build_var PRODUCT_OUT)
TARGET_ARCH=$(source build/envsetup.sh > /dev/null; TARGET_PRODUCT=${product} get_build_var TARGET_ARCH)
@@ -56,9 +74,12 @@ for product in "${PRODUCTS[@]}"; do
for module in "${MAINLINE_MODULES[@]}"; do
echo_and_run cp ${PWD}/${PRODUCT_OUT}/system/apex/${module}.apex ${DIST_DIR}/${TARGET_ARCH}/
done
+ for library in "${PLATFORM_LIBRARIES[@]}"; do
+ libdir=$(lib_dir $product)
+ echo_and_run cp ${PWD}/${PRODUCT_OUT}/system/${libdir}/${library}.so ${DIST_DIR}/${TARGET_ARCH}/
+ done
done
-
# Create multi-archs SDKs in a different out directory. The multi-arch script
# uses Soong in --skip-make mode which cannot use the same directory as normal
# mode with make.
diff --git a/scripts/construct_context.py b/scripts/construct_context.py
new file mode 100755
index 000000000..8717fe305
--- /dev/null
+++ b/scripts/construct_context.py
@@ -0,0 +1,90 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2020 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.
+#
+"""A tool for constructing class loader context."""
+
+from __future__ import print_function
+
+import argparse
+import sys
+
+from manifest import compare_version_gt
+
+
+def parse_args(args):
+ """Parse commandline arguments."""
+ parser = argparse.ArgumentParser()
+ parser.add_argument('--target-sdk-version', default='', dest='sdk',
+ help='specify target SDK version (as it appears in the manifest)')
+ parser.add_argument('--host-classpath-for-sdk', dest='host_classpaths',
+ action='append', nargs=2, metavar=('sdk','classpath'),
+ help='specify classpath on host for a given SDK version or "any" version')
+ parser.add_argument('--target-classpath-for-sdk', dest='target_classpaths',
+ action='append', nargs=2, metavar=('sdk','classpath'),
+ help='specify classpath on target for a given SDK version or "any" version')
+ return parser.parse_args(args)
+
+# The hidl.manager shared library has a dependency on hidl.base. We manually
+# add that information to the class loader context if we see those libraries.
+HIDL_MANAGER = 'android.hidl.manager-V1.0-java'
+HIDL_BASE = 'android.hidl.base-V1.0-java'
+
+# Special keyword that means that the classpath should be added to class loader
+# context regardless of the target SDK version.
+any_sdk = 'any'
+
+# We assume that the order of classpath arguments passed to this script is
+# correct (matches the order computed by package manager). It is possible to
+# sort them here, but Soong needs to use deterministic order anyway, so it can
+# as well use the correct order.
+def construct_context(versioned_classpaths, target_sdk):
+ context = []
+ for [sdk, classpath] in versioned_classpaths:
+ if sdk == any_sdk or compare_version_gt(sdk, target_sdk):
+ for jar in classpath.split(':'):
+ pcl = 'PCL[%s]' % jar
+ if HIDL_MANAGER in jar:
+ pcl += '{PCL[%s]}' % jar.replace(HIDL_MANAGER, HIDL_BASE, 1)
+ context.append(pcl)
+ return context
+
+def construct_contexts(args):
+ host_context = construct_context(args.host_classpaths, args.sdk)
+ target_context = construct_context(args.target_classpaths, args.sdk)
+ context_sep = '#'
+ return ('class_loader_context_arg=--class-loader-context=PCL[]{%s} ; ' % context_sep.join(host_context) +
+ 'stored_class_loader_context_arg=--stored-class-loader-context=PCL[]{%s}' % context_sep.join(target_context))
+
+def main():
+ """Program entry point."""
+ try:
+ args = parse_args(sys.argv[1:])
+ if not args.sdk:
+ raise SystemExit('target sdk version is not set')
+ if not args.host_classpaths:
+ raise SystemExit('host classpath is not set')
+ if not args.target_classpaths:
+ raise SystemExit('target classpath is not set')
+
+ print(construct_contexts(args))
+
+ # pylint: disable=broad-except
+ except Exception as err:
+ print('error: ' + str(err), file=sys.stderr)
+ sys.exit(-1)
+
+if __name__ == '__main__':
+ main()
diff --git a/scripts/construct_context_test.py b/scripts/construct_context_test.py
new file mode 100755
index 000000000..0b0b0a315
--- /dev/null
+++ b/scripts/construct_context_test.py
@@ -0,0 +1,81 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2020 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.
+#
+"""Unit tests for construct_context.py."""
+
+import sys
+import unittest
+
+import construct_context as cc
+
+sys.dont_write_bytecode = True
+
+def construct_contexts(arglist):
+ args = cc.parse_args(arglist)
+ return cc.construct_contexts(args)
+
+classpaths = [
+ '--host-classpath-for-sdk', '28', 'out/zdir/z.jar',
+ '--target-classpath-for-sdk', '28', '/system/z.jar',
+ '--host-classpath-for-sdk', '29', 'out/xdir/x.jar:out/ydir/y.jar',
+ '--target-classpath-for-sdk', '29', '/system/x.jar:/product/y.jar',
+ '--host-classpath-for-sdk', 'any', 'out/adir/a.jar:out/android.hidl.manager-V1.0-java.jar:out/bdir/b.jar',
+ '--target-classpath-for-sdk', 'any', '/system/a.jar:/system/android.hidl.manager-V1.0-java.jar:/product/b.jar',
+]
+
+class ConstructContextTest(unittest.TestCase):
+ def test_construct_context_28(self):
+ args = ['--target-sdk-version', '28'] + classpaths
+ result = construct_contexts(args)
+ expect = ('class_loader_context_arg=--class-loader-context=PCL[]{PCL[out/xdir/x.jar]'
+ '#PCL[out/ydir/y.jar]'
+ '#PCL[out/adir/a.jar]'
+ '#PCL[out/android.hidl.manager-V1.0-java.jar]{PCL[out/android.hidl.base-V1.0-java.jar]}'
+ '#PCL[out/bdir/b.jar]}'
+ ' ; '
+ 'stored_class_loader_context_arg=--stored-class-loader-context=PCL[]{PCL[/system/x.jar]'
+ '#PCL[/product/y.jar]'
+ '#PCL[/system/a.jar]'
+ '#PCL[/system/android.hidl.manager-V1.0-java.jar]{PCL[/system/android.hidl.base-V1.0-java.jar]}'
+ '#PCL[/product/b.jar]}')
+ self.assertEqual(result, expect)
+
+ def test_construct_context_29(self):
+ args = ['--target-sdk-version', '29'] + classpaths
+ result = construct_contexts(args)
+ expect = ('class_loader_context_arg=--class-loader-context=PCL[]{PCL[out/adir/a.jar]'
+ '#PCL[out/android.hidl.manager-V1.0-java.jar]{PCL[out/android.hidl.base-V1.0-java.jar]}'
+ '#PCL[out/bdir/b.jar]}'
+ ' ; '
+ 'stored_class_loader_context_arg=--stored-class-loader-context=PCL[]{PCL[/system/a.jar]'
+ '#PCL[/system/android.hidl.manager-V1.0-java.jar]{PCL[/system/android.hidl.base-V1.0-java.jar]}'
+ '#PCL[/product/b.jar]}')
+ self.assertEqual(result, expect)
+
+ def test_construct_context_S(self):
+ args = ['--target-sdk-version', 'S'] + classpaths
+ result = construct_contexts(args)
+ expect = ('class_loader_context_arg=--class-loader-context=PCL[]{PCL[out/adir/a.jar]'
+ '#PCL[out/android.hidl.manager-V1.0-java.jar]{PCL[out/android.hidl.base-V1.0-java.jar]}'
+ '#PCL[out/bdir/b.jar]}'
+ ' ; '
+ 'stored_class_loader_context_arg=--stored-class-loader-context=PCL[]{PCL[/system/a.jar]'
+ '#PCL[/system/android.hidl.manager-V1.0-java.jar]{PCL[/system/android.hidl.base-V1.0-java.jar]}'
+ '#PCL[/product/b.jar]}')
+ self.assertEqual(result, expect)
+
+if __name__ == '__main__':
+ unittest.main(verbosity=2)
diff --git a/scripts/gen-kotlin-build-file.py b/scripts/gen-kotlin-build-file.py
new file mode 100644
index 000000000..83b4cd8a3
--- /dev/null
+++ b/scripts/gen-kotlin-build-file.py
@@ -0,0 +1,94 @@
+#!/usr/bin/env python3
+#
+# Copyright 2018 Google Inc. All rights reserved.
+#
+# 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.
+
+# Generates kotlinc module xml file to drive kotlinc
+
+import argparse
+import os
+
+from ninja_rsp import NinjaRspFileReader
+
+def parse_args():
+ """Parse commandline arguments."""
+
+ def convert_arg_line_to_args(arg_line):
+ for arg in arg_line.split():
+ if arg.startswith('#'):
+ return
+ if not arg.strip():
+ continue
+ yield arg
+
+ parser = argparse.ArgumentParser(fromfile_prefix_chars='@')
+ parser.convert_arg_line_to_args = convert_arg_line_to_args
+ parser.add_argument('--out', dest='out',
+ help='file to which the module.xml contents will be written.')
+ parser.add_argument('--classpath', dest='classpath', action='append', default=[],
+ help='classpath to pass to kotlinc.')
+ parser.add_argument('--name', dest='name',
+ help='name of the module.')
+ parser.add_argument('--out_dir', dest='out_dir',
+ help='directory to which kotlinc will write output files.')
+ parser.add_argument('--srcs', dest='srcs', action='append', default=[],
+ help='file containing whitespace separated list of source files.')
+ parser.add_argument('--common_srcs', dest='common_srcs', action='append', default=[],
+ help='file containing whitespace separated list of common multiplatform source files.')
+
+ return parser.parse_args()
+
+def main():
+ """Program entry point."""
+ args = parse_args()
+
+ if not args.out:
+ raise RuntimeError('--out argument is required')
+
+ if not args.name:
+ raise RuntimeError('--name argument is required')
+
+ with open(args.out, 'w') as f:
+ # Print preamble
+ f.write('<modules>\n')
+ f.write(' <module name="%s" type="java-production" outputDir="%s">\n' % (args.name, args.out_dir or ''))
+
+ # Print classpath entries
+ for c in args.classpath:
+ for entry in c.split(':'):
+ path = os.path.abspath(entry)
+ f.write(' <classpath path="%s"/>\n' % path)
+
+ # For each rsp file, print source entries
+ for rsp_file in args.srcs:
+ for src in NinjaRspFileReader(rsp_file):
+ path = os.path.abspath(src)
+ if src.endswith('.java'):
+ f.write(' <javaSourceRoots path="%s"/>\n' % path)
+ elif src.endswith('.kt'):
+ f.write(' <sources path="%s"/>\n' % path)
+ else:
+ raise RuntimeError('unknown source file type %s' % file)
+
+ for rsp_file in args.common_srcs:
+ for src in NinjaRspFileReader(rsp_file):
+ path = os.path.abspath(src)
+ f.write(' <sources path="%s"/>\n' % path)
+ f.write(' <commonSources path="%s"/>\n' % path)
+
+ f.write(' </module>\n')
+ f.write('</modules>\n')
+
+if __name__ == '__main__':
+ main()
diff --git a/scripts/gen-kotlin-build-file.sh b/scripts/gen-kotlin-build-file.sh
deleted file mode 100755
index 177ca1b04..000000000
--- a/scripts/gen-kotlin-build-file.sh
+++ /dev/null
@@ -1,73 +0,0 @@
-#!/bin/bash -e
-
-# Copyright 2018 Google Inc. All rights reserved.
-#
-# 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.
-
-# Generates kotlinc module xml file to standard output based on rsp files
-
-if [[ -z "$1" ]]; then
- echo "usage: $0 <classpath> <name> <outDir> <rspFiles>..." >&2
- exit 1
-fi
-
-# Classpath variable has a tendency to be prefixed by "-classpath", remove it.
-if [[ $1 == "-classpath" ]]; then
- shift
-fi;
-
-classpath=$1
-name=$2
-out_dir=$3
-shift 3
-
-# Path in the build file may be relative to the build file, we need to make them
-# absolute
-prefix="$(pwd)"
-
-get_abs_path () {
- local file="$1"
- if [[ "${file:0:1}" == '/' ]] ; then
- echo "${file}"
- else
- echo "${prefix}/${file}"
- fi
-}
-
-# Print preamble
-echo "<modules><module name=\"${name}\" type=\"java-production\" outputDir=\"${out_dir}\">"
-
-# Print classpath entries
-for file in $(echo "$classpath" | tr ":" "\n"); do
- path="$(get_abs_path "$file")"
- echo " <classpath path=\"${path}\"/>"
-done
-
-# For each rsp file, print source entries
-while (( "$#" )); do
- for file in $(cat "$1"); do
- path="$(get_abs_path "$file")"
- if [[ $file == *.java ]]; then
- echo " <javaSourceRoots path=\"${path}\"/>"
- elif [[ $file == *.kt ]]; then
- echo " <sources path=\"${path}\"/>"
- else
- echo "Unknown source file type ${file}"
- exit 1
- fi
- done
-
- shift
-done
-
-echo "</module></modules>"
diff --git a/scripts/lint-project-xml.py b/scripts/lint-project-xml.py
new file mode 100755
index 000000000..f1ef85dcc
--- /dev/null
+++ b/scripts/lint-project-xml.py
@@ -0,0 +1,151 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2018 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.
+#
+
+"""This file generates project.xml and lint.xml files used to drive the Android Lint CLI tool."""
+
+import argparse
+
+from ninja_rsp import NinjaRspFileReader
+
+
+def check_action(check_type):
+ """
+ Returns an action that appends a tuple of check_type and the argument to the dest.
+ """
+ class CheckAction(argparse.Action):
+ def __init__(self, option_strings, dest, nargs=None, **kwargs):
+ if nargs is not None:
+ raise ValueError("nargs must be None, was %s" % nargs)
+ super(CheckAction, self).__init__(option_strings, dest, **kwargs)
+ def __call__(self, parser, namespace, values, option_string=None):
+ checks = getattr(namespace, self.dest, [])
+ checks.append((check_type, values))
+ setattr(namespace, self.dest, checks)
+ return CheckAction
+
+
+def parse_args():
+ """Parse commandline arguments."""
+
+ def convert_arg_line_to_args(arg_line):
+ for arg in arg_line.split():
+ if arg.startswith('#'):
+ return
+ if not arg.strip():
+ continue
+ yield arg
+
+ parser = argparse.ArgumentParser(fromfile_prefix_chars='@')
+ parser.convert_arg_line_to_args = convert_arg_line_to_args
+ parser.add_argument('--project_out', dest='project_out',
+ help='file to which the project.xml contents will be written.')
+ parser.add_argument('--config_out', dest='config_out',
+ help='file to which the lint.xml contents will be written.')
+ parser.add_argument('--name', dest='name',
+ help='name of the module.')
+ parser.add_argument('--srcs', dest='srcs', action='append', default=[],
+ help='file containing whitespace separated list of source files.')
+ parser.add_argument('--generated_srcs', dest='generated_srcs', action='append', default=[],
+ help='file containing whitespace separated list of generated source files.')
+ parser.add_argument('--resources', dest='resources', action='append', default=[],
+ help='file containing whitespace separated list of resource files.')
+ parser.add_argument('--classes', dest='classes', action='append', default=[],
+ help='file containing the module\'s classes.')
+ parser.add_argument('--classpath', dest='classpath', action='append', default=[],
+ help='file containing classes from dependencies.')
+ parser.add_argument('--extra_checks_jar', dest='extra_checks_jars', action='append', default=[],
+ help='file containing extra lint checks.')
+ parser.add_argument('--manifest', dest='manifest',
+ help='file containing the module\'s manifest.')
+ parser.add_argument('--merged_manifest', dest='merged_manifest',
+ help='file containing merged manifest for the module and its dependencies.')
+ parser.add_argument('--library', dest='library', action='store_true',
+ help='mark the module as a library.')
+ parser.add_argument('--test', dest='test', action='store_true',
+ help='mark the module as a test.')
+ parser.add_argument('--cache_dir', dest='cache_dir',
+ help='directory to use for cached file.')
+ parser.add_argument('--root_dir', dest='root_dir',
+ help='directory to use for root dir.')
+ group = parser.add_argument_group('check arguments', 'later arguments override earlier ones.')
+ group.add_argument('--fatal_check', dest='checks', action=check_action('fatal'), default=[],
+ help='treat a lint issue as a fatal error.')
+ group.add_argument('--error_check', dest='checks', action=check_action('error'), default=[],
+ help='treat a lint issue as an error.')
+ group.add_argument('--warning_check', dest='checks', action=check_action('warning'), default=[],
+ help='treat a lint issue as a warning.')
+ group.add_argument('--disable_check', dest='checks', action=check_action('ignore'), default=[],
+ help='disable a lint issue.')
+ return parser.parse_args()
+
+
+def write_project_xml(f, args):
+ test_attr = "test='true' " if args.test else ""
+
+ f.write("<?xml version='1.0' encoding='utf-8'?>\n")
+ f.write("<project>\n")
+ if args.root_dir:
+ f.write(" <root dir='%s' />\n" % args.root_dir)
+ f.write(" <module name='%s' android='true' %sdesugar='full' >\n" % (args.name, "library='true' " if args.library else ""))
+ if args.manifest:
+ f.write(" <manifest file='%s' %s/>\n" % (args.manifest, test_attr))
+ if args.merged_manifest:
+ f.write(" <merged-manifest file='%s' %s/>\n" % (args.merged_manifest, test_attr))
+ for src_file in args.srcs:
+ for src in NinjaRspFileReader(src_file):
+ f.write(" <src file='%s' %s/>\n" % (src, test_attr))
+ for src_file in args.generated_srcs:
+ for src in NinjaRspFileReader(src_file):
+ f.write(" <src file='%s' generated='true' %s/>\n" % (src, test_attr))
+ for res_file in args.resources:
+ for res in NinjaRspFileReader(res_file):
+ f.write(" <resource file='%s' %s/>\n" % (res, test_attr))
+ for classes in args.classes:
+ f.write(" <classes jar='%s' />\n" % classes)
+ for classpath in args.classpath:
+ f.write(" <classpath jar='%s' />\n" % classpath)
+ for extra in args.extra_checks_jars:
+ f.write(" <lint-checks jar='%s' />\n" % extra)
+ f.write(" </module>\n")
+ if args.cache_dir:
+ f.write(" <cache dir='%s'/>\n" % args.cache_dir)
+ f.write("</project>\n")
+
+
+def write_config_xml(f, args):
+ f.write("<?xml version='1.0' encoding='utf-8'?>\n")
+ f.write("<lint>\n")
+ for check in args.checks:
+ f.write(" <issue id='%s' severity='%s' />\n" % (check[1], check[0]))
+ f.write("</lint>\n")
+
+
+def main():
+ """Program entry point."""
+ args = parse_args()
+
+ if args.project_out:
+ with open(args.project_out, 'w') as f:
+ write_project_xml(f, args)
+
+ if args.config_out:
+ with open(args.config_out, 'w') as f:
+ write_config_xml(f, args)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/scripts/ninja_rsp.py b/scripts/ninja_rsp.py
new file mode 100644
index 000000000..004ce4733
--- /dev/null
+++ b/scripts/ninja_rsp.py
@@ -0,0 +1,83 @@
+# Copyright (C) 2020 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.
+#
+
+"""This file reads entries from a Ninja rsp file."""
+
+class NinjaRspFileReader:
+ """
+ Reads entries from a Ninja rsp file. Ninja escapes any entries in the file that contain a
+ non-standard character by surrounding the whole entry with single quotes, and then replacing
+ any single quotes in the entry with the escape sequence '\''.
+ """
+
+ def __init__(self, filename):
+ self.f = open(filename, 'r')
+ self.r = self.character_reader(self.f)
+
+ def __iter__(self):
+ return self
+
+ def character_reader(self, f):
+ """Turns a file into a generator that returns one character at a time."""
+ while True:
+ c = f.read(1)
+ if c:
+ yield c
+ else:
+ return
+
+ def __next__(self):
+ entry = self.read_entry()
+ if entry:
+ return entry
+ else:
+ raise StopIteration
+
+ def read_entry(self):
+ c = next(self.r, "")
+ if not c:
+ return ""
+ elif c == "'":
+ return self.read_quoted_entry()
+ else:
+ entry = c
+ for c in self.r:
+ if c == " " or c == "\n":
+ break
+ entry += c
+ return entry
+
+ def read_quoted_entry(self):
+ entry = ""
+ for c in self.r:
+ if c == "'":
+ # Either the end of the quoted entry, or the beginning of an escape sequence, read the next
+ # character to find out.
+ c = next(self.r)
+ if not c or c == " " or c == "\n":
+ # End of the item
+ return entry
+ elif c == "\\":
+ # Escape sequence, expect a '
+ c = next(self.r)
+ if c != "'":
+ # Malformed escape sequence
+ raise "malformed escape sequence %s'\\%s" % (entry, c)
+ entry += "'"
+ else:
+ raise "malformed escape sequence %s'%s" % (entry, c)
+ else:
+ entry += c
+ raise "unterminated quoted entry %s" % entry
diff --git a/scripts/rustfmt.toml b/scripts/rustfmt.toml
new file mode 100644
index 000000000..617d42585
--- /dev/null
+++ b/scripts/rustfmt.toml
@@ -0,0 +1,5 @@
+# Android Format Style
+
+edition = "2018"
+use_small_heuristics = "Max"
+newline_style = "Unix"
diff --git a/scripts/transitive-deps.sh b/scripts/transitive-deps.sh
index c6f8b76e4..ba36ba4bf 100755
--- a/scripts/transitive-deps.sh
+++ b/scripts/transitive-deps.sh
@@ -56,7 +56,7 @@ Output Options:
temporary / intermediate files.
-sep=<delim> Use 'delim' as output field separator between notice
checksum and notice filename in notice output.
- e.g. sep='\t'
+ e.g. sep='\\t'
(Default space)
-csv Shorthand for -sep=','
-directories=<f> Output directory names of dependencies to 'f'.
@@ -280,7 +280,7 @@ while [ $# -gt 0 ]; do
notices=)
notices_out=$(expr "${flag}" : '^.*=\(.*\)$');;
*)
- die "Unknown flag ${1}";;
+ die "${usage}\n\nUnknown flag ${1}";;
esac
;;
*)