| # Perfetto Project Development Guidelines |
| |
| This document provides essential instructions and best practices for developing |
| in the Perfetto codebase. Adhere to these guidelines to ensure consistency and |
| quality. |
| |
| ## 1. Building the Project |
| |
| Use the following commands to build the project for different configurations. |
| All commands should be run from the root of the repository. |
| |
| The output folder where code is built lives in out/xxx. Different people use |
| different output folders. Pick the output folder as follows |
| - The $OUT env var should contain the path of the output folder. If it exists respect that. |
| - If $OUT is empty/unset, set it by looking at the most recent out/ subdir, i.e. |
| `OUT=out/$(ls -t1 out | head -n1)` |
| |
| ### Building C++ code |
| |
| Our C++ sources use tools/gn and tools/ninja to build. |
| |
| - If you touch a .gn or .gni file, rerun `tools/gn gen --check $OUT` |
| - Afterwards, you can build code running `tools/ninja -C $OUT TARGET_NAME" |
| - TARGET_NAME is: |
| - perfetto_unittests: for any file in src/**/*_unittest.cc |
| - perfetto_integrationtests: for any file in src/**/*_integrationtest.cc (and most code under test/) |
| - perfetto_benchmarks: for any file in src/**/*_benchmark.cc (and most code under test/) |
| - Other target names are usually: traced, traced_probes, perfetto, trace_processor_shell. You can discover them following the root /BUILD.gn file |
| |
| When adding/removing source files, keep BUILD.gn files updated. |
| Usually there is a BUILD.gn file in each directory. If not, look at closer parent dirs for precedent. |
| |
| Never bother manually updating Android.bp files or bazel BUILD files. |
| Those are autogenerated later when uploading the pull request via |
| `tools/gen_all $OUT`, but humans will take care of that. |
| |
| To build one or more targets: |
| |
| ```sh |
| tools/ninja -C $OUT -k 10000 trace_processor_shell perfetto_unittests |
| ``` |
| |
| ### 2. Running C++ Tests |
| |
| Perfetto uses the Google Test framework. You will see c++ sources like |
| ```cpp |
| TEST(ProtozeroToJsonTest, Foo) { |
| ... |
| } |
| ``` |
| |
| ProtozeroToJsonTest is the test suite name, Foo the test name. |
| |
| You can run all the tests in a test suite by doing: |
| |
| ```sh |
| $OUT/perfetto_unittests --gtest_brief=1 --gtest_filter="ProtozeroToJsonTest.*" |
| ``` |
| |
| Or if you touch a specific test, you can run only that one doing |
| ```sh |
| $OUT/perfetto_unittests --gtest_brief=1 --gtest_filter="ProtozeroToJsonTest.Foo" |
| ``` |
| Same goes for perfetto_integrationtests. |
| |
| For perfetto_benchmarks you need instead to run |
| |
| ```sh |
| $OUT/perfetto_benchmarks --benchmark_filter='.*BM_RtMutex_NoContention.*' |
| ``` |
| |
| Note that unlike Google Test, where the filter is a glob, in Google Benchmarks the filter is a regex. |
| |
| ### Trace Processor Diff Tests |
| |
| Trace Processor Diff Tests (or diff tests for short) are executed by running the |
| following command: |
| |
| ```sh |
| tools/diff_test_trace_processor.py $OUT$/trace_processor_shell --keep-input --quiet --name-filter="<regex of test names>" |
| ``` |
| |
| **Note:** These tests can also be run with ASan or MSan builds by changing the |
| path from `out/linux_clang_release/` to `out/linux_asan/` or `out/linux_msan/` |
| respectively. **Note:** The `--name-filter` argument is optional. **Note:** When |
| using the `--name-filter` flag, do not include `test_` in the filter. The test |
| runner automatically drops this prefix. For example, to run `test_my_cool_test`, |
| use the filter `MyTestSuite.my_cool_test`. |
| |
| |
| ### Test Guidelines |
| |
| - **Prefer test suites over individual tests.** When using the `--gtest_filter` |
| flag, specify a whole test suite (e.g., `"MyTestSuite.*"`) instead of a single |
| test case (e.g., `"MyTestSuite.MySpecificTest"`). This ensures broader test |
| coverage. |
| - **Do not test unstable IDs.** When writing diff tests, do not include columns |
| that contain unstable IDs (e.g. `upid`, `utid`, `id`, etc) in the output. These |
| IDs can change between different runs of the same test, which will cause the |
| test to fail. |
| - **Remove `test_` prefix for diff tests.** When using the `--name-filter` flag |
| for diff tests, do not include `test_` in the filter. The test |
| runner automatically drops this prefix. For example, to run `test_my_cool_test`, |
| use the filter `MyTestSuite.my_cool_test`. |
| |
| ## 3. Core Software Engineering Principles |
| |
| Follow these principles when writing and modifying code. |
| |
| ### Principle 1: Don't Repeat Yourself (DRY) |
| |
| - **Avoid code duplication.** Before writing a new function, search the codebase |
| for existing functions that provide similar functionality. |
| - **Reuse and refactor.** If a suitable function exists, reuse it. If it's close |
| but not an exact match, consider refactoring the existing function to |
| accommodate the new use case instead of creating a copy. |
| - **Consult if unsure.** If you are considering duplicating a function or a |
| significant block of code, consult with the user first. |
| |
| ## 4. Getting Diffs |
| |
| When asked to "get a diff" or "read the current diff", run the following |
| command: |
| |
| ```sh |
| git diff $(git config branch.$(git rev-parse --abbrev-ref HEAD).parent) |
| ``` |
| |
| ## 5. Fixing GN Dependencies |
| |
| When asked to fix GN dependencies, run the following command and fix any errors |
| that are reported: |
| |
| ```sh |
| tools/gn check $OUT |
| ``` |
| |
| **Note:** When fixing include errors, do not add dependencies to `public_deps` |
| unless explicitly instructed to by the user. Instead, add a direct dependency to |
| the target that requires it. |
| |
| ## 6. Other Configurations |
| |
| ### ASan (AddressSanitizer) Build |
| |
| To build with ASan for memory error detection: |
| |
| ```sh |
| tools/ninja -C out/linux_asan -k 10000 trace_processor_shell perfetto_unittests |
| ``` |
| |
| ### MSan (MemorySanitizer) Build |
| |
| To build with MSan for uninitialized read detection: |
| |
| ```sh |
| tools/ninja -C out/linux_msan -k 10000 trace_processor_shell perfetto_unittests |
| ``` |
| |
| ### ASan (AddressSanitizer) Tests |
| |
| **Note:** Ensure the `ASAN_SYMBOLIZER_PATH` is set correctly. |
| |
| ```sh |
| ASAN_SYMBOLIZER_PATH="$(pwd)/buildtools/linux64/clang/bin/llvm-symbolizer" \ |
| out/linux_asan/perfetto_unittests --gtest_brief=1 --gtest_filter="<TestSuiteName.*>" |
| ``` |
| |
| ### MSan (MemorySanitizer) Tests |
| |
| **Note:** Ensure the `MSAN_SYMBOLIZER_PATH` is set correctly. |
| |
| ```sh |
| MSAN_SYMBOLIZER_PATH="$(pwd)/buildtools/linux64/clang/bin/llvm-symbolizer" \ |
| out/linux_msan/perfetto_unittests --gtest_brief=1 --gtest_filter="<TestSuiteName.*>" |
| |
| ## 7. Creating Pull Requests |
| |
| When creating a pull request, follow these steps: |
| |
| 1. **Create a new branch:** |
| Use the command `git new-branch dev/lalitm/<name-of-branch>` to create a new branch for your pull request. |
| |
| 2. **Create a stacked/dependent pull request:** |
| To create a pull request that depends on another, use the command `git new-branch --parent <name-of-parent-branch> dev/lalitm/<name-of-branch>`. |
| |
| **Note:** The `git new-branch` command only creates and switches to a new |
| branch. The normal `git add` and `git commit` workflow should be used to add |
| changes to the branch. |
| |
| ## 8. Commit Messages |
| |
| When writing commit messages, follow these guidelines: |
| |
| - **Prefix your commits.** Prefix changes to Trace Processor code with `tp:`, |
| UI code with `ui:`, and general Perfetto changes with `perfetto:`. |
| - **Keep it concise.** A short one-line summary followed by a paragraph |
| describing the change is the best commit message. |