1#!/usr/bin/env python3 2# Copyright (C) 2021 The Android Open Source Project 3# 4# Licensed under the Apache License, Version 2.0 (the "License"); 5# you may not use this file except in compliance with the License. 6# You may obtain a copy of the License at 7# 8# http://www.apache.org/licenses/LICENSE-2.0 9# 10# Unless required by applicable law or agreed to in writing, software 11# distributed under the License is distributed on an "AS IS" BASIS, 12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13# See the License for the specific language governing permissions and 14# limitations under the License. 15 16# This file should do the same thing when being invoked in any of these ways: 17# ./traceconv 18# python traceconv 19# bash traceconv 20# cat ./traceconv | bash 21# cat ./traceconv | python - 22 23BASH_FALLBACK = """ " 24exec python3 - "$@" <<'#'EOF 25#""" 26 27TOOL_NAME = 'trace_to_text' 28 29# BEGIN_SECTION_GENERATED_BY(roll-prebuilts) 30# Revision: v25.0 31PERFETTO_PREBUILT_MANIFEST = [{ 32 'tool': 33 'trace_to_text', 34 'arch': 35 'mac-amd64', 36 'file_name': 37 'trace_to_text', 38 'file_size': 39 6525752, 40 'url': 41 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v25.0/mac-amd64/trace_to_text', 42 'sha256': 43 '64ccf6bac87825145691c6533412e514891f82300d68ff7ce69e8d2ca69aaf62', 44 'platform': 45 'darwin', 46 'machine': ['x86_64'] 47}, { 48 'tool': 49 'trace_to_text', 50 'arch': 51 'mac-arm64', 52 'file_name': 53 'trace_to_text', 54 'file_size': 55 5661424, 56 'url': 57 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v25.0/mac-arm64/trace_to_text', 58 'sha256': 59 'fbb6d256c96cdc296f2faec2965d16a1527c4900e66a33aca979ff1c336a9f2f', 60 'platform': 61 'darwin', 62 'machine': ['arm64'] 63}, { 64 'tool': 65 'trace_to_text', 66 'arch': 67 'linux-amd64', 68 'file_name': 69 'trace_to_text', 70 'file_size': 71 6939560, 72 'url': 73 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v25.0/linux-amd64/trace_to_text', 74 'sha256': 75 '109f4ff3bbd47633b0c08a338f1230e69d529ddf1584656ed45d8a59acaaabeb', 76 'platform': 77 'linux', 78 'machine': ['x86_64'] 79}, { 80 'tool': 81 'trace_to_text', 82 'arch': 83 'windows-amd64', 84 'file_name': 85 'trace_to_text.exe', 86 'file_size': 87 5925888, 88 'url': 89 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v25.0/windows-amd64/trace_to_text.exe', 90 'sha256': 91 '29e50ec4d8e28c7c322ba13273afcce80c63fe7d9f182b83af0e2077b4d2b952', 92 'platform': 93 'win32', 94 'machine': ['amd64'] 95}] 96 97 98# DO NOT EDIT. If you wish to make edits to this code, you need to change only 99# //tools/get_perfetto_prebuilt.py and run /tools/roll-prebuilts to regenerate 100# all the others scripts this is embedded into. 101def get_perfetto_prebuilt(tool_name, soft_fail=False, arch=None): 102 """ Downloads the prebuilt, if necessary, and returns its path on disk. """ 103 104 # The first time this is invoked, it downloads the |url| and caches it into 105 # ~/.perfetto/prebuilts/$tool_name. On subsequent invocations it just runs the 106 # cached version. 107 def download_or_get_cached(file_name, url, sha256): 108 import os, hashlib, subprocess 109 dir = os.path.join( 110 os.path.expanduser('~'), '.local', 'share', 'perfetto', 'prebuilts') 111 os.makedirs(dir, exist_ok=True) 112 bin_path = os.path.join(dir, file_name) 113 sha256_path = os.path.join(dir, file_name + '.sha256') 114 needs_download = True 115 116 # Avoid recomputing the SHA-256 on each invocation. The SHA-256 of the last 117 # download is cached into file_name.sha256, just check if that matches. 118 if os.path.exists(bin_path) and os.path.exists(sha256_path): 119 with open(sha256_path, 'rb') as f: 120 digest = f.read().decode() 121 if digest == sha256: 122 needs_download = False 123 124 if needs_download: 125 # Either the filed doesn't exist or the SHA256 doesn't match. 126 tmp_path = bin_path + '.tmp' 127 print('Downloading ' + url) 128 subprocess.check_call(['curl', '-f', '-L', '-#', '-o', tmp_path, url]) 129 with open(tmp_path, 'rb') as fd: 130 actual_sha256 = hashlib.sha256(fd.read()).hexdigest() 131 if actual_sha256 != sha256: 132 raise Exception('Checksum mismatch for %s (actual: %s, expected: %s)' % 133 (url, actual_sha256, sha256)) 134 os.chmod(tmp_path, 0o755) 135 os.rename(tmp_path, bin_path) 136 with open(sha256_path, 'w') as f: 137 f.write(sha256) 138 return bin_path 139 # --- end of download_or_get_cached() --- 140 141 # --- get_perfetto_prebuilt() function starts here. --- 142 import os, platform, sys 143 plat = sys.platform.lower() 144 machine = platform.machine().lower() 145 manifest_entry = None 146 for entry in PERFETTO_PREBUILT_MANIFEST: 147 # If the caller overrides the arch, just match that (for Android prebuilts). 148 if arch and entry.get('arch') == arch: 149 manifest_entry = entry 150 break 151 # Otherwise guess the local machine arch. 152 if entry.get('tool') == tool_name and entry.get( 153 'platform') == plat and machine in entry.get('machine', []): 154 manifest_entry = entry 155 break 156 if manifest_entry is None: 157 if soft_fail: 158 return None 159 raise Exception( 160 ('No prebuilts available for %s-%s\n' % (plat, machine)) + 161 'See https://perfetto.dev/docs/contributing/build-instructions') 162 163 return download_or_get_cached( 164 file_name=manifest_entry['file_name'], 165 url=manifest_entry['url'], 166 sha256=manifest_entry['sha256']) 167 168 169# END_SECTION_GENERATED_BY(roll-prebuilts) 170 171if __name__ == '__main__': 172 import sys, os 173 bin_path = get_perfetto_prebuilt(TOOL_NAME) 174 os.execv(bin_path, [bin_path] + sys.argv[1:]) 175 176#EOF 177