Compilation databases
Compilation databases are JSON files that Clang-based tooling (e.g. clangd and clang-tidy) consume to know what flags (in particular related to include paths) are used to build C++ files.
Generating compilation databases
You can generate compilation databases for consumption by tools such as clangd and clang-tidy by running the following BXL script:
buck2 bxl prelude//cxx/tools/compilation_database.bxl:generate -- --targets ...
The script will generate a compilation database for all source and header inputs
to the targets listed on the command line. The path to the database is printed
to stdout. Note that files that are referenced by multiple targets will have
multiple associated entries in the database, which may not be desirable in all
circumstances. For example, clang-tidy runs analysis for each entry sequentially
when the file being linted has several entries.
It is common to symlink the resulting data at the root of the repository:
ln -sf $(buck2 bxl prelude//cxx/tools/compilation_database.bxl:generate -- --targets ...) $(git rev-parse --show-toplevel)
Since the path to the script is rather long, consider setting up an alias in your repository:
# `comp_db.bxl`
load("@prelude//cxx/tools/compilation_database.bxl:generate", "generate")
gen = generate
ln -sf $(buck2 bxl comp_db.bxl:gen -- --targets ...) $(git rev-parse --show-toplevel)
Providing better ergonomics for BXL scripts (such as enabling something like
buck2 comp_db) is being discussed
here.
Tools jumping to buck-out
You may notice that your tools (e.g. clangd's Go To Definition feature)
jump to symlinks into buck-out, rather than into the source tree.
This is often problematic, because buck-out is not under source
control (so all VCS-related editor tools fail), and text editors
typically handle those symlinks poorly (e.g. VS Code will keep separate
tabs for the symlink and the source header, and Vim will reuse an
existing symlink buffer even when explicitly opening the source header).
The fix for this is to use header maps instead. To enable header maps,
set header_mode = HeaderMode("header_map_only") in your
CxxToolchainInfo.
Note that header maps are not supported by GCC. This should not be a problem since compilation databases are Clang technology, but you can setup a build constraint and conditionally set the header mode based on it if needed.