Skip to content

Choose what to try ​

Start with unused includes and dependencies. Check the time saved in builds you actually run, not just the percentage. Run one experiment at a time so you can tell what caused the result.

Find expensive headers ​

bash
buildray profile --source /path/to/project --compiler clang++-21 --jobs 2

headers.md ranks headers by parse time from Clang traces. Nested header times overlap; adding them does not predict a speedup. Traces are diagnostic and stay outside before/after timings.

Clean up includes ​

bash
buildray clean /path/to/project --runs 3 --jobs 2
buildray headers --source /path/to/project \
  --forward-declarations --header-path src \
  --exclude third_party --runs 3 --jobs 2

clean (also called optimize) tries removing unused includes from C++ sources. headers works on observed headers; --forward-declarations also tries replacing includes with forward declarations. Analysis uses actual compiler commands. It does not enforce every clang-tidy style rule.

Excluded paths still build and run tests, but their contents are not edited. Files generated or downloaded during configuration are also excluded from edits.

Try Unity ​

bash
buildray unity --source /path/to/project --target my_library \
  --batch-size 4 --runs 3 --jobs 2 \
  --rebuild-file src/model.cc --rebuild-file include/model.h

Unity produces a CMake option that defaults to off. After applying the patch, -DBUILDRAY_UNITY=ON enables the tested groups. Add --rebuild-file to measure files you often edit.

For Unity or a manually selected PCH, replace --jobs with --job-levels 1,2,4,8 to compare job counts. This cannot be combined with --auto or Unity retries. Buildray runs each level sequentially, validates the same candidate and keeps its measurements separate. The report marks job counts above the machine's detected CPU capacity. See the parallelism reference.

PCH is an optional experiment, disabled by default. Applying its patch also leaves it off; -DBUILDRAY_PCH=ON enables it. Consider it only when the absolute time saved justifies the added configuration. The PCH reference covers explicit experiments.

Examine dependencies ​

bash
buildray deps --source /path/to/project
buildray prune-links --source /path/to/project --runs 3 --jobs 2

deps shows header and target relationships, including cycles. It does not break cycles automatically; some are valid.

prune-links tests removing one redundant CMake declaration whose requirements remain reachable through another path. It does not yet find every unnecessary library. If the final link command stays the same, removing that declaration alone is not expected to save time.

prune-deps checks archive use once per program, then tries removing eligible private static libraries together. It splits groups that fail and keeps accepted removals in every later trial. Compiler commands must stay unchanged, and link replay must produce identical binaries from the same objects. The final combined patch must also pass the full build and tests.

CMake may also remove a redundant copy of a library that stays linked. Buildray accepts this only when the resulting binary is identical; it keeps the library's compilation coverage.

Target names and library lists can use CMake variables, including in loops and functions. The patch changes only the target and list values that were tested. Other values keep the original command, and shared variable definitions stay unchanged.

buildray clean-deps . runs this search and selects ELF LLD for both variants. Use --linker /path/to/ld.lld to choose its executable. The old prune-deps command keeps your configured linker unless --linker is supplied. If a library only supplies headers or compilation settings, the patch can keep those while removing the link. Add --rebuild-file to check whether an edit triggers fewer links. The command reference gives the setup and limits.

Dependency names can also be CMake aliases. Buildray checks the underlying library, keeps the alias definition, and preserves its spelling in any patch. If another linker argument changes, the rejected trial saves both commands in link-command-change.json for review.

The search defaults to 64 trial configurations and 300 seconds. Change these with --max-dependency-trials and --dependency-time-budget. The final build and tests still run after the search budget is reached.

If your project deliberately skips some tests, use --allow-baseline-skips. Buildray records those tests separately and requires the same skipped names after the patch and each measured file edit. Skipped tests never count as passed. Disabled tests, failures and an all-skipped test run still block validation.

Keep a validated patch ​

Read patch_validated, patch_recommended and performance_result in report.json. A .patch file can remain after a failure; its presence does not establish validation.

For a validated include patch, from your project root:

bash
git apply --check /path/to/run/includes.patch
git apply /path/to/run/includes.patch

Review the change and test other configurations before integrating it. The technical references describe each command's selection and validation rules.