[go: nahoru, domu]

blob: 2cca0fd1573bd08556d3f6ebd41fb5b1948e25a5 [file] [log] [blame]
Jakub Gielzak61a09da2022-11-16 17:01:19 +00001#!/usr/bin/env python3
2
3# Copyright (C) 2022 The Android Open Source Project
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16
17import os
18import glob
19import argparse
20import pathlib
21import shutil
22import subprocess
23import re
24
25
26def sed(pattern, replacement, file):
27 """ Performs an in-place string replacement of pattern in a target file
28
29 Args:
30 pattern: pattern to replace
31 replacement: replacement for the pattern matches
32 file: target file
33
34 Returns:
35 Nothing
36 """
37
38 with open(file) as reader:
39 file_contents = reader.read()
40 new_file_contents = re.sub(pattern, replacement, file_contents)
41 with open(file, "w") as writer:
42 writer.write(new_file_contents)
43
44
45def single(items):
46 """ Returns the only item from a list of just one item
47
48 Raises a ValueError if the list does not contain exactly one element
49
50 Args:
51 items: a list of one item
52
53 Returns:
54 The only item from a single-item-list
55 """
56
57 if len(items) != 1:
58 raise ValueError('Expected a list of size 1. Found: %s' % items)
59 return items[0]
60
61
62def update_tracing_perfetto(old_version, new_version, core_path, force_unstripped_binaries=False):
63 """Updates tracing-perfetto version and artifacts (including building new binaries)
64
65 Args:
66 old_version: old version of the existing library
67 new_version: new version of the library; defaults to incrementing the old_version
68 core_path: path to frameworks/support directory
69 force_unstripped_binaries: flag allowing to force unstripped variant of binaries
70 Returns:
71 Nothing
72 """
73
74 print("Updating tracing-perfetto, this can take a while...")
75
76 # update version in code
77 sed('tracingPerfettoVersion = "%s"' % old_version,
78 'tracingPerfettoVersion = "%s"' % new_version,
79 os.path.join(core_path, 'benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/'
80 'macro/perfetto/PerfettoSdkHandshakeTest.kt'))
81 sed('TRACING_PERFETTO = "%s"' % old_version,
82 'TRACING_PERFETTO = "%s"' % new_version,
83 os.path.join(core_path, 'libraryversions.toml'))
84 sed('#define VERSION "%s"' % old_version,
85 '#define VERSION "%s"' % new_version,
86 os.path.join(core_path, 'tracing/tracing-perfetto-binary/src/main/cpp/tracing_perfetto.cc'))
87 sed('const val libraryVersion = "%s"' % old_version,
88 'const val libraryVersion = "%s"' % new_version,
89 os.path.join(core_path, 'tracing/tracing-perfetto/src/androidTest/java/androidx/tracing/'
90 'perfetto/jni/test/PerfettoNativeTest.kt'))
91 sed('const val version = "%s"' % old_version,
92 'const val version = "%s"' % new_version,
93 os.path.join(core_path, 'tracing/tracing-perfetto/src/main/java/androidx/tracing/perfetto/'
94 'jni/PerfettoNative.kt'))
95
96 # build new binaries
97 subprocess.check_call(["./gradlew",
98 ":tracing:tracing-perfetto-binary:createProjectZip",
Jakub Gielzak93483402023-02-10 16:13:31 +000099 "-Pandroidx.constraints=true",
Jakub Gielzak61a09da2022-11-16 17:01:19 +0000100 "-DTRACING_PERFETTO_REUSE_PREBUILTS_AAR=false"],
101 cwd=core_path)
102
103 # copy binaries to prebuilts
104 project_zip_dir = os.path.join(core_path, '../../out/dist/per-project-zips')
105 project_zip_file = os.path.join(
106 project_zip_dir,
107 single(glob.glob('%s/*tracing*perfetto*binary*%s*.zip' % (project_zip_dir, new_version))))
108 dst_dir = pathlib.Path(os.path.join(
109 core_path,
110 "../../prebuilts/androidx/internal/androidx/tracing/tracing-perfetto-binary",
111 new_version))
112 if dst_dir.exists():
113 shutil.rmtree(dst_dir)
114 dst_dir.mkdir()
115 subprocess.check_call(
116 ["unzip", "-xjqq", project_zip_file, '**/%s/**' % new_version, "-d", dst_dir])
117
118 # force unstripped binaries if the flag is enabled
119 if force_unstripped_binaries:
120 # locate unstripped binaries
121 out_dir = pathlib.Path(core_path, "../../out")
122 arm64_lib_file = out_dir.joinpath(single(subprocess.check_output(
123 'find . -type f -name "libtracing_perfetto.so"'
124 ' -and -path "*RelWithDebInfo/*/obj/arm64*"'
125 ' -exec stat -c "%Y %n" {} \\; |'
126 ' sort | tail -1 | cut -d " " -f2-',
127 cwd=out_dir,
128 shell=True).splitlines()).decode())
129 base_dir = arm64_lib_file.parent.parent.parent
130 obj_dir = base_dir.joinpath('obj')
131 if not obj_dir.exists():
132 raise RuntimeError('Expected path %s to exist' % repr(obj_dir))
133 jni_dir = base_dir.joinpath('jni')
134
135 # prepare a jni folder to inject into the destination aar
136 if jni_dir.exists():
137 shutil.rmtree(jni_dir)
138 shutil.copytree(obj_dir, jni_dir)
139
140 # inject the jni folder into the aar
141 dst_aar = os.path.join(dst_dir, 'tracing-perfetto-binary-%s.aar' % new_version)
142 subprocess.check_call(['zip', '-r', dst_aar, 'jni'], cwd=base_dir)
143
144 # clean up
145 if jni_dir.exists():
146 shutil.rmtree(jni_dir)
147
148 # update SHA
149 for arch in ['armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64']:
150 checksum = subprocess.check_output(
151 'unzip -cxqq "*tracing*binary*%s*.aar" "**/%s/libtracing_perfetto.so" | shasum -a256 |'
152 ' awk \'{print $1}\' | tr -d "\n"' % (new_version, arch),
153 cwd=dst_dir,
154 shell=True
155 ).decode()
156 if not re.fullmatch('^[0-9a-z]{64}$', checksum):
157 raise ValueError('Expecting a sha256 sum. Got: %s' % checksum)
158 sed(
159 '"%s" to "[0-9a-z]{64}"' % arch,
160 '"%s" to "%s"' % (arch, checksum),
161 os.path.join(core_path, 'tracing/tracing-perfetto/src/main/java/androidx/tracing/'
162 'perfetto/jni/PerfettoNative.kt'))
163
164 print("Updated tracing-perfetto.")
165
166
167if __name__ == '__main__':
168 parser = argparse.ArgumentParser(
169 description='Updates tracing-perfetto in the source code, which involves:'
170 ' 1) updating hardcoded version references in code'
171 ' 2) building binaries and updating them in the prebuilts folder'
172 ' 3) updating SHA checksums hardcoded in code.')
173 parser.add_argument('-f', '--frameworks-support-dir',
174 required=True,
175 help='Path to frameworks/support directory')
176 parser.add_argument('-c', '--current-version',
177 required=True,
178 help='Current version, e.g. 1.0.0-alpha07')
179 parser.add_argument('-t', '--target-version',
180 required=True,
181 help='Target version, e.g. 1.0.0-alpha08')
182 parser.add_argument('-k', '--keep-binary-debug-symbols',
183 required=False,
184 default=False,
185 action='store_true',
186 help='Keeps debug symbols in the built binaries. Useful when profiling '
187 'performance of the library. ')
188 args = parser.parse_args()
189 core_path_abs = pathlib.Path(args.frameworks_support_dir).resolve()
190 update_tracing_perfetto(args.current_version, args.target_version, core_path_abs,
191 args.keep_binary_debug_symbols)