requirements/output-append.md
When the user performs incremental builds or builds separate components at
different times, they need to accumulate compilation entries across multiple
Bear runs into a single compilation database. The --append flag merges new
entries with an existing compile_commands.json instead of overwriting it.
--append is specified and the output file exists, existing entries
are preserved and new entries are added after them--append is specified and the output file does not exist, Bear logs
a warning and writes only the new entries (no error)--append is not specified, the output file is overwritten with only
the new entries (default behavior)The --append flag is available both in the semantic subcommand and in
the combined mode (bear --append -- <build>).
When append mode is active, Bear reads the existing compilation database
before writing the new one. The existing entries are chained before the new
entries. This ordering matters: the duplicate filter (output-duplicate-detection) keeps the
first occurrence, so when a file is recompiled with identical flags the
original entry from the existing database is preserved.
The append step runs after entry conversion and before the atomic write
(output-atomic-write). The duplicate filter (output-duplicate-detection) and source filter run after
the atomic write stage in the pipeline.
Reading errors are handled at two levels:
output-atomic-write handles this)Given no existing compile_commands.json:
When the user runs
bear --append -- <compiler> -c file1.c, thencompile_commands.jsonis created with one entry for file1.c.
Given an existing compile_commands.json with an entry for file1.c:
When the user runs
bear --append -- <compiler> -c file2.c, thencompile_commands.jsoncontains entries for both file1.c and file2.c.
Given an existing compile_commands.json with an entry for file1.c:
When the user runs
bear -- <compiler> -c file2.c(no--append), thencompile_commands.jsoncontains only the entry for file2.c.
Given an existing compile_commands.json with corrupted JSON content:
When the user runs
bear --append -- <compiler> -c file1.c, thencompile_commands.jsoncontains only the entry for file1.c.
Given an existing compile_commands.json with some valid and some invalid entries:
When the user runs
bear --append -- <compiler> -c new.c, then the valid existing entries are preserved, the invalid entries are skipped with per-entry warnings, and the new entry is added.
Given an existing compile_commands.json with read permission denied:
When the user runs
bear --append -- <compiler> -c file1.c, then Bear exits with an IO error and does not write output.
Given an existing compile_commands.json and a new build that produces zero
compiler invocations:
When the user runs
bear --append -- true, then the existing entries are preserved unchanged.
Given an existing compile_commands.json with an entry for file1.c compiled
with -O2, and a new build that compiles file1.c with identical flags:
When the user runs
bear --append -- <compiler> -c -O2 file1.c, then the duplicate filter determines whether both entries survive, and the original entry (from the existing database) takes priority.
--append
on large projects in the old C++ implementation. The current Rust
implementation uses iterators but the underlying JSON parser may still
buffer the full file.--update concept where existing entries
with matching filenames are replaced rather than appended. This is related
but distinct from basic append behavior.