8130c482ab
construct_context.py is a script that runs at Ninja stage and constructs class loader context arguments for dex2oat. Previously it accepted lists of library paths and concatenated them into one class loader context string. The script also handled the dependency of "android.hidl.manager" on "android.hidl.base" that is not tracked by the build system and must be handled in a special way. Now that class loader context representation is going to change from flat lists to trees, passing paths to individual libraries as script arguments is no longer possible, because a list of paths cannot represent a class loader context tree. Passing the trees in a serialized form is also inconvenient, because the script would have to parse them, which would complicate it a lot. Therefore this patch ports all the concatenation and "android.hidl.base" handling to Soong. It is not possible to port the remaining script to Soong because Soong has no information about the targetSdkVersiion of the dexpreopted apps (it is in the manifest and sometimes in an APK, and has to be extracted at Ninja time). Test: construct_context_test.py Test: new subtests in TestUsesLibs Test: lunch aosp_cf_x86_phone-userdebug && m Bug: 132357300 Change-Id: Icdb03cf00d1e27e4cff3844b89bfaec4de502dd7
81 lines
3 KiB
Python
Executable file
81 lines
3 KiB
Python
Executable file
#!/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-context-for-sdk', dest='host_contexts',
|
|
action='append', nargs=2, metavar=('sdk','context'),
|
|
help='specify context on host for a given SDK version or "any" version')
|
|
parser.add_argument('--target-context-for-sdk', dest='target_contexts',
|
|
action='append', nargs=2, metavar=('sdk','context'),
|
|
help='specify context on target for a given SDK version or "any" version')
|
|
return parser.parse_args(args)
|
|
|
|
# Special keyword that means that the context should be added to class loader
|
|
# context regardless of the target SDK version.
|
|
any_sdk = 'any'
|
|
|
|
# We assume that the order of context 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_contexts, target_sdk):
|
|
context = []
|
|
for [sdk, ctx] in versioned_contexts:
|
|
if sdk == any_sdk or compare_version_gt(sdk, target_sdk):
|
|
context.append(ctx)
|
|
return context
|
|
|
|
def construct_contexts(args):
|
|
host_context = construct_context(args.host_contexts, args.sdk)
|
|
target_context = construct_context(args.target_contexts, 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_contexts:
|
|
raise SystemExit('host context is not set')
|
|
if not args.target_contexts:
|
|
raise SystemExit('target context 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()
|