docs/requirements/output-path-format.md
The JSON compilation database specification
(https://clang.llvm.org/docs/JSONCompilationDatabase.html) states that
paths in the command or file fields must be "either absolute or relative
to [the] directory." Different tools consuming the database have different
expectations: some require absolute paths (clang-tidy historically
segfaulted on relative paths, see LLVM bug #24710), others work better with
relative paths (shorter, portable), and some need canonical paths with
symlinks resolved (clangd struggles with symlinked source trees).
Bear provides configurable path formatting for the directory, file, and
output fields to accommodate these different consumers.
directory field path format is configurablefile field path format is configurableoutput field is formatted using the same strategy as file; on
formatting failure, Bear falls back to the original unformatted path. and .. components; the path
must exist on disk at the time the output is writtendirectory field value is the process working directory of the
intercepted command, formatted according to the chosen strategy using
itself as the basefile field is resolved relative to the (already formatted)
directory fieldfile or output path
(for example, the path no longer exists on disk), Bear logs a warning
and falls back to the original unformatted path for that fielddirectory field cannot be canonicalized under the
symlink-resolving format, the entire entry is dropped with a warning\\?\) that Windows canonicalization produces
(GitHub issue #683)../../other/dir/file.c)arguments array (include paths, output paths in
flags) are deliberately not transformed. Rewriting them would require
a compiler-flag-aware path rewriter, which is complex and error-prone.Given a build invoked from /home/user/project that compiles src/main.c:
When path format is
as-isfor both directory and file, thendirectoryis written as-is from the interception, andfileis written as-is (e.g.src/main.c).
Given a build whose intercepted event records the working directory as
the relative path build while Bear runs from /home/user/project:
When path format for directory is
absolute, thendirectoryis written as/home/user/project/build.
Given a build where the source file is specified as
/home/user/project/src/main.c:
When path format for file is
relativeand directory is/home/user/project, thenfileis written assrc/main.c.
Given a build where source files are symlinked:
When path format for file is
canonical, thenfileis written as the resolved real path (symlinks followed).
Given a build on Windows where canonicalize produces \\?\C:\Users\...:
When path format is
canonical, then the\\?\prefix is stripped from the output path.
Given a build where the source file does not exist at output time:
When path format is
canonical, then Bear logs a warning and falls back to the original path for thefilefield. If thedirectorycannot be canonicalized, the entire entry is dropped with a warning.
Given /a/b/one.c compiled from /a/b and /a/c/two.c compiled from
/a/c:
When path format for file is
relativeand directory isabsolute, then the first entry hasdirectory/a/bandfileone.c, and the second entry hasdirectory/a/candfiletwo.c.
Given a build invoked from /home/user/project that compiles src/main.c
to obj/main.o, with output-field emission enabled:
When path format for file is
relative, thenoutputis written asobj/main.o, formatted with the same strategy asfile.
Given the same build, where obj/main.o has been deleted before the
output is written:
When path format for file is
canonical, thenfileis written as the resolved real path, andoutputfalls back to the original unformatted pathobj/main.o, with a warning.
Given path format for directory set to relative:
Then the
directoryfield resolves to.(relative to itself), which is valid but rarely useful.