blob: 2cca0fd1573bd08556d3f6ebd41fb5b1948e25a5 [file] [log] [blame]
#!/usr/bin/env python3
# Copyright (C) 2022 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.
import os
import glob
import argparse
import pathlib
import shutil
import subprocess
import re
def sed(pattern, replacement, file):
""" Performs an in-place string replacement of pattern in a target file
Args:
pattern: pattern to replace
replacement: replacement for the pattern matches
file: target file
Returns:
Nothing
"""
with open(file) as reader:
file_contents = reader.read()
new_file_contents = re.sub(pattern, replacement, file_contents)
with open(file, "w") as writer:
writer.write(new_file_contents)
def single(items):
""" Returns the only item from a list of just one item
Raises a ValueError if the list does not contain exactly one element
Args:
items: a list of one item
Returns:
The only item from a single-item-list
"""
if len(items) != 1:
raise ValueError('Expected a list of size 1. Found: %s' % items)
return items[0]
def update_tracing_perfetto(old_version, new_version, core_path, force_unstripped_binaries=False):
"""Updates tracing-perfetto version and artifacts (including building new binaries)
Args:
old_version: old version of the existing library
new_version: new version of the library; defaults to incrementing the old_version
core_path: path to frameworks/support directory
force_unstripped_binaries: flag allowing to force unstripped variant of binaries
Returns:
Nothing
"""
print("Updating tracing-perfetto, this can take a while...")
# update version in code
sed('tracingPerfettoVersion = "%s"' % old_version,
'tracingPerfettoVersion = "%s"' % new_version,
os.path.join(core_path, 'benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/'
'macro/perfetto/PerfettoSdkHandshakeTest.kt'))
sed('TRACING_PERFETTO = "%s"' % old_version,
'TRACING_PERFETTO = "%s"' % new_version,
os.path.join(core_path, 'libraryversions.toml'))
sed('#define VERSION "%s"' % old_version,
'#define VERSION "%s"' % new_version,
os.path.join(core_path, 'tracing/tracing-perfetto-binary/src/main/cpp/tracing_perfetto.cc'))
sed('const val libraryVersion = "%s"' % old_version,
'const val libraryVersion = "%s"' % new_version,
os.path.join(core_path, 'tracing/tracing-perfetto/src/androidTest/java/androidx/tracing/'
'perfetto/jni/test/PerfettoNativeTest.kt'))
sed('const val version = "%s"' % old_version,
'const val version = "%s"' % new_version,
os.path.join(core_path, 'tracing/tracing-perfetto/src/main/java/androidx/tracing/perfetto/'
'jni/PerfettoNative.kt'))
# build new binaries
subprocess.check_call(["./gradlew",
":tracing:tracing-perfetto-binary:createProjectZip",
"-Pandroidx.constraints=true",
"-DTRACING_PERFETTO_REUSE_PREBUILTS_AAR=false"],
cwd=core_path)
# copy binaries to prebuilts
project_zip_dir = os.path.join(core_path, '../../out/dist/per-project-zips')
project_zip_file = os.path.join(
project_zip_dir,
single(glob.glob('%s/*tracing*perfetto*binary*%s*.zip' % (project_zip_dir, new_version))))
dst_dir = pathlib.Path(os.path.join(
core_path,
"../../prebuilts/androidx/internal/androidx/tracing/tracing-perfetto-binary",
new_version))
if dst_dir.exists():
shutil.rmtree(dst_dir)
dst_dir.mkdir()
subprocess.check_call(
["unzip", "-xjqq", project_zip_file, '**/%s/**' % new_version, "-d", dst_dir])
# force unstripped binaries if the flag is enabled
if force_unstripped_binaries:
# locate unstripped binaries
out_dir = pathlib.Path(core_path, "../../out")
arm64_lib_file = out_dir.joinpath(single(subprocess.check_output(
'find . -type f -name "libtracing_perfetto.so"'
' -and -path "*RelWithDebInfo/*/obj/arm64*"'
' -exec stat -c "%Y %n" {} \\; |'
' sort | tail -1 | cut -d " " -f2-',
cwd=out_dir,
shell=True).splitlines()).decode())
base_dir = arm64_lib_file.parent.parent.parent
obj_dir = base_dir.joinpath('obj')
if not obj_dir.exists():
raise RuntimeError('Expected path %s to exist' % repr(obj_dir))
jni_dir = base_dir.joinpath('jni')
# prepare a jni folder to inject into the destination aar
if jni_dir.exists():
shutil.rmtree(jni_dir)
shutil.copytree(obj_dir, jni_dir)
# inject the jni folder into the aar
dst_aar = os.path.join(dst_dir, 'tracing-perfetto-binary-%s.aar' % new_version)
subprocess.check_call(['zip', '-r', dst_aar, 'jni'], cwd=base_dir)
# clean up
if jni_dir.exists():
shutil.rmtree(jni_dir)
# update SHA
for arch in ['armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64']:
checksum = subprocess.check_output(
'unzip -cxqq "*tracing*binary*%s*.aar" "**/%s/libtracing_perfetto.so" | shasum -a256 |'
' awk \'{print $1}\' | tr -d "\n"' % (new_version, arch),
cwd=dst_dir,
shell=True
).decode()
if not re.fullmatch('^[0-9a-z]{64}$', checksum):
raise ValueError('Expecting a sha256 sum. Got: %s' % checksum)
sed(
'"%s" to "[0-9a-z]{64}"' % arch,
'"%s" to "%s"' % (arch, checksum),
os.path.join(core_path, 'tracing/tracing-perfetto/src/main/java/androidx/tracing/'
'perfetto/jni/PerfettoNative.kt'))
print("Updated tracing-perfetto.")
if __name__ == '__main__':
parser = argparse.ArgumentParser(
description='Updates tracing-perfetto in the source code, which involves:'
' 1) updating hardcoded version references in code'
' 2) building binaries and updating them in the prebuilts folder'
' 3) updating SHA checksums hardcoded in code.')
parser.add_argument('-f', '--frameworks-support-dir',
required=True,
help='Path to frameworks/support directory')
parser.add_argument('-c', '--current-version',
required=True,
help='Current version, e.g. 1.0.0-alpha07')
parser.add_argument('-t', '--target-version',
required=True,
help='Target version, e.g. 1.0.0-alpha08')
parser.add_argument('-k', '--keep-binary-debug-symbols',
required=False,
default=False,
action='store_true',
help='Keeps debug symbols in the built binaries. Useful when profiling '
'performance of the library. ')
args = parser.parse_args()
core_path_abs = pathlib.Path(args.frameworks_support_dir).resolve()
update_tracing_perfetto(args.current_version, args.target_version, core_path_abs,
args.keep_binary_debug_symbols)