1*6dbdd20aSAndroid Build Coastguard Worker# Copyright (C) 2021 The Android Open Source Project 2*6dbdd20aSAndroid Build Coastguard Worker# 3*6dbdd20aSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License"); 4*6dbdd20aSAndroid Build Coastguard Worker# you may not use this file except in compliance with the License. 5*6dbdd20aSAndroid Build Coastguard Worker# You may obtain a copy of the License at 6*6dbdd20aSAndroid Build Coastguard Worker# 7*6dbdd20aSAndroid Build Coastguard Worker# http://www.apache.org/licenses/LICENSE-2.0 8*6dbdd20aSAndroid Build Coastguard Worker# 9*6dbdd20aSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software 10*6dbdd20aSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS, 11*6dbdd20aSAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*6dbdd20aSAndroid Build Coastguard Worker# See the License for the specific language governing permissions and 13*6dbdd20aSAndroid Build Coastguard Worker# limitations under the License. 14*6dbdd20aSAndroid Build Coastguard Worker"""Recipe for building Perfetto.""" 15*6dbdd20aSAndroid Build Coastguard Worker 16*6dbdd20aSAndroid Build Coastguard Workerfrom recipe_engine.recipe_api import Property 17*6dbdd20aSAndroid Build Coastguard Worker 18*6dbdd20aSAndroid Build Coastguard WorkerDEPS = [ 19*6dbdd20aSAndroid Build Coastguard Worker 'depot_tools/gsutil', 20*6dbdd20aSAndroid Build Coastguard Worker 'recipe_engine/buildbucket', 21*6dbdd20aSAndroid Build Coastguard Worker 'recipe_engine/cipd', 22*6dbdd20aSAndroid Build Coastguard Worker 'recipe_engine/context', 23*6dbdd20aSAndroid Build Coastguard Worker 'recipe_engine/file', 24*6dbdd20aSAndroid Build Coastguard Worker 'recipe_engine/path', 25*6dbdd20aSAndroid Build Coastguard Worker 'recipe_engine/platform', 26*6dbdd20aSAndroid Build Coastguard Worker 'recipe_engine/properties', 27*6dbdd20aSAndroid Build Coastguard Worker 'recipe_engine/raw_io', 28*6dbdd20aSAndroid Build Coastguard Worker 'recipe_engine/step', 29*6dbdd20aSAndroid Build Coastguard Worker 'macos_sdk', 30*6dbdd20aSAndroid Build Coastguard Worker 'windows_sdk', 31*6dbdd20aSAndroid Build Coastguard Worker] 32*6dbdd20aSAndroid Build Coastguard Worker 33*6dbdd20aSAndroid Build Coastguard WorkerPROPERTIES = { 34*6dbdd20aSAndroid Build Coastguard Worker 'repository': 35*6dbdd20aSAndroid Build Coastguard Worker Property( 36*6dbdd20aSAndroid Build Coastguard Worker kind=str, 37*6dbdd20aSAndroid Build Coastguard Worker default='https://android.googlesource.com/platform/external/perfetto' 38*6dbdd20aSAndroid Build Coastguard Worker ), 39*6dbdd20aSAndroid Build Coastguard Worker} 40*6dbdd20aSAndroid Build Coastguard Worker 41*6dbdd20aSAndroid Build Coastguard WorkerARTIFACTS = [ 42*6dbdd20aSAndroid Build Coastguard Worker { 43*6dbdd20aSAndroid Build Coastguard Worker 'name': 'trace_processor_shell' 44*6dbdd20aSAndroid Build Coastguard Worker }, 45*6dbdd20aSAndroid Build Coastguard Worker { 46*6dbdd20aSAndroid Build Coastguard Worker 'name': 'traceconv', 47*6dbdd20aSAndroid Build Coastguard Worker }, 48*6dbdd20aSAndroid Build Coastguard Worker { 49*6dbdd20aSAndroid Build Coastguard Worker 'name': 'tracebox', 50*6dbdd20aSAndroid Build Coastguard Worker 'exclude_platforms': ['windows-amd64'] 51*6dbdd20aSAndroid Build Coastguard Worker }, 52*6dbdd20aSAndroid Build Coastguard Worker { 53*6dbdd20aSAndroid Build Coastguard Worker 'name': 'perfetto' 54*6dbdd20aSAndroid Build Coastguard Worker }, 55*6dbdd20aSAndroid Build Coastguard Worker { 56*6dbdd20aSAndroid Build Coastguard Worker 'name': 'traced' 57*6dbdd20aSAndroid Build Coastguard Worker }, 58*6dbdd20aSAndroid Build Coastguard Worker { 59*6dbdd20aSAndroid Build Coastguard Worker 'name': 'traced_probes', 60*6dbdd20aSAndroid Build Coastguard Worker 'exclude_platforms': ['windows-amd64'] 61*6dbdd20aSAndroid Build Coastguard Worker }, 62*6dbdd20aSAndroid Build Coastguard Worker] 63*6dbdd20aSAndroid Build Coastguard Worker 64*6dbdd20aSAndroid Build Coastguard Worker 65*6dbdd20aSAndroid Build Coastguard Workerclass BuildContext: 66*6dbdd20aSAndroid Build Coastguard Worker 67*6dbdd20aSAndroid Build Coastguard Worker def __init__(self, src_dir): 68*6dbdd20aSAndroid Build Coastguard Worker self.src_dir = src_dir 69*6dbdd20aSAndroid Build Coastguard Worker self.git_revision = None 70*6dbdd20aSAndroid Build Coastguard Worker self.maybe_git_tag = None 71*6dbdd20aSAndroid Build Coastguard Worker 72*6dbdd20aSAndroid Build Coastguard Worker 73*6dbdd20aSAndroid Build Coastguard Workerdef GnArgs(platform): 74*6dbdd20aSAndroid Build Coastguard Worker (os, cpu) = platform.split('-') 75*6dbdd20aSAndroid Build Coastguard Worker base_args = 'is_debug=false monolithic_binaries=true' 76*6dbdd20aSAndroid Build Coastguard Worker if os not in ('android', 'linux', 'mac'): 77*6dbdd20aSAndroid Build Coastguard Worker return base_args # No cross-compiling on Windows. 78*6dbdd20aSAndroid Build Coastguard Worker cpu = 'x64' if cpu == 'amd64' else cpu # GN calls it "x64". 79*6dbdd20aSAndroid Build Coastguard Worker return base_args + ' target_os="{}" target_cpu="{}"'.format(os, cpu) 80*6dbdd20aSAndroid Build Coastguard Worker 81*6dbdd20aSAndroid Build Coastguard Worker 82*6dbdd20aSAndroid Build Coastguard Workerdef UploadArtifact(api, ctx, platform, out_dir, artifact): 83*6dbdd20aSAndroid Build Coastguard Worker exclude_platforms = artifact.get('exclude_platforms', []) 84*6dbdd20aSAndroid Build Coastguard Worker if platform in exclude_platforms: 85*6dbdd20aSAndroid Build Coastguard Worker return 86*6dbdd20aSAndroid Build Coastguard Worker 87*6dbdd20aSAndroid Build Coastguard Worker # We want to use the stripped binaries except on Windows where we don't generate 88*6dbdd20aSAndroid Build Coastguard Worker # them. 89*6dbdd20aSAndroid Build Coastguard Worker exe_dir = out_dir if api.platform.is_win else out_dir.join('stripped') 90*6dbdd20aSAndroid Build Coastguard Worker 91*6dbdd20aSAndroid Build Coastguard Worker # Compute the exact artifact path 92*6dbdd20aSAndroid Build Coastguard Worker gcs_upload_dir = ctx.maybe_git_tag if ctx.maybe_git_tag else ctx.git_revision 93*6dbdd20aSAndroid Build Coastguard Worker artifact_ext = artifact['name'] + ('.exe' if api.platform.is_win else '') 94*6dbdd20aSAndroid Build Coastguard Worker source_path = exe_dir.join(artifact_ext) 95*6dbdd20aSAndroid Build Coastguard Worker 96*6dbdd20aSAndroid Build Coastguard Worker # Upload to GCS bucket. 97*6dbdd20aSAndroid Build Coastguard Worker gcs_target_path = '{}/{}/{}'.format(gcs_upload_dir, platform, artifact_ext) 98*6dbdd20aSAndroid Build Coastguard Worker api.gsutil.upload(source_path, 'perfetto-luci-artifacts', gcs_target_path) 99*6dbdd20aSAndroid Build Coastguard Worker 100*6dbdd20aSAndroid Build Coastguard Worker # Uploads also the .pdb (debug symbols) to GCS. 101*6dbdd20aSAndroid Build Coastguard Worker pdb_path = exe_dir.join(artifact_ext + '.pdb') 102*6dbdd20aSAndroid Build Coastguard Worker if api.platform.is_win: 103*6dbdd20aSAndroid Build Coastguard Worker api.gsutil.upload(pdb_path, 'perfetto-luci-artifacts', 104*6dbdd20aSAndroid Build Coastguard Worker gcs_target_path + '.pdb') 105*6dbdd20aSAndroid Build Coastguard Worker 106*6dbdd20aSAndroid Build Coastguard Worker # Create the CIPD package definition from the artifact path. 107*6dbdd20aSAndroid Build Coastguard Worker cipd_pkg_name = 'perfetto/{}/{}'.format(artifact['name'], platform) 108*6dbdd20aSAndroid Build Coastguard Worker pkg_def = api.cipd.PackageDefinition( 109*6dbdd20aSAndroid Build Coastguard Worker package_name=cipd_pkg_name, package_root=exe_dir) 110*6dbdd20aSAndroid Build Coastguard Worker pkg_def.add_file(source_path) 111*6dbdd20aSAndroid Build Coastguard Worker 112*6dbdd20aSAndroid Build Coastguard Worker # Actually build the CIPD pakcage 113*6dbdd20aSAndroid Build Coastguard Worker cipd_pkg_file_name = '{}-{}.cipd'.format(artifact['name'], platform) 114*6dbdd20aSAndroid Build Coastguard Worker cipd_pkg_file = api.path['cleanup'].join(cipd_pkg_file_name) 115*6dbdd20aSAndroid Build Coastguard Worker api.cipd.build_from_pkg( 116*6dbdd20aSAndroid Build Coastguard Worker pkg_def=pkg_def, 117*6dbdd20aSAndroid Build Coastguard Worker output_package=cipd_pkg_file, 118*6dbdd20aSAndroid Build Coastguard Worker ) 119*6dbdd20aSAndroid Build Coastguard Worker 120*6dbdd20aSAndroid Build Coastguard Worker # If we have a git tag, add that to the CIPD tags. 121*6dbdd20aSAndroid Build Coastguard Worker tags = { 122*6dbdd20aSAndroid Build Coastguard Worker 'git_revision': ctx.git_revision, 123*6dbdd20aSAndroid Build Coastguard Worker } 124*6dbdd20aSAndroid Build Coastguard Worker if ctx.maybe_git_tag: 125*6dbdd20aSAndroid Build Coastguard Worker tags['git_tag'] = ctx.maybe_git_tag 126*6dbdd20aSAndroid Build Coastguard Worker 127*6dbdd20aSAndroid Build Coastguard Worker # Upload the package and regisiter with the 'latest' tag. 128*6dbdd20aSAndroid Build Coastguard Worker api.cipd.register( 129*6dbdd20aSAndroid Build Coastguard Worker package_name=cipd_pkg_name, 130*6dbdd20aSAndroid Build Coastguard Worker package_path=cipd_pkg_file, 131*6dbdd20aSAndroid Build Coastguard Worker refs=['latest'], 132*6dbdd20aSAndroid Build Coastguard Worker tags=tags, 133*6dbdd20aSAndroid Build Coastguard Worker ) 134*6dbdd20aSAndroid Build Coastguard Worker 135*6dbdd20aSAndroid Build Coastguard Worker 136*6dbdd20aSAndroid Build Coastguard Workerdef BuildForPlatform(api, ctx, platform): 137*6dbdd20aSAndroid Build Coastguard Worker out_dir = ctx.src_dir.join('out', platform) 138*6dbdd20aSAndroid Build Coastguard Worker 139*6dbdd20aSAndroid Build Coastguard Worker # Build Perfetto. 140*6dbdd20aSAndroid Build Coastguard Worker # There should be no need for internet access here. 141*6dbdd20aSAndroid Build Coastguard Worker 142*6dbdd20aSAndroid Build Coastguard Worker with api.context(cwd=ctx.src_dir), api.macos_sdk(), api.windows_sdk(): 143*6dbdd20aSAndroid Build Coastguard Worker targets = [ 144*6dbdd20aSAndroid Build Coastguard Worker x['name'] 145*6dbdd20aSAndroid Build Coastguard Worker for x in ARTIFACTS 146*6dbdd20aSAndroid Build Coastguard Worker if platform not in x.get('exclude_platforms', []) 147*6dbdd20aSAndroid Build Coastguard Worker ] 148*6dbdd20aSAndroid Build Coastguard Worker args = GnArgs(platform) 149*6dbdd20aSAndroid Build Coastguard Worker api.step('gn gen', 150*6dbdd20aSAndroid Build Coastguard Worker ['python3', 'tools/gn', 'gen', out_dir, '--args={}'.format(args)]) 151*6dbdd20aSAndroid Build Coastguard Worker api.step('gn clean', ['python3', 'tools/gn', 'clean', out_dir]) 152*6dbdd20aSAndroid Build Coastguard Worker api.step('ninja', ['python3', 'tools/ninja', '-C', out_dir] + targets) 153*6dbdd20aSAndroid Build Coastguard Worker 154*6dbdd20aSAndroid Build Coastguard Worker # Upload stripped artifacts using gsutil if we're on the official builder. 155*6dbdd20aSAndroid Build Coastguard Worker if 'official' not in api.buildbucket.builder_id.builder: 156*6dbdd20aSAndroid Build Coastguard Worker return 157*6dbdd20aSAndroid Build Coastguard Worker 158*6dbdd20aSAndroid Build Coastguard Worker with api.step.nest('Artifact upload'), api.context(cwd=ctx.src_dir): 159*6dbdd20aSAndroid Build Coastguard Worker for artifact in ARTIFACTS: 160*6dbdd20aSAndroid Build Coastguard Worker UploadArtifact(api, ctx, platform, out_dir, artifact) 161*6dbdd20aSAndroid Build Coastguard Worker 162*6dbdd20aSAndroid Build Coastguard Worker 163*6dbdd20aSAndroid Build Coastguard Workerdef RunSteps(api, repository): 164*6dbdd20aSAndroid Build Coastguard Worker builder_cache_dir = api.path['cache'].join('builder') 165*6dbdd20aSAndroid Build Coastguard Worker src_dir = builder_cache_dir.join('perfetto') 166*6dbdd20aSAndroid Build Coastguard Worker 167*6dbdd20aSAndroid Build Coastguard Worker # Crate the context we use in all the building stages. 168*6dbdd20aSAndroid Build Coastguard Worker ctx = BuildContext(src_dir) 169*6dbdd20aSAndroid Build Coastguard Worker 170*6dbdd20aSAndroid Build Coastguard Worker # Fetch the Perfetto repo. 171*6dbdd20aSAndroid Build Coastguard Worker with api.step.nest('git'), api.context(infra_steps=True): 172*6dbdd20aSAndroid Build Coastguard Worker api.file.ensure_directory('ensure source dir', src_dir) 173*6dbdd20aSAndroid Build Coastguard Worker api.step('init', ['git', 'init', src_dir]) 174*6dbdd20aSAndroid Build Coastguard Worker with api.context(cwd=src_dir): 175*6dbdd20aSAndroid Build Coastguard Worker build_input = api.buildbucket.build_input 176*6dbdd20aSAndroid Build Coastguard Worker ref = ( 177*6dbdd20aSAndroid Build Coastguard Worker build_input.gitiles_commit.ref 178*6dbdd20aSAndroid Build Coastguard Worker if build_input.gitiles_commit else 'refs/heads/main') 179*6dbdd20aSAndroid Build Coastguard Worker # Fetch tags so `git describe` works. 180*6dbdd20aSAndroid Build Coastguard Worker api.step('fetch', ['git', 'fetch', '--tags', repository, ref]) 181*6dbdd20aSAndroid Build Coastguard Worker api.step('checkout', ['git', 'checkout', 'FETCH_HEAD']) 182*6dbdd20aSAndroid Build Coastguard Worker 183*6dbdd20aSAndroid Build Coastguard Worker # Store information about the git revision and the tag if available. 184*6dbdd20aSAndroid Build Coastguard Worker ctx.git_revision = api.step( 185*6dbdd20aSAndroid Build Coastguard Worker 'rev-parse', ['git', 'rev-parse', 'HEAD'], 186*6dbdd20aSAndroid Build Coastguard Worker stdout=api.raw_io.output_text()).stdout.strip() 187*6dbdd20aSAndroid Build Coastguard Worker ctx.maybe_git_tag = ref.replace( 188*6dbdd20aSAndroid Build Coastguard Worker 'refs/tags/', '') if ref.startswith('refs/tags/') else None 189*6dbdd20aSAndroid Build Coastguard Worker 190*6dbdd20aSAndroid Build Coastguard Worker # Pull all deps here. 191*6dbdd20aSAndroid Build Coastguard Worker with api.context(cwd=src_dir, infra_steps=True): 192*6dbdd20aSAndroid Build Coastguard Worker extra_args = [] 193*6dbdd20aSAndroid Build Coastguard Worker if 'android' in api.buildbucket.builder_id.builder: 194*6dbdd20aSAndroid Build Coastguard Worker extra_args += ['--android'] 195*6dbdd20aSAndroid Build Coastguard Worker elif api.platform.is_linux: 196*6dbdd20aSAndroid Build Coastguard Worker # Pull the cross-toolchains for building for linux-arm{,64}. 197*6dbdd20aSAndroid Build Coastguard Worker extra_args += ['--linux-arm'] 198*6dbdd20aSAndroid Build Coastguard Worker api.step('build-deps', ['python3', 'tools/install-build-deps'] + extra_args) 199*6dbdd20aSAndroid Build Coastguard Worker 200*6dbdd20aSAndroid Build Coastguard Worker if api.platform.is_win: 201*6dbdd20aSAndroid Build Coastguard Worker BuildForPlatform(api, ctx, 'windows-amd64') 202*6dbdd20aSAndroid Build Coastguard Worker elif api.platform.is_mac: 203*6dbdd20aSAndroid Build Coastguard Worker with api.step.nest('mac-amd64'): 204*6dbdd20aSAndroid Build Coastguard Worker BuildForPlatform(api, ctx, 'mac-amd64') 205*6dbdd20aSAndroid Build Coastguard Worker with api.step.nest('mac-arm64'): 206*6dbdd20aSAndroid Build Coastguard Worker BuildForPlatform(api, ctx, 'mac-arm64') 207*6dbdd20aSAndroid Build Coastguard Worker elif 'android' in api.buildbucket.builder_id.builder: 208*6dbdd20aSAndroid Build Coastguard Worker with api.step.nest('android-arm'): 209*6dbdd20aSAndroid Build Coastguard Worker BuildForPlatform(api, ctx, 'android-arm') 210*6dbdd20aSAndroid Build Coastguard Worker with api.step.nest('android-arm64'): 211*6dbdd20aSAndroid Build Coastguard Worker BuildForPlatform(api, ctx, 'android-arm64') 212*6dbdd20aSAndroid Build Coastguard Worker with api.step.nest('android-x86'): 213*6dbdd20aSAndroid Build Coastguard Worker BuildForPlatform(api, ctx, 'android-x86') 214*6dbdd20aSAndroid Build Coastguard Worker with api.step.nest('android-x64'): 215*6dbdd20aSAndroid Build Coastguard Worker BuildForPlatform(api, ctx, 'android-x64') 216*6dbdd20aSAndroid Build Coastguard Worker elif api.platform.is_linux: 217*6dbdd20aSAndroid Build Coastguard Worker with api.step.nest('linux-amd64'): 218*6dbdd20aSAndroid Build Coastguard Worker BuildForPlatform(api, ctx, 'linux-amd64') 219*6dbdd20aSAndroid Build Coastguard Worker with api.step.nest('linux-arm'): 220*6dbdd20aSAndroid Build Coastguard Worker BuildForPlatform(api, ctx, 'linux-arm') 221*6dbdd20aSAndroid Build Coastguard Worker with api.step.nest('linux-arm64'): 222*6dbdd20aSAndroid Build Coastguard Worker BuildForPlatform(api, ctx, 'linux-arm64') 223*6dbdd20aSAndroid Build Coastguard Worker 224*6dbdd20aSAndroid Build Coastguard Worker 225*6dbdd20aSAndroid Build Coastguard Workerdef GenTests(api): 226*6dbdd20aSAndroid Build Coastguard Worker for target in ('android', 'linux', 'mac', 'win'): 227*6dbdd20aSAndroid Build Coastguard Worker host = 'linux' if target == 'android' else target 228*6dbdd20aSAndroid Build Coastguard Worker yield (api.test('ci_' + target) + api.platform.name(host) + 229*6dbdd20aSAndroid Build Coastguard Worker api.buildbucket.ci_build( 230*6dbdd20aSAndroid Build Coastguard Worker project='perfetto', 231*6dbdd20aSAndroid Build Coastguard Worker builder='perfetto-official-builder-%s' % target, 232*6dbdd20aSAndroid Build Coastguard Worker git_repo='android.googlesource.com/platform/external/perfetto', 233*6dbdd20aSAndroid Build Coastguard Worker )) 234*6dbdd20aSAndroid Build Coastguard Worker 235*6dbdd20aSAndroid Build Coastguard Worker yield (api.test('ci_tag') + api.platform.name('linux') + 236*6dbdd20aSAndroid Build Coastguard Worker api.buildbucket.ci_build( 237*6dbdd20aSAndroid Build Coastguard Worker project='perfetto', 238*6dbdd20aSAndroid Build Coastguard Worker builder='official', 239*6dbdd20aSAndroid Build Coastguard Worker git_repo='android.googlesource.com/platform/external/perfetto', 240*6dbdd20aSAndroid Build Coastguard Worker git_ref='refs/tags/v13.0')) 241*6dbdd20aSAndroid Build Coastguard Worker 242*6dbdd20aSAndroid Build Coastguard Worker yield (api.test('unofficial') + api.platform.name('linux') + 243*6dbdd20aSAndroid Build Coastguard Worker api.buildbucket.ci_build( 244*6dbdd20aSAndroid Build Coastguard Worker project='perfetto', 245*6dbdd20aSAndroid Build Coastguard Worker git_repo='android.googlesource.com/platform/external/perfetto')) 246