xref: /aosp_15_r20/external/perfetto/docs/contributing/build-instructions.md (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
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
172To auto-format all source files, run ui/format-sources, which takes care of
173running both prettier and eslint on the changed files:
174
175```bash
176# By default it formats only files that changed from the upstream Git branch
177# (typicaly origin/main).
178# Pass --all for formatting all files under ui/src
179ui/format-sources
180```
181
182For VSCode users, we recommend using the eslint & prettier extensions to handle
183this entirely from within the IDE. See the
184[Useful Extensions](#useful-extensions) section on how to set this up.
185
186Presubmit checks require no formatting or linting issues, so fix all issues
187using the commands above before submitting a patch.
188
189## Build files
190
191The source of truth of our build file is in the BUILD.gn files, which are based
192on [GN][gn-quickstart].
193The Android build file ([Android.bp](/Android.bp)) is autogenerated from the GN
194files through `tools/gen_android_bp`, which needs to be invoked whenever a
195change touches GN files or introduces new ones.
196Likewise, the Bazel build file ([BUILD](/BUILD)) is autogenerated through the
197`tools/gen_bazel` script.
198
199A presubmit check checks that the Android.bp is consistent with GN files when
200submitting a CL through `git cl upload`.
201
202The generator has a list of root targets that will be translated into the
203Android.bp file. If you are adding a new target, add a new entry to the
204`default_targets` variable in [`tools/gen_android_bp`](/tools/gen_android_bp).
205
206## Supported platforms
207
208**Linux desktop** (Debian Testing/Rodete)
209
210- Hermetic clang + libcxx toolchain (both following chromium's revisions)
211- GCC-7 and libstdc++ 6
212- Cross-compiling for arm and arm64 (more below).
213
214**Android**
215
216- Android's NDK r15c (using NDK's libcxx)
217- AOSP's in-tree clang (using in-tree libcxx)
218
219**Mac**
220
221- XCode 9 / clang (maintained best-effort).
222
223**Windows**
224
225- Windows 10 with either MSVC 2019 or clang-cl (maintained best-effort).
226
227### Building on Windows
228
229Building on Windows is possible using both the MSVC 2019 compiler (you don't
230need the full IDE, just the build tools) or the LLVM clang-cl compiler.
231
232The Windows support in standalone builds has been introduced in v16 by
233[r.android.com/1711913](https://r.android.com/1711913).
234
235clang-cl support is more stable because that build configuration is actively
236covered by the Chromium project (Perfetto rolls into chromium and underpins
237chrome://tracing). The MSVC build is maintained best-effort.
238
239The following targets are supported on Windows:
240
241- `trace_processor_shell`: the trace importer and SQL query engine.
242- `traceconv`: the trace conversion tool.
243- `traced` and `perfetto`: the tracing service and cmdline client. They use an
244  alternative implementation of the [inter-process tracing protocol](/docs/design-docs/api-and-abi.md#tracing-protocol-abi)
245  based on a TCP socket and named shared memory. This configuration is only for
246  testing / benchmarks and is not shipped in production.
247  Googlers: see [go/perfetto-win](http://go/perfetto-win) for details.
248- `perfetto_unittests` / `perfetto_integrationtests`: although they support only
249  the subset of code that is supported on Windows (e.g. no ftrace).
250
251It is NOT possible to build the Perfetto UI from Windows.
252
253#### Prerequisites
254
255You need all of these both for MSVC and clang-cl:
256
257- [Build Tools for Visual Studio 2019](https://visualstudio.microsoft.com/downloads/#build-tools-for-visual-studio-2019)
258- [Windows 10 SDK](https://developer.microsoft.com/en-us/windows/downloads/windows-10-sdk/)
259- [Python 3](https://www.python.org/downloads/windows/)
260
261The [`win_find_msvc.py`](/gn/standalone/toolchain/win_find_msvc.py) script will
262locate the higest version numbers available from
263`C:\Program Files (x86)\Windows Kits\10` and
264`C:\Program Files (x86)\Microsoft Visual Studio\2019`.
265
266#### Pull dependent libraries and toolchains
267
268```bash
269# This will download also the LLVM clang-cl prebuilt used by chromium.
270python3 tools/install-build-deps
271```
272
273#### Generate build files
274
275```bash
276python3 tools/gn gen out/win
277```
278
279In the editor type:
280
281```bash
282is_debug = true | false
283
284is_clang = true  # Will use the hermetic clang-cl toolchain.
285# or
286is_clang = false  # Will use MSVC 2019.
287```
288
289#### Build
290
291```bash
292python3 tools/ninja -C out/win perfetto traced trace_processor_shell
293```
294
295### Cross-compiling for Linux ARM/64
296
297When cross-compiling for Linux you will need a sysroot. You have two options:
298
299#### 1. Use the built-in sysroots based on Debian Sid
300
301```bash
302tools/install-build-deps --linux-arm
303```
304
305Then set the following GN args:
306
307```python
308target_os = "linux"
309target_cpu = "arm"
310# or
311target_cpu = "arm64"
312```
313
314#### 2. Use your own sysroot
315
316In this case you need to manually specify the sysroot location and the
317toolchain prefix triplet to use.
318
319```python
320target_os = "linux"
321target_sysroot = "/path/to/sysroot"
322target_triplet = "aarch64-linux-gnu"  # Or any other supported triplet.
323```
324
325For more details see the [Using cutom toolchains](#custom-toolchain) section
326below.
327
328## Build configurations
329
330TIP: `tools/setup_all_configs.py` can be used to generate out/XXX folders for
331most of the supported configurations.
332
333The following [GN args][gn-quickstart] are supported:
334
335`target_os = "android" | "linux" | "mac"`:
336
337Defaults to the current host, set "android" to build for Android.
338
339`target_cpu = "arm" | "arm64" | "x64"`
340
341Defaults to `"arm"` when `target_os` == `"android"`, `"x64"` when targeting the
342host. 32-bit host builds are not supported.
343Note: x64 here really means x86_64. This is to keep it consistent with
344Chromium's choice, which in turn follows Windows naming convention.
345
346`is_debug = true | false`
347
348Toggles Debug (default) / Release mode. This affects, among other things:
349(i) the `-g` compiler flag; (ii) setting/unsetting `-DNDEBUG`; (iii) turning
350on/off `DCHECK` and `DLOG`.
351Note that debug builds of Perfetto are sensibly slower than release versions. We
352strongly encourage using debug builds only for local development.
353
354`is_clang = true | false`
355
356Use Clang (default: true) or GCC (false).
357On Linux, by default it uses the self-hosted clang (see `is_hermetic_clang`).
358On Android, by default it uses clang from the NDK (in `buildtools/ndk`).
359On Mac, by default it uses the system version of clang (requires Xcode).
360See also the [custom toolchain](#custom-toolchain) section below.
361
362`is_hermetic_clang = true | false`
363
364Use bundled toolchain from `buildtools/` rather than system-wide one.
365
366`non_hermetic_clang_stdlib = libc++ | libstdc++`
367
368If `is_hermetic_clang` is `false`, sets the `-stdlib` flag for clang
369invocations. `libstdc++` is default on Linux hosts and `libc++` is
370default everywhere else.
371
372`cc = "gcc" / cxx = "g++"`
373
374Uses a different compiler binary (default: autodetected depending on is_clang).
375See also the [custom toolchain](#custom-toolchain) section below.
376
377`cc_wrapper = "tool_name"`
378
379Prepends all build commands with a wrapper command. Using `"ccache"` here
380enables the [ccache](https://github.com/ccache/ccache) caching compiler,
381which can considerably speed up repeat builds.
382
383`is_asan = true`
384
385Enables [Address Sanitizer](https://github.com/google/sanitizers/wiki/AddressSanitizer)
386
387`is_lsan = true`
388
389Enables [Leak Sanitizer](https://github.com/google/sanitizers/wiki/AddressSanitizerLeakSanitizer)
390(Linux/Mac only)
391
392`is_msan = true`
393
394Enables [Memory Sanitizer](https://github.com/google/sanitizers/wiki/MemorySanitizer)
395(Linux only)
396
397`is_tsan = true`
398
399Enables [Thread Sanitizer](https://github.com/google/sanitizers/wiki/ThreadSanitizerCppManual)
400(Linux/Mac only)
401
402`is_ubsan = true`
403
404Enables [Undefined Behavior Sanitizer](https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html)
405
406### {#custom-toolchain} Using custom toolchains and CC / CXX / CFLAGS env vars
407
408When building Perfetto as part of some other build environment it might be
409necessary to switch off all the built-in toolchain-related path-guessing scripts
410and manually specify the path of the toolchains.
411
412```python
413# Disable the scripts that guess the path of the toolchain.
414is_system_compiler = true
415
416ar = "/path/to/ar"
417cc = "/path/to/gcc-like-compiler"
418cxx = "/path/to/g++-like-compiler"
419linker = ""  # This is passed to -fuse-ld=...
420```
421
422If you are using a build system that keeps the toolchain settings in
423environment variables, you can set:
424
425```python
426is_system_compiler = true
427ar="${AR}"
428cc="${CC}"
429cxx="${CXX}"
430```
431
432`is_system_compiler = true` can be used also for cross-compilation.
433In case of cross-compilation, the GN variables have the following semantic:
434`ar`, `cc`, `cxx`, `linker` refer to the _host_ toolchain (sometimes also called
435_build_ toolchain). This toolchain is used to build: (i) auxiliary tools
436(e.g. the `traceconv` conversion util) and (ii) executable artifacts that are
437used during the rest of the build process for the target (e.g., the `protoc`
438compiler or the `protozero_plugin` protoc compiler plugin).
439
440The cross-toolchain used to build the artifacts that run on the device is
441prefixed by `target_`: `target_ar`, `target_cc`, `target_cxx`, `target_linker`.
442
443```python
444# Cross compilation kicks in when at least one of these three variables is set
445# to a value != than the host defaults.
446
447target_cpu = "x86" | "x64" | "arm" | "arm64"
448target_os = "linux" | "android"
449target_triplet =  "arm-linux-gnueabi" | "x86_64-linux-gnu" | ...
450```
451
452When integrating with GNU Makefile cross-toolchains build environments, a
453typical mapping of the corresponding environment variables is:
454
455```python
456ar="${BUILD_AR}"
457cc="${BUILD_CC}"
458cxx="${BUILD_CXX}"
459target_ar="${AR}"
460target_cc="${CC}"
461target_cxx="${CXX}"
462```
463
464It is possible to extend the set of `CFLAGS` and `CXXFLAGS` through the
465`extra_xxxflags` GN variables as follows. The extra flags are always appended
466(hence, take precedence) to the set of flags that the GN build files generate.
467
468```python
469# These apply both to host and target toolchain.
470extra_cflags="${CFLAGS}"
471extra_cxxflags="${CXXFLAGS}"
472extra_ldflags="${LDFLAGS}"
473
474# These apply only to the host toolchain.
475extra_host_cflags="${BUILD_CFLAGS}"
476extra_host_cxxflags="${BUILD_CXXFLAGS}"
477extra_host_ldflags="${BUILD_LDFLAGS}"
478
479# These apply only to the target toolchain.
480extra_target_cflags="${CFLAGS}"
481extra_target_cxxflags="${CXXFLAGS} ${debug_flags}"
482extra_target_ldflags="${LDFLAGS}"
483```
484
485[gn-quickstart]: https://gn.googlesource.com/gn/+/master/docs/quick_start.md
486
487## IDE setup
488
489Use a following command in the checkout directory in order to generate the
490compilation database file:
491
492```bash
493tools/gn gen out/default --export-compile-commands
494```
495
496After generating, it can be used in CLion (File -> Open -> Open As Project),
497Visual Studio Code with C/C++ extension and any other tool and editor that
498supports the compilation database format.
499
500#### Useful extensions
501
502If you are using VS Code we suggest the following extensions:
503
504- [Clang-Format](https://marketplace.visualstudio.com/items?itemName=xaver.clang-format)
505- [C/C++](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools)
506- [clangd](https://marketplace.visualstudio.com/items?itemName=llvm-vs-code-extensions.vscode-clangd)
507- [Native Debug](https://marketplace.visualstudio.com/items?itemName=webfreak.debug)
508- [GNFormat](https://marketplace.visualstudio.com/items?itemName=persidskiy.vscode-gnformat)
509- [ESlint](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint)
510- [markdownlint](https://marketplace.visualstudio.com/items?itemName=DavidAnson.vscode-markdownlint)
511- [Prettier](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode)
512
513#### Useful settings
514
515In `.vscode/settings.json`:
516
517```json
518{
519  "C_Cpp.clang_format_path": "${workspaceRoot}/buildtools/mac/clang-format",
520  "C_Cpp.clang_format_sortIncludes": true,
521  "files.exclude": {
522    "out/*/obj": true,
523    "out/*/gen": true,
524  },
525  "clangd.arguments": [
526    "--compile-commands-dir=${workspaceFolder}/out/mac_debug",
527    "--completion-style=detailed",
528    "--header-insertion=never"
529  ],
530  "eslint.workingDirectories": [
531    "./ui",
532  ],
533  "prettier.configPath": "ui/.prettierrc.yml",
534  "typescript.preferences.importModuleSpecifier": "relative",
535  "[typescript]": {
536    "editor.defaultFormatter": "esbenp.prettier-vscode"
537  },
538  "[scss]": {
539    "editor.defaultFormatter": "esbenp.prettier-vscode"
540  },
541}
542```
543
544Replace `/mac/` with `/linux64/` on Linux.
545
546### Debugging with VSCode
547
548Edit `.vscode/launch.json`:
549
550```json
551{
552  "version": "0.2.0",
553  "configurations": [
554    {
555      "request": "launch",
556      "type": "cppdbg",
557      "name": "Perfetto unittests",
558      "program": "${workspaceRoot}/out/mac_debug/perfetto_unittests",
559      "args": ["--gtest_filter=TracingServiceImplTest.StopTracingTriggerRingBuffer"],
560      "cwd": "${workspaceFolder}/out/mac_debug",
561      "MIMode": "lldb",
562    },
563  ]
564}
565```
566
567Then open the command palette `Meta`+`Shift`+`P` -> `Debug: Start debugging`.
568