| # AGENTS.md — Doris BE |
| |
| Scope: `be/`. This file is operational — what to do while developing or |
| reviewing BE C++ code so the compile-time invariants hold. The gate mechanics |
| and the `*_fwd.h` convention are documented in `be/README.md` (read it when a |
| gate fires). Repository-wide rules (commit format, build/test commands, |
| clang-format/clang-tidy) live in the root `AGENTS.md`; nothing here overrides |
| them. |
| |
| ## Machine-Checked Obligations (configure-time gates) |
| |
| BE configure runs `build-support/check-build-hygiene.sh` (option |
| `ENABLE_BUILD_HYGIENE`, default ON; scripts and self-tests live in |
| `build-support/` and `build-support/tests/`). It is pure text and takes about |
| a second — **run it directly after any change touching BE headers, includes, |
| template instantiations, unity skip lists, or test files that include src |
| sources**; do not wait for configure or CI to tell you. |
| |
| Every failure message carries the mechanism and the fix path. The legal way |
| past a gate is never to bypass it, but one of: |
| |
| - fix the edge as the message says (forward-declare + include in the `.cpp`, |
| or route declarations through a `*_fwd.h`); |
| - when the change is deliberate, edit the corresponding table |
| (rule exception set / `ANGLE_BANS` / `FORWARD_CLOSURE_BUDGETS` / |
| `REVERSE_REACH_BASELINES` / `PCH_QUOTED_WHITELIST` / `ALLOW`) **in the same |
| commit** and justify it in the commit message — the table diff is the |
| review signal. |
| |
| ## Rules while writing BE code |
| |
| - **Adding an `#include` to a widely-included (hub) header is a design |
| decision, not a convenience.** Everything a hub includes is reparsed by |
| every TU behind it (~1000 TUs for `exec_env.h`, `thread_context.h`, |
| `runtime_state.h`, `function.h`, `dependency.h`, `column.h`, ...). Prefer |
| forward declarations; put the real include in the `.cpp`. If many files |
| need the declarations, use a `*_fwd.h` (declarations and lightweight |
| aliases only — never bodies or non-fwd project includes). |
| - **Never add a quoted include to `pch/pch.h`.** Every header on the PCH |
| rebuilds the whole backend (plus the PCH itself) when touched; it is the |
| single most leveraged regression surface in the repo. |
| - **Keep `extern template` families paired.** An explicit instantiation in a |
| `.cpp` needs the matching `extern template` in the header, spelled with the |
| same template arguments — a missing extern compiles and links fine and just |
| silently re-instantiates in every TU. Instantiations expanded from macros |
| (e.g. `DECLARE_OPERATOR` in `operator.cpp`) are invisible to the pairing |
| gate on both sides: keep those in sync by hand. |
| - **A test that `#include`s a be/src `.cpp`** needs that file opted out of |
| unity batching via `doris_skip_unity_inclusion` in the owning |
| `be/src/.../CMakeLists.txt`; otherwise the BE UT link fails with duplicate |
| symbols an hour later. The gate error names the exact entry to add. |
| - **Do not re-add banned third-party includes** (`fmt`/`boost`/ |
| `concurrentqueue.h`/`<ranges>`) to the headers listed in `ANGLE_BANS`: |
| their bodies were deliberately moved out of line, and `<ranges>` in a src |
| header additionally breaks the `-fno-access-control` UT build on libc++. |
| |
| ## Review checkpoints (AI review and self-review) |
| |
| - [ ] New includes in hub headers: could a forward declaration or `*_fwd.h` |
| carry this instead? Does the PR pay a closure/reach budget bump — and |
| if so, does the commit message justify it? |
| - [ ] Any edit to a gate table (`RULES` exceptions, budgets, whitelist, |
| `ALLOW`) must be deliberate, minimal, and explained in the same |
| commit; an unexplained table edit is a red flag, not a fix. |
| - [ ] Any change to `pch/pch.h` is near-always wrong; demand the reasoning. |
| - [ ] New explicit instantiation lists or `extern template` blocks: both |
| sides present, same spelling? New test `#include` of a src `.cpp`: |
| skip entry present? |
| - [ ] `git grep` for a deleted/renamed header in skip lists and gate tables: |
| stale entries fail configure loudly — fix them in the same PR. |