1# Perfetto build instructions 2 3The source of truth for the Perfetto codebase lives in AOSP: 4https://android.googlesource.com/platform/external/perfetto/ 5 6A read-only mirror is also available at https://github.com/google/perfetto . 7 8Perfetto can be built both from the Android tree (AOSP) and standalone. 9Standalone builds are meant only for local testing and are not shipped. 10Due to the reduced dependencies, the standalone workflow is faster to iterate on 11and the suggested way to work on Perfetto, unless you are working on code that 12has non-NDK depedencies into Android internals. Profilers and internal HAL/AIDL 13dependencies will not be built in the standalone build. 14 15If you are chromium contributor, AOSP is still the place you should send CLs to. 16The code inside chromium's 17[third_party/perfetto](https://source.chromium.org/chromium/chromium/src/+/main:third_party/perfetto/?q=f:third_party%2Fperfetto&ss=chromium) 18is a direct mirror of the AOSP repo. The 19[AOSP->Chromium autoroller](https://autoroll.skia.org/r/perfetto-chromium-autoroll) 20takes care of keeping chromium's DEPS up to date. 21 22## Standalone builds 23 24#### Get the code 25 26```bash 27git clone https://android.googlesource.com/platform/external/perfetto/ 28``` 29 30#### Pull dependent libraries and toolchains 31 32```bash 33tools/install-build-deps [--android] [--ui] [--linux-arm] 34``` 35 36`--android` will pull the Android NDK, emulator and other deps required 37to build for `target_os = "android"`. 38 39`--ui` will pull NodeJS and all the NPM modules required to build the 40Web UI. See the [UI Development](#ui-development) section below for more. 41 42`--linux-arm` will pull the sysroots for cross-compiling for Linux ARM/64. 43 44WARNING: Note that if you're using an M1 or any later ARM Mac, your Python 45version should be at least 3.9.1 to work around 46[this Python Bug](https://bugs.python.org/issue42704). 47 48#### Generate the build files via GN 49 50Perfetto uses [GN](https://gn.googlesource.com/gn/+/HEAD/docs/quick_start.md) 51as primary build system. See the [Build files](#build-files) section below for 52more. 53 54```bash 55tools/gn args out/android 56``` 57 58This will open an editor to customize the GN args. Enter: 59 60```python 61# Set only when building for Android, omit when building for linux, mac or win. 62target_os = "android" 63target_cpu = "arm" / "arm64" / "x64" 64 65is_debug = true / false 66cc_wrapper = "ccache" # [Optional] speed up rebuilds with ccache. 67``` 68 69See the [Build Configurations](#build-configurations) and 70[Building on Windows](#building-on-windows) sections below for more. 71 72TIP: If you are a chromium developer and have depot_tools installed you can 73avoid the `tools/` prefix below and just use gn/ninja from depot_tools. 74 75#### Build native C/C++ targets 76 77```bash 78# This will build all the targets. 79tools/ninja -C out/android 80 81# Alternatively, list targets explicitly. 82tools/ninja -C out/android \ 83 traced \ # Tracing service. 84 traced_probes \ # Ftrace interop and /proc poller. 85 perfetto \ # Cmdline client. 86 trace_processor_shell \ # Trace parsing. 87 traceconv # Trace conversion. 88... 89``` 90 91## Android tree builds 92 93Follow these instructions if you are an AOSP contributor. 94 95The source code lives in [`external/perfetto` in the AOSP tree](https://cs.android.com/android/platform/superproject/main/+/main:external/perfetto/). 96 97Follow the instructions on https://source.android.com/setup/build/building . 98 99Then: 100 101```bash 102mmma external/perfetto 103# or 104m traced traced_probes perfetto 105``` 106 107This will generate artifacts `out/target/product/XXX/system/`. 108 109Executables and shared libraries are stripped by default by the Android build 110system. The unstripped artifacts are kept into `out/target/product/XXX/symbols`. 111 112## UI development 113 114This command pulls the UI-related dependencies (notably, the NodeJS binary) 115and installs the `node_modules` in `ui/node_modules`: 116 117```bash 118tools/install-build-deps --ui 119``` 120 121Build the UI: 122 123```bash 124# Will build into ./out/ui by default. Can be changed with --out path/ 125# The final bundle will be available at ./ui/out/dist/. 126# The build script creates a symlink from ./ui/out to $OUT_PATH/ui/. 127ui/build 128``` 129 130Test your changes on a local server using: 131 132```bash 133# This will automatically build the UI. There is no need to manually run 134# ui/build before running ui/run-dev-server. 135ui/run-dev-server 136``` 137 138Navigate to http://localhost:10000/ to see the changes. 139 140The server supports live reloading of CSS and TS/JS contents. Whenever a ui 141source file is changed it, the script will automatically re-build it and show a 142prompt in the web page. 143 144UI unit tests are located next to the functionality being tested, and have 145`_unittest.ts` or `_jsdomtest.ts` suffixes. The following command runs all unit 146tests: 147 148```bash 149ui/run-unittests 150``` 151 152This command will perform the build first; which is not necessary if you 153already have a development server running. In this case, to avoid interference 154with the rebuild done by development server and to get the results faster, you 155can use 156 157```bash 158ui/run-unittests --no-build 159``` 160 161to skip the build steps. 162 163Script `ui/run-unittests` also supports `--watch` parameter, which would 164restart the testing when the underlying source files are changed. This can be 165used in conjunction with `--no-build`, and on its own as well. 166 167### Formatting & Linting 168 169We use `eslint` to lint TypeScript and JavaScript, and `prettier` to format 170TypeScript, JavaScript, and SCSS. 171 172Eslint has a `--fix` option which can auto-fix a lot of issues. 173 174```bash 175ui/eslint-all --fix # Fix all files 176# -- or -- 177ui/eslint-all # Just report issues 178``` 179 180To auto-format all source files, run: 181 182```bash 183ui/prettier-all 184``` 185 186For VSCode users, we recommend using the eslint & prettier extensions to handle 187this entirely from within the IDE. See the 188[Useful Extensions](#useful-extensions) section on how to set this up. 189 190Presubmit checks require no formatting or linting issues, so fix all issues 191using the commands above before submitting a patch. 192 193## Build files 194 195The source of truth of our build file is in the BUILD.gn files, which are based 196on [GN][gn-quickstart]. 197The Android build file ([Android.bp](/Android.bp)) is autogenerated from the GN 198files through `tools/gen_android_bp`, which needs to be invoked whenever a 199change touches GN files or introduces new ones. 200Likewise, the Bazel build file ([BUILD](/BUILD)) is autogenerated through the 201`tools/gen_bazel` script. 202 203A presubmit check checks that the Android.bp is consistent with GN files when 204submitting a CL through `git cl upload`. 205 206The generator has a list of root targets that will be translated into the 207Android.bp file. If you are adding a new target, add a new entry to the 208`default_targets` variable in [`tools/gen_android_bp`](/tools/gen_android_bp). 209 210## Supported platforms 211 212**Linux desktop** (Debian Testing/Rodete) 213 214- Hermetic clang + libcxx toolchain (both following chromium's revisions) 215- GCC-7 and libstdc++ 6 216- Cross-compiling for arm and arm64 (more below). 217 218**Android** 219 220- Android's NDK r15c (using NDK's libcxx) 221- AOSP's in-tree clang (using in-tree libcxx) 222 223**Mac** 224 225- XCode 9 / clang (maintained best-effort). 226 227**Windows** 228 229- Windows 10 with either MSVC 2019 or clang-cl (maintained best-effort). 230 231### Building on Windows 232 233Building on Windows is possible using both the MSVC 2019 compiler (you don't 234need the full IDE, just the build tools) or the LLVM clang-cl compiler. 235 236The Windows support in standalone builds has been introduced in v16 by 237[r.android.com/1711913](https://r.android.com/1711913). 238 239clang-cl support is more stable because that build configuration is actively 240covered by the Chromium project (Perfetto rolls into chromium and underpins 241chrome://tracing). The MSVC build is maintained best-effort. 242 243The following targets are supported on Windows: 244 245- `trace_processor_shell`: the trace importer and SQL query engine. 246- `traceconv`: the trace conversion tool. 247- `traced` and `perfetto`: the tracing service and cmdline client. They use an 248 alternative implementation of the [inter-process tracing protocol](/docs/design-docs/api-and-abi.md#tracing-protocol-abi) 249 based on a TCP socket and named shared memory. This configuration is only for 250 testing / benchmarks and is not shipped in production. 251 Googlers: see [go/perfetto-win](http://go/perfetto-win) for details. 252- `perfetto_unittests` / `perfetto_integrationtests`: although they support only 253 the subset of code that is supported on Windows (e.g. no ftrace). 254 255It is NOT possible to build the Perfetto UI from Windows. 256 257#### Prerequisites 258 259You need all of these both for MSVC and clang-cl: 260 261- [Build Tools for Visual Studio 2019](https://visualstudio.microsoft.com/downloads/#build-tools-for-visual-studio-2019) 262- [Windows 10 SDK](https://developer.microsoft.com/en-us/windows/downloads/windows-10-sdk/) 263- [Python 3](https://www.python.org/downloads/windows/) 264 265The [`win_find_msvc.py`](/gn/standalone/toolchain/win_find_msvc.py) script will 266locate the higest version numbers available from 267`C:\Program Files (x86)\Windows Kits\10` and 268`C:\Program Files (x86)\Microsoft Visual Studio\2019`. 269 270#### Pull dependent libraries and toolchains 271 272```bash 273# This will download also the LLVM clang-cl prebuilt used by chromium. 274python3 tools/install-build-deps 275``` 276 277#### Generate build files 278 279```bash 280python3 tools/gn gen out/win 281``` 282 283In the editor type: 284 285```bash 286is_debug = true | false 287 288is_clang = true # Will use the hermetic clang-cl toolchain. 289# or 290is_clang = false # Will use MSVC 2019. 291``` 292 293#### Build 294 295```bash 296python3 tools/ninja -C out/win perfetto traced trace_processor_shell 297``` 298 299### Cross-compiling for Linux ARM/64 300 301When cross-compiling for Linux you will need a sysroot. You have two options: 302 303#### 1. Use the built-in sysroots based on Debian Sid 304 305```bash 306tools/install-build-deps --linux-arm 307``` 308 309Then set the following GN args: 310 311```python 312target_os = "linux" 313target_cpu = "arm" 314# or 315target_cpu = "arm64" 316``` 317 318#### 2. Use your own sysroot 319 320In this case you need to manually specify the sysroot location and the 321toolchain prefix triplet to use. 322 323```python 324target_os = "linux" 325target_sysroot = "/path/to/sysroot" 326target_triplet = "aarch64-linux-gnu" # Or any other supported triplet. 327``` 328 329For more details see the [Using cutom toolchains](#custom-toolchain) section 330below. 331 332## Build configurations 333 334TIP: `tools/setup_all_configs.py` can be used to generate out/XXX folders for 335most of the supported configurations. 336 337The following [GN args][gn-quickstart] are supported: 338 339`target_os = "android" | "linux" | "mac"`: 340 341Defaults to the current host, set "android" to build for Android. 342 343`target_cpu = "arm" | "arm64" | "x64"` 344 345Defaults to `"arm"` when `target_os` == `"android"`, `"x64"` when targeting the 346host. 32-bit host builds are not supported. 347Note: x64 here really means x86_64. This is to keep it consistent with 348Chromium's choice, which in turn follows Windows naming convention. 349 350`is_debug = true | false` 351 352Toggles Debug (default) / Release mode. This affects, among other things: 353(i) the `-g` compiler flag; (ii) setting/unsetting `-DNDEBUG`; (iii) turning 354on/off `DCHECK` and `DLOG`. 355Note that debug builds of Perfetto are sensibly slower than release versions. We 356strongly encourage using debug builds only for local development. 357 358`is_clang = true | false` 359 360Use Clang (default: true) or GCC (false). 361On Linux, by default it uses the self-hosted clang (see `is_hermetic_clang`). 362On Android, by default it uses clang from the NDK (in `buildtools/ndk`). 363On Mac, by default it uses the system version of clang (requires Xcode). 364See also the [custom toolchain](#custom-toolchain) section below. 365 366`is_hermetic_clang = true | false` 367 368Use bundled toolchain from `buildtools/` rather than system-wide one. 369 370`non_hermetic_clang_stdlib = libc++ | libstdc++` 371 372If `is_hermetic_clang` is `false`, sets the `-stdlib` flag for clang 373invocations. `libstdc++` is default on Linux hosts and `libc++` is 374default everywhere else. 375 376`cc = "gcc" / cxx = "g++"` 377 378Uses a different compiler binary (default: autodetected depending on is_clang). 379See also the [custom toolchain](#custom-toolchain) section below. 380 381`cc_wrapper = "tool_name"` 382 383Prepends all build commands with a wrapper command. Using `"ccache"` here 384enables the [ccache](https://github.com/ccache/ccache) caching compiler, 385which can considerably speed up repeat builds. 386 387`is_asan = true` 388 389Enables [Address Sanitizer](https://github.com/google/sanitizers/wiki/AddressSanitizer) 390 391`is_lsan = true` 392 393Enables [Leak Sanitizer](https://github.com/google/sanitizers/wiki/AddressSanitizerLeakSanitizer) 394(Linux/Mac only) 395 396`is_msan = true` 397 398Enables [Memory Sanitizer](https://github.com/google/sanitizers/wiki/MemorySanitizer) 399(Linux only) 400 401`is_tsan = true` 402 403Enables [Thread Sanitizer](https://github.com/google/sanitizers/wiki/ThreadSanitizerCppManual) 404(Linux/Mac only) 405 406`is_ubsan = true` 407 408Enables [Undefined Behavior Sanitizer](https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html) 409 410### {#custom-toolchain} Using custom toolchains and CC / CXX / CFLAGS env vars 411 412When building Perfetto as part of some other build environment it might be 413necessary to switch off all the built-in toolchain-related path-guessing scripts 414and manually specify the path of the toolchains. 415 416```python 417# Disable the scripts that guess the path of the toolchain. 418is_system_compiler = true 419 420ar = "/path/to/ar" 421cc = "/path/to/gcc-like-compiler" 422cxx = "/path/to/g++-like-compiler" 423linker = "" # This is passed to -fuse-ld=... 424``` 425 426If you are using a build system that keeps the toolchain settings in 427environment variables, you can set: 428 429```python 430is_system_compiler = true 431ar="${AR}" 432cc="${CC}" 433cxx="${CXX}" 434``` 435 436`is_system_compiler = true` can be used also for cross-compilation. 437In case of cross-compilation, the GN variables have the following semantic: 438`ar`, `cc`, `cxx`, `linker` refer to the _host_ toolchain (sometimes also called 439_build_ toolchain). This toolchain is used to build: (i) auxiliary tools 440(e.g. the `traceconv` conversion util) and (ii) executable artifacts that are 441used during the rest of the build process for the target (e.g., the `protoc` 442compiler or the `protozero_plugin` protoc compiler plugin). 443 444The cross-toolchain used to build the artifacts that run on the device is 445prefixed by `target_`: `target_ar`, `target_cc`, `target_cxx`, `target_linker`. 446 447```python 448# Cross compilation kicks in when at least one of these three variables is set 449# to a value != than the host defaults. 450 451target_cpu = "x86" | "x64" | "arm" | "arm64" 452target_os = "linux" | "android" 453target_triplet = "arm-linux-gnueabi" | "x86_64-linux-gnu" | ... 454``` 455 456When integrating with GNU Makefile cross-toolchains build environments, a 457typical mapping of the corresponding environment variables is: 458 459```python 460ar="${BUILD_AR}" 461cc="${BUILD_CC}" 462cxx="${BUILD_CXX}" 463target_ar="${AR}" 464target_cc="${CC}" 465target_cxx="${CXX}" 466``` 467 468It is possible to extend the set of `CFLAGS` and `CXXFLAGS` through the 469`extra_xxxflags` GN variables as follows. The extra flags are always appended 470(hence, take precedence) to the set of flags that the GN build files generate. 471 472```python 473# These apply both to host and target toolchain. 474extra_cflags="${CFLAGS}" 475extra_cxxflags="${CXXFLAGS}" 476extra_ldflags="${LDFLAGS}" 477 478# These apply only to the host toolchain. 479extra_host_cflags="${BUILD_CFLAGS}" 480extra_host_cxxflags="${BUILD_CXXFLAGS}" 481extra_host_ldflags="${BUILD_LDFLAGS}" 482 483# These apply only to the target toolchain. 484extra_target_cflags="${CFLAGS}" 485extra_target_cxxflags="${CXXFLAGS} ${debug_flags}" 486extra_target_ldflags="${LDFLAGS}" 487``` 488 489[gn-quickstart]: https://gn.googlesource.com/gn/+/master/docs/quick_start.md 490 491## IDE setup 492 493Use a following command in the checkout directory in order to generate the 494compilation database file: 495 496```bash 497tools/gn gen out/default --export-compile-commands 498``` 499 500After generating, it can be used in CLion (File -> Open -> Open As Project), 501Visual Studio Code with C/C++ extension and any other tool and editor that 502supports the compilation database format. 503 504#### Useful extensions 505 506If you are using VS Code we suggest the following extensions: 507 508- [Clang-Format](https://marketplace.visualstudio.com/items?itemName=xaver.clang-format) 509- [C/C++](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools) 510- [clangd](https://marketplace.visualstudio.com/items?itemName=llvm-vs-code-extensions.vscode-clangd) 511- [Native Debug](https://marketplace.visualstudio.com/items?itemName=webfreak.debug) 512- [GNFormat](https://marketplace.visualstudio.com/items?itemName=persidskiy.vscode-gnformat) 513- [ESlint](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) 514- [markdownlint](https://marketplace.visualstudio.com/items?itemName=DavidAnson.vscode-markdownlint) 515- [Prettier](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode) 516 517#### Useful settings 518 519In `.vscode/settings.json`: 520 521```json 522{ 523 "C_Cpp.clang_format_path": "${workspaceRoot}/buildtools/mac/clang-format", 524 "C_Cpp.clang_format_sortIncludes": true, 525 "files.exclude": { 526 "out/*/obj": true, 527 "out/*/gen": true, 528 }, 529 "clangd.arguments": [ 530 "--compile-commands-dir=${workspaceFolder}/out/mac_debug", 531 "--completion-style=detailed", 532 "--header-insertion=never" 533 ], 534 "eslint.workingDirectories": [ 535 "./ui", 536 ], 537 "prettier.configPath": "ui/.prettierrc.yml", 538 "typescript.preferences.importModuleSpecifier": "relative", 539 "[typescript]": { 540 "editor.defaultFormatter": "esbenp.prettier-vscode" 541 }, 542 "[scss]": { 543 "editor.defaultFormatter": "esbenp.prettier-vscode" 544 }, 545} 546``` 547 548Replace `/mac/` with `/linux64/` on Linux. 549 550### Debugging with VSCode 551 552Edit `.vscode/launch.json`: 553 554```json 555{ 556 "version": "0.2.0", 557 "configurations": [ 558 { 559 "request": "launch", 560 "type": "cppdbg", 561 "name": "Perfetto unittests", 562 "program": "${workspaceRoot}/out/mac_debug/perfetto_unittests", 563 "args": ["--gtest_filter=TracingServiceImplTest.StopTracingTriggerRingBuffer"], 564 "cwd": "${workspaceFolder}/out/mac_debug", 565 "MIMode": "lldb", 566 }, 567 ] 568} 569``` 570 571Then open the command palette `Meta`+`Shift`+`P` -> `Debug: Start debugging`. 572